The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
VisitorSymbolIdentification.cs
Go to the documentation of this file.
1 // -------------------------------------------------------------------------- //
3 // Project rROTOR //
4 // -------------------------------------------------------------------------- //
5 // File: VisitorSymbolIdentification.cs //
6 // Authors: Cristina Gonzalez Muņoz - cristi.gm@gmail.com //
7 // Francisco Ortin - francisco.ortin@gmail.com //
8 // Description: //
9 // This class visits the AST to assign symbol information to identifier //
10 // It also sets the Symbol's "dynamnic" property from the DynVarManager //
11 // expression. //
12 // Inheritance: VisitorAdapter //
13 // Implements Visitor pattern [Concrete Visitor]. //
14 // -------------------------------------------------------------------------- //
15 // Create date: 30-03-2007 //
16 // Modification date: 22-05-2007 //
18 
19 using System;
20 using System.Collections.Generic;
21 using System.IO;
22 using System.Text;
23 
24 using AST;
25 using ErrorManagement;
26 using Symbols;
27 using Tools;
28 using TypeSystem;
29 using DynVarManagement;
30 
31 namespace Semantic
32 {
42  {
43  #region Fields
44 
48  private SymbolTable table;
49 
53  private List<string> usings;
54 
58  private UserType thisType;
59 
63  private string currentNamespace;
64 
68  private string currentClass;
69 
73  private string currentMethod;
74 
78  private UserType baseType;
79 
83  private DynVarManagement.DynVarManager manager;
84 
88  private List<int> blockList;
89 
93  private int indexBlockList = 0;
94 
98  private IDictionary<string, string> directories;
99 
100  #endregion
101 
102  #region Constructor
103 
108  public VisitorSymbolIdentification(IDictionary<string, string> directories)
109  {
110  this.table = new SymbolTable();
111  this.usings = new List<string>();
112  this.manager = new DynVarManagement.DynVarManager();
113  this.currentNamespace = "";
114  this.currentClass = "";
115  this.currentMethod = "";
116  this.directories = directories;
117  }
118 
119  #endregion
120 
121  #region loadDynVars
122 
126  private void loadDynVars()
127  {
128  string dynFile = Path.ChangeExtension(this.currentFile, DynVarManagement.DynVarManager.DynVarFileExt);
129 
130  if (File.Exists(dynFile))
131  {
132  try
133  {
134  manager.Load(dynFile);
135  }
136  catch (DynVarManagement.DynVarException e)
137  {
138  ErrorManager.Instance.NotifyError(new LoadingDynVarsError(e.Message));
139  }
140  }
141  }
142 
143 
144  #endregion
145 
146  #region searchDynInfo()
147 
153  private bool searchDynInfo(string id)
154  {
155  if (manager.Ready)
156  {
157  if (this.currentMethod.Length == 0)
158  return manager.SearchDynVar(this.currentNamespace, this.currentClass, id);
159  if ((this.blockList != null) && (this.blockList.Count != 0) && (this.indexBlockList > 0))
160  return manager.SearchDynVar(this.currentNamespace, this.currentClass, this.currentMethod, this.blockList.GetRange(0, this.indexBlockList), id);
161  return manager.SearchDynVar(this.currentNamespace, this.currentClass, this.currentMethod, id);
162  }
163  return false;
164  }
165 
166  #endregion
167 
168  #region Visit(SourceFile node, Object obj)
169 
170  public override Object Visit(SourceFile node, Object obj)
171  {
172  this.currentFile = node.Location.FileName;
173 
174  this.loadDynVars();
175 
176  for (int i = 0; i < node.Usings.Count; i++)
177  {
178  usings.Add(node.Usings[i]);
179  }
180 
181  foreach (string key in node.Namespacekeys)
182  {
183  int count = node.GetNamespaceDefinitionCount(key);
184  for (int i = 0; i < count; i++)
185  {
186  node.GetNamespaceDeclarationElement(key, i).Accept(this, obj);
187  }
188  }
189 
190  for (int i = 0; i < node.DeclarationCount; i++)
191  {
192  node.GetDeclarationElement(i).Accept(this, obj);
193  }
194 
195  return null;
196  }
197 
198  #endregion
199 
200  #region Visit(Namespace node, Object obj)
201 
202  public override Object Visit(Namespace node, Object obj)
203  {
204  this.table.Set();
205  this.currentNamespace = node.Identifier.Identifier;
206 
207  usings.Add(node.Identifier.Identifier);
208 
209  for (int i = 0; i < node.NamespaceMembersCount; i++)
210  {
211  node.GetDeclarationElement(i).Accept(this, obj);
212  }
213 
214  usings.Remove(node.Identifier.Identifier);
215 
216  this.currentNamespace = "";
217  this.table.Reset();
218  return null;
219  }
220 
221  #endregion
222 
223  #region Visit(ClassDefinition node, Object obj)
224 
225  public override Object Visit(ClassDefinition node, Object obj)
226  {
227  this.table.Set();
228  this.currentClass = node.Identifier;
229  this.thisType = (UserType)node.TypeExpr;
230  this.baseType = ((ClassType)node.TypeExpr).BaseClass;
231 
232  // first step
233  for (int i = 0; i < node.MemberCount; i++)
234  {
235  if (node.GetMemberElement(i) is FieldDeclaration)
236  this.fieldDeclarationSymbol((FieldDeclaration)node.GetMemberElement(i));
237  }
238 
239  // second step
240  for (int i = 0; i < node.MemberCount; i++)
241  {
242  node.GetMemberElement(i).Accept(this, obj);
243  }
244 
245  this.currentClass = "";
246  this.thisType = null;
247  this.baseType = null;
248  this.table.Reset();
249  return null;
250  }
251 
252  #endregion
253 
254  #region Visit(IdDeclaration node, Object obj)
255 
256  public override Object Visit(IdDeclaration node, Object obj)
257  {
258  node.Symbol = declarationSymbol(node);
259  return null;
260  }
261 
262  #endregion
263 
264  #region Visit(Definition node, Object obj)
265 
266  public override Object Visit(Definition node, Object obj)
267  {
268  node.Init.Accept(this, obj);
269  node.Symbol = declarationSymbol(node);
270  return null;
271  }
272 
273  #endregion
274 
275  #region Visit(ConstantDefinition node, Object obj)
276 
277  public override Object Visit(ConstantDefinition node, Object obj)
278  {
279  node.Init.Accept(this, obj);
280  node.Symbol = declarationSymbol(node);
281  return null;
282  }
283 
284  #endregion
285 
286  #region declarationSymbol()
287 
293  private Symbol declarationSymbol(IdDeclaration node)
294  {
295  TypeExpression te = this.searchType(node.FullName, node.Location.Line, node.Location.Column);
296  if (te != null)
297  {
298  node.TypeExpr = te;
299  string id = node.Identifier;
300  if (node.IdentifierExp.IndexOfSSA != -1)
301  id += node.IdentifierExp.IndexOfSSA;
302  Symbol symbol = this.table.Insert(id, te, searchDynInfo(node.Identifier));
303  if (symbol == null)
304  ErrorManager.Instance.NotifyError(new DeclarationFoundError(node.Identifier, new Location(this.currentFile, node.Location.Line, node.Location.Column)));
305  return symbol;
306  }
307  ErrorManager.Instance.NotifyError(new UnknownTypeError(node.FullName, new Location(this.currentFile, node.Location.Line, node.Location.Column)));
308  return null;
309  }
310 
311  #endregion
312 
313  #region fieldDeclarationSymbol()
314 
319  private void fieldDeclarationSymbol(FieldDeclaration node)
320  {
321  if (node.TypeExpr == null)
322  {
323  ErrorManager.Instance.NotifyError(new UnknownTypeError(node.FullName, new Location(this.currentFile, node.Location.Line, node.Location.Column)));
324  return;
325  }
326  bool isDynamic = searchDynInfo(node.Identifier);
327  if (this.table.Insert(node.Identifier, node.TypeExpr, isDynamic) == null)
328  {
329  ErrorManager.Instance.NotifyError(new DeclarationFoundError(node.Identifier, new Location(this.currentFile, node.Location.Line, node.Location.Column)));
330  return;
331  }
332  DynVarOptions.Instance.AssignDynamism(this.thisType.Fields[node.Identifier].Type, isDynamic);
333  }
334 
335  #endregion
336 
337  #region Visit(MethodDefinition node, Object obj)
338 
339  public override Object Visit(MethodDefinition node, Object obj)
340  {
341  this.blockList = new List<int>();
342  this.indexBlockList = 0;
343 
344  this.table.Set();
345  this.currentMethod = node.Identifier;
346  node.IsReturnDynamic = this.searchDynInfo("");
347  this.parameterSymbol(node);
348  node.Body.Accept(this, node);
349  this.currentMethod = "";
350  this.table.Reset();
351  return null;
352  }
353 
354  #endregion
355 
356  #region Visit(ConstructorDefinition node, Object obj)
357 
358  public override Object Visit(ConstructorDefinition node, Object obj)
359  {
360  this.blockList = new List<int>();
361  this.indexBlockList = 0;
362 
363  this.table.Set();
364  this.currentMethod = node.Identifier;
365  this.parameterSymbol(node);
366 
367  if (node.Initialization != null)
368  node.Initialization.Accept(this, obj);
369 
370  node.Body.Accept(this, node);
371  this.currentMethod = "";
372  this.table.Reset();
373  return null;
374  }
375 
376  #endregion
377 
378  #region parameterSymbol()
379 
380  private void parameterSymbol(MethodDefinition node)
381  {
382  for (int i = 0; i < ((MethodType)node.TypeExpr).ParameterListCount; i++)
383  {
384  string id = node.ParametersInfo[i].Identifier;
385  if (!(((MethodType)node.TypeExpr).GetParameter(i) is ArrayType))
386  id += "0";
387  if (this.table.Insert(id, ((MethodType)node.TypeExpr).GetParameter(i), searchDynInfo(node.ParametersInfo[i].Identifier)) == null)
388  ErrorManager.Instance.NotifyError(new DeclarationFoundError(node.ParametersInfo[i].Identifier, new Location(this.currentFile, node.Location.Line, node.Location.Column)));
389  }
390  }
391 
392  #endregion
393 
394  // Literals
395 
396  #region Visit(SingleIdentifierExpression node, Object obj)
397 
398  public override Object Visit(SingleIdentifierExpression node, Object obj)
399  {
400  Symbol sym = null;
401  if (node.IndexOfSSA != -1)
402  sym = this.table.Search(node.Identifier + node.IndexOfSSA);
403  else
404  sym = this.table.Search(node.Identifier);
405 
406  if (sym != null)
407  node.IdSymbol = (Symbol)sym;
408 
409  return null;
410  }
411 
412  #endregion
413 
414  #region searchType()
415 
423  private TypeExpression searchType(string typeIdentifier, int line, int column)
424  {
425  TypeExpression te = null;
426  bool found = false;
427  int rank = 0;
428 
429  while ((typeIdentifier.Contains("[]")) && (!found))
430  {
431  te = TypeTable.Instance.GetType(typeIdentifier, new Location(this.currentFile, line, column));
432  if (te == null)
433  {
434  typeIdentifier = typeIdentifier.Substring(0, typeIdentifier.Length - 2);
435  rank++;
436  }
437  else
438  found = true;
439  }
440 
441  if (!found)
442  te = TypeTable.Instance.GetType(typeIdentifier, new Location(this.currentFile, line, column));
443 
444  if (te == null)
445  {
446  for (int i = 0; i < usings.Count; i++)
447  {
448  StringBuilder str = new StringBuilder();
449  str.Append(usings[i]);
450  str.Append(".");
451  str.Append(typeIdentifier);
452 
453  te = TypeTable.Instance.GetType(str.ToString(), new Location(this.currentFile, line, column));
454  if (te != null)
455  break;
456  }
457  }
458 
459  if (te != null)
460  {
461  if (rank != 0)
462  {
463  for (int i = 0; i < rank; i++)
464  {
465  te = new ArrayType(te);
467  TypeTable.Instance.AddType(te.FullName, te, new Location(this.currentFile, line, column));
468  }
469  }
470  }
471 
472  return te;
473  }
474 
475  #endregion
476 
477  #region compoundExpressionToArray()
478 
484  private TypeExpression[] compoundExpressionToArray(CompoundExpression args)
485  {
486  TypeExpression[] aux = new TypeExpression[args.ExpressionCount];
487  TypeExpression te;
488 
489  for (int i = 0; i < args.ExpressionCount; i++)
490  {
491  if ((te = args.GetExpressionElement(i).ExpressionType) != null)
492  aux[i] = te;
493  else
494  return null;
495  }
496  return aux;
497  }
498 
499  #endregion
500 
501  // Statements
502 
503  #region Visit(Block node, Object obj)
504 
505  public override Object Visit(Block node, Object obj)
506  {
507  if (node.StatementCount != 0)
508  {
509  if (!(obj is MethodDefinition)) // Set block
510  {
511  if (this.indexBlockList >= this.blockList.Count)
512  this.blockList.Add(0);
513  else
514  this.blockList[indexBlockList] = this.blockList[indexBlockList] + 1;
515  this.indexBlockList++;
516  }
517 
518  for (int i = 0; i < node.StatementCount; i++)
519  node.GetStatementElement(i).Accept(this, null);
520 
521  if (!(obj is MethodDefinition))
522  {
523  for (int i = this.indexBlockList; i < this.blockList.Count; i++)
524  this.blockList.RemoveAt(i);
525  this.indexBlockList--;
526  }
527  }
528 
529  return null;
530  }
531 
532  #endregion
533 
534  #region Visit(DoStatement node, Object obj)
535 
536  public override Object Visit(DoStatement node, Object obj)
537  {
538  for (int i = 0; i < node.InitDo.Count; i++)
539  {
540  node.InitDo[i].Accept(this, obj);
541  }
542  this.table.Set();
543  for (int i = 0; i < node.BeforeBody.Count; i++)
544  {
545  node.BeforeBody[i].Accept(this, obj);
546  }
547  node.Statements.Accept(this, obj);
548  this.table.Reset();
549  node.Condition.Accept(this, obj);
550  return null;
551  }
552 
553  #endregion
554 
555  #region Visit(ForStatement node, Object obj)
556 
557  public override Object Visit(ForStatement node, Object obj)
558  {
559  this.table.Set();
560  for (int i = 0; i < node.InitializerCount; i++)
561  {
562  node.GetInitializerElement(i).Accept(this, obj);
563  }
564  for (int i = 0; i < node.AfterInit.Count; i++)
565  {
566  node.AfterInit[i].Accept(this, obj);
567  }
568  for (int i = 0; i < node.BeforeCondition.Count; i++)
569  {
570  node.BeforeCondition[i].Accept(this, obj);
571  }
572  node.Condition.Accept(this, obj);
573  for (int i = 0; i < node.AfterCondition.Count; i++)
574  {
575  node.AfterCondition[i].Accept(this, obj);
576  }
577  node.Statements.Accept(this, obj);
578  for (int i = 0; i < node.IteratorCount; i++)
579  {
580  node.GetIteratorElement(i).Accept(this, obj);
581  }
582  this.table.Reset();
583  return null;
584  }
585 
586  #endregion
587 
588  #region Visit(IfElseStatement node, Object obj)
589 
590  public override Object Visit(IfElseStatement node, Object obj)
591  {
592  node.Condition.Accept(this, obj);
593  for (int i = 0; i < node.AfterCondition.Count; i++)
594  {
595  node.AfterCondition[i].Accept(this, obj);
596  }
597  this.table.Set();
598  node.TrueBranch.Accept(this, obj);
599  this.table.Reset();
600  this.table.Set();
601  node.FalseBranch.Accept(this, obj);
602  this.table.Reset();
603  for (int i = 0; i < node.ThetaStatements.Count; i++)
604  {
605  node.ThetaStatements[i].Accept(this, obj);
606  }
607  return null;
608  }
609 
610  #endregion
611 
612  #region Visit(WhileStatement node, Object obj)
613 
614  public override Object Visit(WhileStatement node, Object obj)
615  {
616  for (int i = 0; i < node.InitWhile.Count; i++)
617  {
618  node.InitWhile[i].Accept(this, obj);
619  }
620  for (int i = 0; i < node.BeforeCondition.Count; i++)
621  {
622  node.BeforeCondition[i].Accept(this, obj);
623  }
624  node.Condition.Accept(this, obj);
625  for (int i = 0; i < node.AfterCondition.Count; i++)
626  {
627  node.AfterCondition[i].Accept(this, obj);
628  }
629  this.table.Set();
630  node.Statements.Accept(this, obj);
631  this.table.Reset();
632  return null;
633  }
634 
635  #endregion
636 
637  #region Visit(SwitchStatement node, Object obj)
638 
639  public override Object Visit(SwitchStatement node, Object obj)
640  {
641  node.Condition.Accept(this, obj);
642  for (int i = 0; i < node.AfterCondition.Count; i++)
643  {
644  node.AfterCondition[i].Accept(this, obj);
645  }
646 
647  for (int i = 0; i < node.SwitchBlockCount; i++)
648  {
649  this.table.Set();
650  node.GetSwitchSectionElement(i).Accept(this, obj);
651  this.table.Reset();
652  }
653  for (int i = 0; i < node.ThetaStatements.Count; i++)
654  {
655  node.ThetaStatements[i].Accept(this, obj);
656  }
657  return null;
658  }
659 
660  #endregion
661  }
662 }
Encapsulates a definition of a concrete method.
override Object Visit(MethodDefinition node, Object obj)
override Object Visit(Block node, Object obj)
Encapsulates a Do statement of our programming language.
Definition: DoStatement.cs:34
Encapsulates a block of statements.
Definition: Block.cs:34
Encapsulates a namespace definition.
Definition: Namespace.cs:35
override Object Visit(ConstantDefinition node, Object obj)
Representa an array type.
Definition: ArrayType.cs:35
static TypeTable Instance
Gets the unique instance of TypeTable
Definition: TypeTable.cs:57
Represents a error produced when the used type is not defined.
This class encapsulates a location in a specific file. Implements an Inmutable pattern. So it can be used in any context, that is his internal fields never change.
Definition: Location.cs:24
override Object Visit(ConstructorDefinition node, Object obj)
override Object Visit(DoStatement node, Object obj)
override Object Visit(WhileStatement node, Object obj)
Location Location
Definition: AstNode.cs:45
Symbol Insert(string id, TypeExpression type, bool isDynamic)
Insert a new symbol in the current scope.
Definition: SymbolTable.cs:84
VisitorSymbolIdentification(IDictionary< string, string > directories)
Constructor of VisitorSymbolIdentification A mapping between each sort file name and its full directo...
Represents a error produced when the declaration already exists.
Encapsulates a definition.
Definition: Definition.cs:36
New implementation of DynVarManagement: -Ignores &quot;block&quot; elements: not used anymore. -Provides wider interface: -Dynamic method return (dynreturn attribute in method elements) -Interface elements Includes set of old fields, properties and methods for retro-compatibility reasons.
override Object Visit(IdDeclaration node, Object obj)
override Object Visit(SourceFile node, Object obj)
override Object Visit(IfElseStatement node, Object obj)
bool Ready
Gets true if the xml document is loaded. Otherwise false.
Abstract class that represents all different types.
Encapsulates a For statement of our programming languages.
Definition: ForStatement.cs:34
Implementation of a symbol table.
Definition: SymbolTable.cs:26
Encapsulates a While statement of our programming languages.
System.Text.StringBuilder StringBuilder
Definition: CSharpParser.cs:4
int StatementCount
Gets the number of statements.
Definition: Block.cs:51
bool SearchDynVar(string ns, string classId, string varId)
virtual string FullName
Gets the full name of the type Note: WriteType expression is the longest recursive representation of ...
This class represents a symbol associated with its identifier.
Definition: Symbol.cs:26
int Column
Gets column where the item is located
Definition: Location.cs:64
Encapsulates a identifier expression of our programming language.
override Object Visit(SwitchStatement node, Object obj)
Encapsulates a set of expressions.
string currentFile
Name of the current file.
List< Parameter > ParametersInfo
Gets the parameters information used to obtain its type
Abstract class to define different visits over the abstract syntax tree. It makes a deep walker...
int Line
Gets line where the item is located
Definition: Location.cs:58
bool ContainsType(string key)
Returns if the type table contains the specified tmpName.
Definition: TypeTable.cs:174
SingleIdentifierExpression IdentifierExp
Gets the identifier expression
override Object Visit(Namespace node, Object obj)
Implementation of a table of types.
Definition: TypeTable.cs:30
Encapsulates a If-Else statement of our programming language.
override Object Visit(Definition node, Object obj)
void AddType(string name, TypeExpression type, Location location)
Adds a new type into the type table
Definition: TypeTable.cs:191
Encapsulates a definition of a concrete constructor.
Declaration GetMemberElement(int index)
Gets the element stored in the specified index.
Encapsulates the source code.
Definition: SourceFile.cs:35
Expression GetExpressionElement(int index)
Gets the element stored in the specified index.
Encapsulates a declaration.
int IndexOfSSA
Gets or sets the index associated with SSA algorithm
InvocationExpression Initialization
Gets the base or this initialization of the constructor definition
Representa a method type.
Definition: MethodType.cs:37
Encapsulates a declaration of a concrete field.
Encapsulates a constant definition.
override Object Visit(ClassDefinition node, Object obj)
string FullName
Gets or sets the nominal type of the declaration
Definition: Declaration.cs:72
string Identifier
Gets the name associated to the declaration
Represents a class type.
Definition: ClassType.cs:35
This class visits the AST to assign symbol information to identifier expression.
override Object Visit(SingleIdentifierExpression node, Object obj)
Represents a class or interface type.
Definition: UserType.cs:31
Statement GetStatementElement(int index)
Gets the element stored in the specified index.
Definition: Block.cs:159
Encapsulates a definition of a concrete class.
override Object Visit(ForStatement node, Object obj)
TypeExpression TypeExpr
Gets or sets the type of the declaration
Definition: Declaration.cs:63
Encapsulates a Switch statement of our programming languages.
Represents the error occurred when dynamic variable are loaded.