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(UsingAST usingAST) { try { UsingLocalFile(usingAST); } catch (NotFoundException) { string pluginName = Visit(usingAST.FileName.First()); if (!PluginManager.Plugins.ContainsKey(pluginName)) { throw logger.Error(new SemanticException(usingAST.FindToken(), $"No local file nor plugin was found.")); } logger.Solve(); if (usingAST.FileName.Count > 1 || usingAST.Relative) { throw logger.Error(new SemanticException(usingAST.FindToken(), "Plugin reference does not support path.")); } string module; if (usingAST.ModuleName != null) { module = Visit(usingAST.ModuleName); } else { module = pluginName; } try { PluginManager.UsingPlugin(pluginName, currentScope, module); } catch (PluginException) { throw logger.Error(new SemanticException(usingAST.FindToken(), $"Cannot using plugin {pluginName}")); } } return(null); }