Пример #1
0
 public ScopeSymbolTable(string name, int level, ScopeSymbolTable enclosingScope = null)
 {
     this.ScopeName      = name;
     this.scopeLevel     = level;
     this.enclosingScope = enclosingScope;
     InitBuiltins();
 }
Пример #2
0
        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;
            }
        }
Пример #3
0
        public ScopeSymbolTable SetScope(ScopeSymbolTable scope)
        {
            ScopeSymbolTable originalScope = currentScope;

            currentScope = scope;
            return(originalScope);
        }
Пример #4
0
 public ScopeSymbolTable Merge(ScopeSymbolTable scope)
 {
     foreach (Symbol symbol in scope.Symbols.Values)
     {
         Insert(symbol);
     }
     return(this);
 }
Пример #5
0
        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;
        }
Пример #6
0
        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;
        }
Пример #7
0
        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"));
            }
        }
Пример #8
0
 private object Visit(ProgramAST programAST)
 {
     currentScope             = new ScopeSymbolTable(programAST.Name, 0);
     modules[CurrentFileName] = currentScope;
     return(Visit(programAST.Statements));
 }
Пример #9
0
 public ScopeSymbol(string name, TypeSymbol type, ScopeSymbolTable value) : base(name, type, value)
 {
 }