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; } }
private object Visit(ImportAST importAST) { try { ImportLocalFile(importAST); } catch (NotFoundException) { string pluginName = Visit(importAST.FileName.First()); if (!PluginManager.Plugins.ContainsKey(pluginName)) { throw logger.Error(new SemanticException(importAST.FindToken(), $"No local file nor plugin was found.")); } logger.Solve(); if (importAST.FileName.Count > 1 || importAST.Relative) { throw logger.Error(new SemanticException(importAST.FindToken(), "Plugin reference does not support path.")); } try { if (importAST.Symbols.Count == 0) { PluginManager.ImportPlugin(pluginName, currentScope); } else { List <string> items = importAST.Symbols.ConvertAll(symbol => Visit(symbol)); PluginManager.ImportPlugin(pluginName, currentScope, items); } } catch (PluginException) { throw logger.Error(new SemanticException(importAST.FindToken(), $"Cannot import plugin {pluginName}")); } } return(null); }