public override void PreVisit(FuncDef funcDef) { // Transfer scopes. this.FunctionScopeLink = this.GlobalScope.Get(funcDef.Entry.ID, Classification.Function); this.ClassInstanceScope = new SymbolTable(); if (funcDef.ScopeResolution != null) { this.ClassInstanceScope = this.GlobalScope.Get(funcDef.ScopeResolution.ID, Classification.Class).Link; } var newFunctionScope = new SymbolTable(); // Add the return values. newFunctionScope.Add(new TableEntry("retaddr", Classification.SubCalculationStackSpace, 4), (0, 0)); newFunctionScope.Add(new TableEntry("retval", Classification.SubCalculationStackSpace, funcDef.NodeMemorySize), (0, 0)); if (funcDef.ScopeResolution != null) { newFunctionScope.AddRange(this.GlobalScope.Get(funcDef.ScopeResolution.ID, Classification.Class).Link.GetAll(Classification.Variable), (0, 0)); } newFunctionScope.AddRange(this.FunctionScopeLink.Link.GetAll(), (0, 0)); FunctionScopeLink.Link = newFunctionScope; }
public SymbolTable GetCurrentScope() { var table = new SymbolTable(); table.AddRange(this.GlobalScope.GetAll(), (0, 0)); table.AddRange(this.FunctionScopeLink?.Link?.GetAll(), (0, 0)); table.AddRange(this.ClassInstanceScope?.GetAll(), (0, 0)); return(table); }
public void AddRange() { var symbols = new Symbol[]{ new Symbol(SymbolType.Private, "id1"), new Symbol(SymbolType.Public, "id2") }; SymbolTable table = new SymbolTable(); Assert.AreEqual(0, table.Count); table.AddRange(symbols); Assert.AreEqual(symbols.Length, table.Count); Assert.AreEqual(symbols, table.ToArray()); }
public void AddRange() { var symbols = new Symbol[] { new Symbol(SymbolType.Private, "id1"), new Symbol(SymbolType.Public, "id2") }; SymbolTable table = new SymbolTable(); Assert.AreEqual(0, table.Count); table.AddRange(symbols); Assert.AreEqual(symbols.Length, table.Count); Assert.AreEqual(symbols, table.ToArray()); }
public override void Visit(Program node) { // Determines whether or not a class contains full implementation. Dictionary <string, object> Done = new Dictionary <string, object>(); // This is done after we visited all the classes. foreach (var classEntry in classes.Values) { var visiting = new Stack <ClassDecl>(); var visited = new Dictionary <string, object>(); var implementation = new SymbolTable(); var focus = classEntry; implementation.AddRange(classEntry.Table.GetAll(), classEntry.Location); do { visited.Add(focus.ClassName, null); foreach (var parent in focus.InheritingClasses.IDs) { if (Done.ContainsKey(parent)) { implementation.AddRange(classes[parent].Table.GetAll(), classEntry.Location, true); } else { if (visited.ContainsKey(parent)) { ErrorManager.Add($"Circular dependancy deteced between {focus.ClassName} and {parent}.", focus.Location); visiting.Clear(); break; } else { if (classes.ContainsKey(parent)) { implementation.AddRange(classes[parent].Table.GetAll(), classEntry.Location); visiting.Push(classes[parent]); } else { ErrorManager.Add($"The class {parent} cannot be found or is not defined.", focus.Location); } } } } if (visiting.Count > 0) { focus = visiting.Pop(); } else { focus = null; } } while (focus != null); Done.Add(classEntry.ClassName, null); classEntry.Table = implementation; } foreach (var classEntry in GlobalScope.GetAll(Classification.Class)) { classEntry.Link = classes[classEntry.ID].Table; } }
public override void Visit(Var var) { SymbolTable currentScope = new SymbolTable(); currentScope.AddRange(this._functionScope.GetAll(), var.Location); currentScope.AddRange(this._globalScope.GetAll(), var.Location); currentScope.AddRange(this._classInstanceScope?.GetAll(), var.Location); foreach (var element in var.Elements) { if (element is AParams aparams) { throw new System.Exception(); } if (element is DataMember dataMember) { TableEntry entry = null; if (currentScope.Get($"{dataMember.Id}-{Classification.Variable}") is TableEntry vEntry) { entry = vEntry; } else if (currentScope.Get($"{dataMember.Id}-{Classification.Parameter}") is TableEntry pEntry) { entry = pEntry; } else { ErrorManager.Add($"The {Classification.Variable} {dataMember.Id} could not be resolved.", dataMember.Location); break; } int actualNumParams; if (dataMember.Indexes == null) { actualNumParams = 0; } else { actualNumParams = dataMember.Indexes.Expressions.Count; } int expectedNumParams = entry.Type.Count(val => val == '['); int diffIndices = expectedNumParams - actualNumParams; if (diffIndices < 0) { ErrorManager.Add($"Too many indices for {dataMember.Id}. Got {actualNumParams}, expected {expectedNumParams}", dataMember.Location); break; } for (int i = 0; i < actualNumParams && i < expectedNumParams; i++) { var exp = dataMember.Indexes.Expressions[i] as Node; if (exp.SemanticalType != "int") { ErrorManager.Add($"Index must be of type int and not {exp.SemanticalType}.", exp.Location); } } dataMember.SemanticalType = entry.Type.Replace("[]", string.Empty) + "[]".Repeat(diffIndices); var.SemanticalType = dataMember.SemanticalType; currentScope = new SymbolTable(); currentScope.AddRange(_globalScope.Get($"{var.SemanticalType}-{Classification.Class}")?.Link?.GetAll(), var.Location); } if (element is FCall fcall) { TableEntry entry = currentScope.Get($"{fcall.Id}-{Classification.Function}"); if (entry != null) { var types = entry.Type.Split('-'); string returnType = types[0]; var parameters = types[1] == "" ? new string[0] : types[1].Split(','); if (parameters.Length == fcall.Parameters.Expressions.Count) { for (int i = 0; i < parameters.Length; i++) { string expectedType = parameters[i]; var expression = fcall.Parameters.Expressions[i] as Node; if (expression != null) { string actualType = expression.SemanticalType; if (actualType != expectedType) { ErrorManager.Add($"Invalid parameter type: Expected {expectedType}, got {actualType}", expression.Location); break; } } else { throw new System.Exception(); } } fcall.SemanticalType = returnType; var.SemanticalType = returnType; if (entry.Link == null) { ErrorManager.Add($"The function {fcall.Id} is not linked.", fcall.Location); //break; } currentScope = new SymbolTable(); currentScope.AddRange(_globalScope.Get($"{var.SemanticalType}-{Classification.Class}")?.Link?.GetAll(), var.Location); } else { ErrorManager.Add($"The function {fcall.Id} takes in {parameters.Length} arguments.", fcall.Location); var.SemanticalType = returnType; break; } } else { ErrorManager.Add($"The function {fcall.Id} could not be found or does not exist.", fcall.Location); break; } } } }
protected virtual void CloneFrom(MetaTableImpl metaTable) { _table = _createInternalStorage(metaTable.Count); _table.AddRange(metaTable._table); _filter = metaTable._filter; }