public void CopyFrom(Annotation Other) { Element = Other.Element; FirstRunnable = Other.FirstRunnable; RunnableParentBlock = Other.RunnableParentBlock; RunnablesCount = Other.RunnablesCount; TreeViewNode = Other.TreeViewNode; ListViewItem = Other.ListViewItem; SourcePosition = Other.SourcePosition; CompiledPosition = Other.CompiledPosition; IDE = Other.IDE; }
/// <summary> /// Parse imports and imported functions' aliases /// </summary> /// <returns></returns> public bool ParseImports() { Dictionary<string, Dictionary<string, List<string>>> imports = new Dictionary<string, Dictionary<string, List<string>>>(); HashSet<string> all_aliases = new HashSet<string>(); //Find all imports while (_caret.WS().Match(@"(?<_kw>import)(?!\w)")) { Element el; string file = null; Dictionary<string, List<string>> aliases = new Dictionary<string, List<string>>(); //Get the file name el = PELiteral(null); if ((el == null) || !(el is TextSearch) || (((TextSearch)el).Type != TextSearch.eType.Normal)) ThrowParseError("Expected the file name", (el == null) ? _caret.LastMatch : el.Annotation.SourcePosition); else { file = ((Literal)(((TextSearch)el).Pattern)).Text; if (imports.ContainsKey(file)) { ThrowParseError("File already imported", el.Annotation.SourcePosition); file = null; } } //Get function aliases if (_caret.WS().Match(@"(?<_kw>aliases)(?!\w)")) { if (!_caret.WS().Match(@"\{")) ThrowParseError("Expected {"); else { while (true) { //End of aliases if (_caret.WS().Match(@"}")) { _caret.Position = _caret.LastMatch.Index; break; } //Get alias(es) if (!_caret.WS().Match(@"(?<_fun>\w+)(?!\w){ws}?(\>{ws}?(?<_fun>\w+)(?!\w)({ws}?,{ws}?(?<_fun>\w+)(?!\w))*)?")) { ThrowParseError("Expected 'Function>Alias1,Alias2' or 'Function>Alias' or 'Function'"); break; } else { var grps = _caret.LastMatch.Groups["_fun"]; var fun_name = grps.Captures[0].Value; List<string> fun_aliases; //Get aliases list and add if needed if (aliases.ContainsKey(fun_name)) fun_aliases = aliases[fun_name]; else { fun_aliases = new List<string>(); aliases.Add(fun_name, fun_aliases); } //Check if an alias is already declared, and if not add it if (grps.Captures.Count > 1) { for (int i = 1 ; i < grps.Captures.Count ; i++) { var c = grps.Captures[i]; if (all_aliases.Contains(c.Value)) ThrowParseError(string.Format("Alias '{0}' already declared", c.Value), c); else { fun_aliases.Add(c.Value); all_aliases.Add(c.Value); } } } //Import without changing the name else { if (all_aliases.Contains(fun_name)) ThrowParseError(string.Format("Alias '{0}' already declared", fun_name)); else { fun_aliases.Add(fun_name); all_aliases.Add(fun_name); } } } } if (aliases.Count == 0) ThrowParseError("No aliases specified"); if (!_caret.WS().Match(@"}")) ThrowParseError("Expected }"); } } //Successful import if (file != null) imports.Add(file, aliases); } //Load imports IDE temp_ide = new IDE(); temp_ide.GetSourceFile = IDE.GetSourceFile; //Load and parse the imports if (temp_ide.GetSourceFile == null) { if (imports.Count > 0) ThrowParseError("Imports defined but no way to get source files is provided"); } else foreach (var im in imports) { temp_ide.Clear(); //Get the source file if (!temp_ide.GetSourceFile(IDE.SourceUID, im.Key, out temp_ide.SourceText, out temp_ide.SourceUID, out temp_ide.SourceFileName)) ThrowParseError(string.Format("Could not get source file '{0}' in '{1}'", im.Key, IDE.SourceFileName)); else { //Parse it if (!temp_ide.Parser.Parse() || (temp_ide.GrammarTree.ParseErrors.Count > 0)) ThrowParseError(string.Format("Errors encountered parsing source file '{0}'({1}) in '{2}'", im.Key, temp_ide.SourceFileName, IDE.SourceFileName)); //Add the imported functions var als = im.Value; var funs = temp_ide.GrammarTree.Functions; foreach (var fun in funs) //Add with alias if (als.ContainsKey(fun.Name)) { foreach (var fal in als[fun.Name]) ImportedFunctions.Add(fal, fun); als.Remove(fun.Name); } else if (!all_aliases.Contains(fun.Name)) ImportedFunctions.Add(fun.Name, fun); foreach (var al in als) ThrowParseError(string.Format("'{0}' not defined in file '{1}'", al.Key, im.Key)); //Update maximum function variables (+ arguments) if (temp_ide.GrammarTree.MaxFunctionVariables > IDE.GrammarTree.MaxFunctionVariables) IDE.GrammarTree.MaxFunctionVariables = temp_ide.GrammarTree.MaxFunctionVariables; } } return true; }