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); }