Beispiel #1
0
        public Result Parse(List <Token> tokens, Compiler.Settings settings = null)
        {
            if (settings == null)
            {
                settings = new Compiler.Settings();
            }

            this.Tokens       = tokens;
            this.CurrentIndex = 0;
            this.CurrentLine  = 0;
            Result result = new Result();

            this.Errors = result.Messages;

            while (!IsAtEnd())
            {
                SkipWhitespace();
                try
                {
                    if (ConsumeIfType(out Token classToken, TokenType.KeywordClass))
                    {
                        SkipWhitespace();

                        result.Classes.Add(ParseClassStatement(classToken));
                    }
                    else if (ConsumeIfType(out Token functionKeyword, TokenType.KeywordFunction))
                    {
                        SkipWhitespace();
                        result.Functions.Add(ParseSubroutineStatement(functionKeyword));
                    }
                    else if (ConsumeIfType(out Token globalKeyword, TokenType.KeywordGlobal))
                    {
                        SkipWhitespace();
                        Token globalName = ConsumeType(TokenType.Symbol, "Expected a name for the global.", "LSS007");
                        result.Globals.Add(new GlobalStatement(globalKeyword.Span + globalName.Span, globalName));
                        ConsumeType(TokenType.Semicolon, "Expected a semicolon after global name.", "LSS008");
                    }
                    else
                    {
                        Token extra = Consume();
                        if (extra.Type != TokenType.Whitespace && extra.Type != TokenType.Comment && extra.Type != TokenType.MultilineComment && extra.Type != TokenType.EndOfStream)
                        {
                            Panic("Expected global, class, or function", "LSS009", extra.Span);
                        }
                    }
                }
                catch (StatementPanicException)
                {
                    SynchronizeToStatement();
                }
                SkipWhitespace();
            }

            return(result);
        }
Beispiel #2
0
        private static int DoCompile(CLIOptions options)
        {
            List <CompileMessage> messages = new List <CompileMessage>();

            // Translate CLIOptions into compiler options
            Compiler.Settings settings = new Compiler.Settings();
            settings.EmitLineNumbers = options.EmitLineNumbers;
            string[] versionNumberParts = options.OSIVersion.Split('.');
            if (versionNumberParts.Length == 2)
            {
                settings.VersionMajor = Int32.Parse(versionNumberParts[0]);
                settings.VersionMinor = Int32.Parse(versionNumberParts[1]);
            }
            else
            {
                messages.Add(new CompileMessage("Invalid OSI version. Version number should be specified like '4.1'.", "LSSC001", CompileMessage.MessageSeverity.Warning, new SourceSpan("", 0, null, 0)));
            }

            // Check options.Inputs for directory names, and replace them with the files they contain, considering the option to be recursive
            List <string> inputs = new List <string>();

            foreach (string input in options.Inputs)
            {
                if (System.IO.Directory.Exists(input))
                {
                    EnumerateDirectory(input, inputs, options.RecurseDirectories);
                }
                else if (System.IO.File.Exists(input))
                {
                    inputs.Add(input);
                }
            }

            Compiler.Result result = Compiler.CompileFiles(inputs);
            messages.AddRange(result.Messages);

            int errorCount = 0;

            foreach (CompileMessage message in messages)
            {
                Console.WriteLine(message.ToString());
                if (message.Severity >= CompileMessage.MessageSeverity.Error)
                {
                    errorCount++;
                }
            }
            if (errorCount > 0)
            {
                Console.WriteLine("Finished with " + errorCount + " errors.");
                return(EXIT_SYNTAX_ERROR);
            }
            else
            {
                string outputFilename = System.IO.Path.GetFullPath(options.Output == "" ? "./base.osi" : options.Output);
                if (System.IO.File.Exists(outputFilename) && !options.AllowOverwrite)
                {
                    Console.WriteLine("Aborted - file '" + outputFilename + "' already exists. (Specify -y to overwrite.)");
                    return(EXIT_OUTPUT_EXISTS);
                }
                else
                {
                    try
                    {
                        using (System.IO.FileStream stream = new System.IO.FileStream(outputFilename, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read))
                            using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream))
                            {
                                result.OSI.Write(writer);
                            }
                        Console.WriteLine("Compiled into '" + outputFilename + "'.");
                        return(EXIT_SUCCESS);
                    }
                    catch (System.IO.IOException exception)
                    {
                        Console.WriteLine("Failed to write result to '" + outputFilename + "': " + exception.ToString());
                        return(EXIT_IO_ERROR);
                    }
                }
            }
        }