public Executable[] ParseInterpretedCode(string filename, string code, string libraryName) { int fileId = this.GetNextFileId(); this.RegisterFileUsed(filename, code, fileId); Token[] tokenList = Tokenizer.Tokenize(filename, code, fileId, true); TokenStream tokens = new TokenStream(tokenList); List <Executable> executables = new List <Executable>(); List <string> namespaceImportsBuilder = new List <string>(); tokens.InsertTokens(implicitCoreImport); while (tokens.HasMore && tokens.IsNext("import")) { ImportStatement importStatement = ExecutableParser.Parse(this, tokens, false, true, true, null) as ImportStatement; if (importStatement == null) { throw new Exception(); } namespaceImportsBuilder.Add(importStatement.ImportPath); Executable[] libraryEmbeddedCode = this.SystemLibraryManager.ImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath); executables.AddRange(libraryEmbeddedCode); } string[] namespaceImports = namespaceImportsBuilder.ToArray(); while (tokens.HasMore) { Executable executable; try { executable = ExecutableParser.Parse(this, tokens, false, true, true, null); } catch (EofException) { throw new ParserException(null, "Unexpected EOF encountered while parsing " + filename + ". Did you forget a closing curly brace?"); } if (executable is ImportStatement) { throw new ParserException(executable.FirstToken, "All imports must occur at the beginning of the file."); } executable.NamespacePrefixSearch = namespaceImports; executable.LibraryName = libraryName; if (executable is Namespace) { ((Namespace)executable).GetFlattenedCode(executables, namespaceImports, libraryName); } else { executables.Add(executable); } } return(executables.ToArray()); }
public void ParseInterpretedCode(string filename, string code) { FileScope fileScope = new FileScope(filename); int fileId = this.GetNextFileId(); this.RegisterFileUsed(filename, code, fileId); Token[] tokenList = Tokenizer.Tokenize(filename, code, fileId, true); TokenStream tokens = new TokenStream(tokenList, filename); List <string> namespaceImportsBuilder = new List <string>(); tokens.InsertTokens(this.GetImplicitCoreImport()); if (this.CurrentLibrary != null && this.CurrentLibrary.CanonicalKey != "en:Core") { Library coreLibrary = this.LibraryManager.GetCoreLibrary(this); this.CurrentLibrary.AddLibraryDependency(coreLibrary); } List <CompilationScope> scopesAdded = new List <CompilationScope>(); while (tokens.HasMore && tokens.IsNext(this.Keywords.IMPORT)) { ImportStatement importStatement = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope) as ImportStatement; if (importStatement == null) { throw new Exception(); } namespaceImportsBuilder.Add(importStatement.ImportPath); Library library = this.LibraryManager.ImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath); if (library == null) { this.unresolvedImports.Add(importStatement); } else { if (this.CurrentLibrary != null) { this.CurrentLibrary.AddLibraryDependency(library); } scopesAdded.Add(library.Scope); } } string[] namespaceImports = namespaceImportsBuilder.ToArray(); while (tokens.HasMore) { TopLevelConstruct executable = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope); if (executable is ImportStatement) { throw new ParserException( executable.FirstToken, this.CurrentLocale.Strings.Get("ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE")); } this.CurrentScope.AddExecutable(executable); } }
public Executable[] ParseInterpretedCode(string filename, string code, string libraryName) { int fileId = this.GetNextFileId(); this.RegisterFileUsed(filename, code, fileId); Token[] tokenList = Tokenizer.Tokenize(filename, code, fileId, true); TokenStream tokens = new TokenStream(tokenList, filename); List <Executable> executables = new List <Executable>(); List <string> namespaceImportsBuilder = new List <string>(); tokens.InsertTokens(this.GetImplicitCoreImport()); Library activeLibrary = libraryName == null ? null : this.LibraryManager.GetLibraryFromName(libraryName); if (libraryName != null && libraryName != "Core") { activeLibrary.AddLibraryDependency(this.LibraryManager.GetLibraryFromName("Core")); } while (tokens.HasMore && tokens.IsNext(this.Keywords.IMPORT)) { ImportStatement importStatement = this.ExecutableParser.Parse(tokens, false, true, true, null) as ImportStatement; if (importStatement == null) { throw new Exception(); } namespaceImportsBuilder.Add(importStatement.ImportPath); List <Executable> libraryEmbeddedCode = new List <Executable>(); Library library = this.LibraryManager.ImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath, libraryEmbeddedCode); if (library == null) { this.unresolvedImports.Add(importStatement); } else { if (activeLibrary != null) { activeLibrary.AddLibraryDependency(library); } executables.AddRange(libraryEmbeddedCode); } } string[] namespaceImports = namespaceImportsBuilder.ToArray(); while (tokens.HasMore) { Executable executable = this.ExecutableParser.Parse(tokens, false, true, true, null); if (executable is ImportStatement) { throw new ParserException( executable.FirstToken, this.Locale.Strings.Get("ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE")); } executable.NamespacePrefixSearch = namespaceImports; executable.LibraryName = libraryName; if (executable is Namespace) { ((Namespace)executable).GetFlattenedCode(executables, namespaceImports, libraryName); } else { executables.Add(executable); } } return(executables.ToArray()); }
public static Executable Parse(Parser parser, TokenStream tokens, bool simpleOnly, bool semicolonPresent, bool isRoot, Executable owner) { string value = tokens.PeekValue(); if (!simpleOnly) { if (parser.IsTranslateMode && value == "struct") { if (!isRoot) { throw new ParserException(tokens.Peek(), "structs cannot be nested into any other construct."); } // struct is special. If you are not compiling in JS mode, if (Parser.IsValidIdentifier(tokens.PeekValue(1)) && tokens.PeekValue(2) == "{") { return ParseStruct(tokens, owner); } } if (!isRoot && (value == "function" || value == "class")) { throw new ParserException(tokens.Peek(), (value == "function" ? "Function" : "Class") + " definition cannot be nested in another construct."); } if (value == "import") { Token importToken = tokens.PopExpected("import"); bool inline = parser.IsTranslateMode && tokens.PopIfPresent("inline"); if (inline) { Token fileToken = tokens.Pop(); char c = fileToken.Value[0]; if (c != '\'' && c != '"') throw new ParserException(fileToken, "Inline imports are supposed to be strings."); tokens.PopExpected(";"); string inlineImportFileName = fileToken.Value.Substring(1, fileToken.Value.Length - 2); string inlineImportFileContents = Util.ReadFileInternally(inlineImportFileName); // TODO: Anti-pattern alert. Clean this up. if (inlineImportFileContents.Contains("%%%")) { Dictionary<string, string> replacements = parser.NullablePlatform.InterpreterCompiler.BuildReplacementsDictionary(); inlineImportFileContents = Constants.DoReplacements(inlineImportFileContents, replacements); } TokenStream inlineTokens = Tokenizer.Tokenize(inlineImportFileName, inlineImportFileContents, 0, true); // OMGHAX - insert the inline import into the current token stream. tokens.InsertTokens(inlineTokens); return ExecutableParser.Parse(parser, tokens, simpleOnly, semicolonPresent, isRoot, owner); // start exectuable parser anew. } if (!isRoot) { throw new ParserException(tokens.Peek(), "Imports can only be made from the root of a file and cannot be nested inside other constructs."); } List<string> importPathBuilder = new List<string>(); while (!tokens.PopIfPresent(";")) { if (importPathBuilder.Count > 0) { tokens.PopExpected("."); } Token pathToken = tokens.Pop(); Parser.VerifyIdentifier(pathToken); importPathBuilder.Add(pathToken.Value); } string importPath = string.Join(".", importPathBuilder); return new ImportStatement(importToken, importPath); } if (value == "enum") { if (!isRoot) { throw new ParserException(tokens.Peek(), "Enums can only be defined from the root of a file and cannot be nested inside functions/loops/etc."); } return ParseEnumDefinition(parser, tokens, owner); } if (value == "namespace") { if (!isRoot) { throw new ParserException(tokens.Peek(), "Namespace declarations cannot be nested in other constructs."); } } switch (value) { case "namespace": return ParseNamespace(parser, tokens, owner); case "function": return ParseFunction(parser, tokens, owner); case "class": return ParseClassDefinition(parser, tokens, owner); case "enum": return ParseEnumDefinition(parser, tokens, owner); case "for": return ParseFor(parser, tokens, owner); case "while": return ParseWhile(parser, tokens, owner); case "do": return ParseDoWhile(parser, tokens, owner); case "switch": return ParseSwitch(parser, tokens, owner); case "if": return ParseIf(parser, tokens, owner); case "try": return ParseTry(parser, tokens, owner); case "return": return ParseReturn(tokens, owner); case "break": return ParseBreak(tokens, owner); case "continue": return ParseContinue(tokens, owner); case "const": return ParseConst(parser, tokens, owner); case "constructor": return ParseConstructor(parser, tokens, owner); default: break; } } Expression expr = ExpressionParser.Parse(tokens, owner); value = tokens.PeekValue(); if (ASSIGNMENT_OPS.Contains(value)) { Token assignment = tokens.Pop(); Expression assignmentValue = ExpressionParser.Parse(tokens, owner); if (semicolonPresent) tokens.PopExpected(";"); return new Assignment(expr, assignment, assignment.Value, assignmentValue, owner); } if (semicolonPresent) { tokens.PopExpected(";"); } return new ExpressionAsExecutable(expr, owner); }
public static Executable Parse(Parser parser, TokenStream tokens, bool simpleOnly, bool semicolonPresent, bool isRoot, Executable owner) { string value = tokens.PeekValue(); if (!simpleOnly) { Token staticToken = null; Token finalToken = null; while (value == "static" || value == "final") { if (value == "static" && staticToken == null) { staticToken = tokens.Pop(); value = tokens.PeekValue(); } if (value == "final" && finalToken == null) { finalToken = tokens.Pop(); value = tokens.PeekValue(); } } if (staticToken != null || finalToken != null) { if (value != "class") { if (staticToken != null) { throw new ParserException(staticToken, "Only classes, methods, and fields may be marked as static"); } else { throw new ParserException(finalToken, "Only classes may be marked as final."); } } if (staticToken != null && finalToken != null) { throw new ParserException(staticToken, "Classes cannot be both static and final."); } } if (!isRoot && (value == "function" || value == "class")) { throw new ParserException(tokens.Peek(), (value == "function" ? "Function" : "Class") + " definition cannot be nested in another construct."); } if (parser.IsTranslateMode && value == "struct") { if (!isRoot) { throw new ParserException(tokens.Peek(), "structs cannot be nested into any other construct."); } return(ParseStruct(tokens, owner)); } if (value == "import") { Token importToken = tokens.PopExpected("import"); bool inline = parser.IsTranslateMode && tokens.PopIfPresent("inline"); if (inline) { Token fileToken = tokens.Pop(); char c = fileToken.Value[0]; if (c != '\'' && c != '"') { throw new ParserException(fileToken, "Inline imports are supposed to be strings."); } tokens.PopExpected(";"); string inlineImportFileName = fileToken.Value.Substring(1, fileToken.Value.Length - 2); string inlineImportFileContents; if (inlineImportFileName.StartsWith("LIB:")) { string[] parts = inlineImportFileName.Split(':'); string libraryName = parts[1]; string filename = FileUtil.JoinPath(parts[2].Split('/')); Library library = parser.SystemLibraryManager.GetLibraryFromKey(libraryName.ToLower()); inlineImportFileContents = library.ReadFile(filename, false); } else { inlineImportFileContents = Util.ReadInterpreterFileInternally(inlineImportFileName); } // TODO: Anti-pattern alert. Clean this up. if (inlineImportFileContents.Contains("%%%")) { Dictionary <string, string> replacements = parser.NullablePlatform.InterpreterCompiler.BuildReplacementsDictionary(); inlineImportFileContents = Constants.DoReplacements(inlineImportFileContents, replacements); } Token[] inlineTokens = Tokenizer.Tokenize(inlineImportFileName, inlineImportFileContents, 0, true); tokens.InsertTokens(inlineTokens); return(ExecutableParser.Parse(parser, tokens, simpleOnly, semicolonPresent, isRoot, owner)); // start exectuable parser anew. } if (!isRoot) { throw new ParserException(tokens.Peek(), "Imports can only be made from the root of a file and cannot be nested inside other constructs."); } List <string> importPathBuilder = new List <string>(); while (!tokens.PopIfPresent(";")) { if (importPathBuilder.Count > 0) { tokens.PopExpected("."); } Token pathToken = tokens.Pop(); Parser.VerifyIdentifier(pathToken); importPathBuilder.Add(pathToken.Value); } string importPath = string.Join(".", importPathBuilder); return(new ImportStatement(importToken, importPath)); } if (value == "enum") { if (!isRoot) { throw new ParserException(tokens.Peek(), "Enums can only be defined from the root of a file and cannot be nested inside functions/loops/etc."); } return(ParseEnumDefinition(parser, tokens, owner)); } if (value == "namespace") { if (!isRoot) { throw new ParserException(tokens.Peek(), "Namespace declarations cannot be nested in other constructs."); } } switch (value) { case "namespace": return(ParseNamespace(parser, tokens, owner)); case "function": return(ParseFunction(parser, tokens, owner)); case "class": return(ParseClassDefinition(parser, tokens, owner, staticToken, finalToken)); case "enum": return(ParseEnumDefinition(parser, tokens, owner)); case "for": return(ParseFor(parser, tokens, owner)); case "while": return(ParseWhile(parser, tokens, owner)); case "do": return(ParseDoWhile(parser, tokens, owner)); case "switch": return(ParseSwitch(parser, tokens, owner)); case "if": return(ParseIf(parser, tokens, owner)); case "try": return(ParseTry(parser, tokens, owner)); case "return": return(ParseReturn(tokens, owner)); case "break": return(ParseBreak(tokens, owner)); case "continue": return(ParseContinue(tokens, owner)); case "const": return(ParseConst(parser, tokens, owner)); case "constructor": return(ParseConstructor(parser, tokens, owner)); default: break; } } Expression expr = ExpressionParser.Parse(tokens, owner); value = tokens.PeekValue(); if (ASSIGNMENT_OPS.Contains(value)) { Token assignment = tokens.Pop(); Expression assignmentValue = ExpressionParser.Parse(tokens, owner); if (semicolonPresent) { tokens.PopExpected(";"); } return(new Assignment(expr, assignment, assignment.Value, assignmentValue, owner)); } if (semicolonPresent) { tokens.PopExpected(";"); } return(new ExpressionAsExecutable(expr, owner)); }