Beispiel #1
0
        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());
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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());
        }
Beispiel #4
0
		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);
		}
Beispiel #5
0
        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));
        }