public ScopeSymbolTable(string name, int level, ScopeSymbolTable enclosingScope = null) { this.ScopeName = name; this.scopeLevel = level; this.enclosingScope = enclosingScope; InitBuiltins(); }
private void ImportLocalFile(ImportAST importAST) { ScopeSymbolTable mainScope = currentScope; string fileName = string.Join('/', importAST.FileName.ConvertAll(file => Visit(file))); folder = importAST.Relative ? relativeFolder : rootFolder; Interpret(fileName); if (importAST.Symbols.Count == 0) { currentScope = mainScope.Merge(currentScope); } else { foreach (var symbolName in importAST.Symbols) { var symbol = currentScope.Lookup(Visit(symbolName), false); if (symbol == null) { throw logger.Error(new SemanticException(symbolName.FindToken(), $"Cannot import {Visit(symbolName)} from {importAST.FileName.Last()}")); } if (!mainScope.Insert(symbol, false)) { throw logger.Error(new SemanticException(symbolName.FindToken(), $"Cannot import {Visit(symbolName)} since it has already exists")); } } currentScope = mainScope; } }
public ScopeSymbolTable SetScope(ScopeSymbolTable scope) { ScopeSymbolTable originalScope = currentScope; currentScope = scope; return(originalScope); }
public ScopeSymbolTable Merge(ScopeSymbolTable scope) { foreach (Symbol symbol in scope.Symbols.Values) { Insert(symbol); } return(this); }
public void Interpret(string fileName, bool global = false) { string fullFileName = Path.Join(folder, fileName); if (Directory.Exists(fullFileName)) { fullFileName = Path.Join(fullFileName, "index.lig"); } else if (File.Exists(fullFileName)) { } else { fullFileName += ".lig"; } string nextFileName = Path.GetFullPath(fullFileName); if (modules.ContainsKey(nextFileName)) { currentScope = modules[nextFileName]; return; } string lastFileName = CurrentFileName; CurrentFileName = nextFileName; string text; try { text = File.ReadAllText(fullFileName); } catch (IOException) { throw logger.Error(new NotFoundException($"File {fullFileName}")); } string originalRelativeFolder = relativeFolder; relativeFolder = Path.GetDirectoryName(fullFileName); Parser parser = new Parser(); parser.Load(text, files.IndexOf(CurrentFileName)); ProgramAST programAST; if (global) { programAST = parser.Parse(); } else { programAST = parser.Parse(fileName); } Interpret(programAST); CurrentFileName = lastFileName; relativeFolder = originalRelativeFolder; }
private void UsingLocalFile(UsingAST usingAST) { string fileName = string.Join('/', usingAST.FileName.ConvertAll(file => Visit(file))); TypeSymbol scopeType = currentScope.Lookup("SCOPE") as TypeSymbol; ScopeSymbolTable mainScope = currentScope; ScopeSymbolTable scopeSymbolTable = mainScope; folder = usingAST.Relative ? relativeFolder : rootFolder; Interpret(fileName); ScopeSymbol scopeSymbol; string module; if (usingAST.ModuleName != null) { module = Visit(usingAST.ModuleName); } else { module = Visit(usingAST.FileName.Last()); foreach (WordAST folder in usingAST.FileName.Take(usingAST.FileName.Count - 1)) { var symbol = scopeSymbolTable.Lookup(folder.Word); if (symbol != null && symbol is ScopeSymbol scope) { scopeSymbolTable = scope.GetValue() as ScopeSymbolTable; } else if (folder.Word == "..") { continue; } else { var temp = new ScopeSymbolTable(folder.Word, 0); scopeSymbol = new ScopeSymbol(folder.Word, scopeType, temp); if (!scopeSymbolTable.Insert(scopeSymbol, false)) { throw logger.Error(new SemanticException(folder.FindToken(), $"Cannot using {folder.Word} since it has already exists, consider rename it.")); } scopeSymbolTable = temp; } } } scopeSymbol = new ScopeSymbol(module, scopeType, currentScope); if (!scopeSymbolTable.Insert(scopeSymbol, false)) { throw logger.Error(new SemanticException((usingAST.ModuleName ?? usingAST.FileName.Last()).FindToken(), $"Cannot using {module} since it has already exists.")); } currentScope = mainScope; }
private object Visit(PointerAST pointerAST) { ScopeSymbolTable scope = Visit(pointerAST.ScopeName) as ScopeSymbolTable; if (scope != null) { ScopeSymbolTable tempScope = currentScope; currentScope = scope; object member = Visit(pointerAST.Member); currentScope = tempScope; return(member); } else { throw logger.Error(new SemanticException(pointerAST.ScopeName.FindToken(), "Scope expected")); } }
private object Visit(ProgramAST programAST) { currentScope = new ScopeSymbolTable(programAST.Name, 0); modules[CurrentFileName] = currentScope; return(Visit(programAST.Statements)); }
public ScopeSymbol(string name, TypeSymbol type, ScopeSymbolTable value) : base(name, type, value) { }