/// <summary> /// Check if a given scope is a child of a function. /// </summary> /// <returns>True if the scope is a child of a function. Else false</returns> public bool IsInFunction() { SymbolTableObject symtab = this; while (this.Parent != null && (!this.Parent.Name?.StartsWith("func_") ?? false)) { symtab = this.Parent; } return((symtab.Parent?.Name?.StartsWith("func_") ?? false) || (this.Name?.StartsWith("func_") ?? false)); }
/// <summary> /// This method will update function parameters of an enclosing function /// </summary> /// <param name="node">The node to look for</param> /// <param name="rhs">The typecontext to assign the variable</param> /// <param name="scopeName">The name of the calling scope</param> public void UpdateFuncVar(VarNode node, TypeContext rhs, string scopeName) { SymbolTableObject symobj = SymbolTableBuilder.GlobalSymbolTable.Children.First(symtab => symtab.Name == scopeName); FuncNode func = SymbolTableObject.FunctionDefinitions.First(fn => this.Name.Contains(fn.Name.Id) && this.Name.Contains("_" + fn.Line)); if (func.FunctionParameters.Any(vn => vn.Id == node.Id)) { node.Declaration = false; } symobj.UpdateTypedef(node, rhs, scopeName, false); }
/// <summary> /// This method will find a child scope given the name of it /// </summary> /// <param name="name">The name of the scope</param> /// <returns>The scope found, if found. Else null</returns> public SymbolTableObject FindChild(string name) { SymbolTableObject found = null; foreach (SymbolTableObject child in this.Children) { if (child.Name == name) { return(child); } found = child.FindChild(name); if (found != null) { break; } } return(found); }
/// <summary> /// Gets the enclosing function scope, of the current scope /// </summary> /// <returns>The enclosing function of the current scope. Else null</returns> public SymbolTableObject GetEnclosingFunction() { SymbolTableObject symtab = this; while (this.Parent != null && (!this.Parent.Name?.StartsWith("func_") ?? false)) { symtab = this.Parent; } if (symtab.Parent?.Name?.StartsWith("func_") ?? false) { return(symtab.Parent); } else if ((this.Name?.StartsWith("func_") ?? false)) { return(this); } return(null); }
/// <summary> /// This method will close a scope, and update the current scope /// </summary> public void CloseScope() { CurrentSymbolTable = TopOfScope.Pop().Parent; }
/// <summary> /// A method that opens a new scope and symbol table. This symboltable is marked as a child of the current scope /// </summary> /// <param name="type">The type of scope being opened</param> /// <param name="name">The name of the scope being opened</param> public void OpenScope(TokenType type, string name) { CurrentSymbolTable = new SymbolTableObject { Type = type, Name = name, Parent = CurrentSymbolTable }; }
/// <summary> /// The constructor of the symboltable builder. Here the global scope is set /// </summary> /// <param name="global">The global scope</param> public SymbolTableBuilder(SymbolTableObject global) { GlobalSymbolTable = global; CurrentSymbolTable = global; }