Пример #1
0
        public string Compile()
        {
            EmitLn("@echo off");
            EmitLn("setlocal EnableExtensions");
            EmitLn("setlocal EnableDelayedExpansion<NL>");
            Comment("SETTING WINDOW TITLE");
            EmitLn("set window_title=Harpy Program");
            EmitLn("title Harpy Program<NL>");
            Comment("GLOBAL VARIABLE DECLARATION");

            /*for (int i = 0; i < 9; i++)
             * {
             *  Variables.Create("arg_" + i, new Value(Value.BatchType.String, "%" + (i + 1)));
             * }*/

            // import includes
            while (CurrentToken != "eof")
            {
                if (CurrentToken == "include")
                {
                    Eat();
                    evaluator.DoIncludes();
                    Reset();
                    //break;
                }
                else
                {
                    Eat();
                }
            }

            Reset();

            // register global variables
            while (CurrentToken != "eof")
            {
                if (CurrentToken == "function")
                {
                    Eat();

                    while (CurrentToken != "l curly")
                    {
                        Eat();
                    }

                    SkipBlock();
                }
                else if (CurrentToken == "var")
                {
                    Eat();
                    evaluator.RegisterGlobalVariable();
                }
                else
                {
                    Eat();
                }
            }

            Reset();

            // register functions
            while (CurrentToken != "eof")
            {
                if (CurrentToken == "function")
                {
                    Eat();
                    evaluator.RegisterFunction();
                }
                else
                {
                    Eat();
                }
            }

            Reset();

            //UserFunctions.userFuncs.Reverse();
            if (!UserFunctions.Exists("main"))
            {
                throw Exception("Program is missing an entry point marked by: main(...): void");
            }

            if (UserFunctions.userFuncs.Count(x => x.name == "main") > 1)
            {
                throw Exception("Cannot have multiple entry points");
            }

            var entryPoint = UserFunctions.userFuncs.Find(x => x.name == "main");
            var id         = UserFunctions.GetID(entryPoint);

            foreach (var type in entryPoint.argumentTypes)
            {
                if (type != Value.BatchType.String)
                {
                    throw Exception("Entry point can only have parameters of type string");
                }
            }

            // compile program
            Lexer.mainCompile = true;

            while (CurrentToken != "eof")
            {
                if (CurrentToken != "function" && CurrentToken != "var" && CurrentToken != "semicolon")
                {
                    throw Exception("Unexpected token in the global scope: " + CurrentToken);
                }

                string line = evaluator.Evaluate().value + "\n";
                if (line.Trim().StartsWith("%"))
                {
                    continue;
                }

                //Variables.ClearTemporaryVariables();

                output += line;
            }

            output += "<NL>";
            Comment("CALL TO ENTRY POINT");
            output += "call :func_" + id + " %1 %2 %3 %4 %5 %6 %7 %8 %9\n";

            // append function bodies
            output += "goto :EOF\n<NL>";
            foreach (var func in UserFunctions.userFuncs)
            {
                output += func.body + "<NL>";
            }

            Lexer.mainCompile = false;

            return(output);
        }