private ScriptData CompileScripts(string code, IProgress <int> progress, ScriptCompilerLogger logger, ParsingExceptionCollector collector) { using (IReader reader = _streamManager.OpenRead()) { // Set up the lexer. logger.Information("Running the lexer..."); ICharStream stream = CharStreams.fromstring(code); HS_Gen1Lexer lexer = new HS_Gen1Lexer(stream); lexer.AddErrorListener(collector); ITokenStream tokens = new CommonTokenStream(lexer); // Set up the parser. logger.Information("Running the parser..."); HS_Gen1Parser parser = new HS_Gen1Parser(tokens); parser.AddErrorListener(collector); // Parse the scripts. parser.BuildParseTree = true; IParseTree tree = parser.hsc(); // Throw an exception if ANTLR reports parsing or lexing errors. if (collector.ContainsExceptions) { logger.Information("The collector contained errors. Cancelling the process..."); throw new OperationCanceledException($"Parsing Failed! {collector.ExceptionCount} Exceptions occured during the parsing process."); } // Load the context. var context = _scriptFile.LoadContext(reader, _cashefile); // Run the compiler. logger.Information("Running the compiler..."); bool outputDebugData = App.AssemblyStorage.AssemblySettings.OutputCompilerDebugData; ScriptCompiler compiler = new ScriptCompiler(_cashefile, _buildInfo, _opcodes, context, progress, logger, outputDebugData); ParseTreeWalker.Default.Walk(compiler, tree); return(compiler.Result()); } }
private async void CompileClick(object sender, RoutedEventArgs e) { // Logger Setup string folder = "Compiler"; if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } string logPath = Path.Combine(folder, "ScriptCompiler.log"); using (var logStream = File.Create(logPath)) { // Create the logger and the exception collector. They are used for debugging. var traceListener = new TextWriterTraceListener(logStream); var logger = new ScriptCompilerLogger(traceListener); var exceptionCollector = new ParsingExceptionCollector(); logger.Information($"Attempting to compile: {_scriptFile.Name}, Time: {DateTime.Now}"); try { // Get the script file. string hsc = txtScript.Text; // Measure the time it took to compile the scripts. var stopWatch = Stopwatch.StartNew(); // Compile the scripts. ScriptData compileData = await Task.Run(() => CompileScripts(hsc, _progress, logger, exceptionCollector)); stopWatch.Stop(); var timeSpan = stopWatch.Elapsed; string compilationMessage = $"The scripts were successfully compiled in {Math.Round(timeSpan.TotalSeconds, 3)} seconds."; logger.Information(compilationMessage); // Show the message box. var saveResult = MetroMessageBox.Show("Scripts Compiled", compilationMessage + "\nWARNING: This compiler is not 100% accurate and could corrupt the map in rare cases. Making a backup before proceeding is advisable." + "\n\nDo you want to save the changes to the file?", MetroMessageBox.MessageBoxButtons.YesNo); if (saveResult == MetroMessageBox.MessageBoxResult.Yes) { //TODO: Move this to its own function. await Task.Run(() => { using (IStream stream = _streamManager.OpenReadWrite()) { _scriptFile.SaveScripts(compileData, stream, _progress); _cashefile.SaveChanges(stream); } }); RefreshMeta(); StatusUpdater.Update("Scripts saved"); } } // Handle Parsing Errors. catch (OperationCanceledException opEx) { if (exceptionCollector.ContainsExceptions) { HandleParsingErrors(opEx, exceptionCollector, logger); } else { MetroMessageBox.Show("Operation Canceled", opEx.Message); } } // Handle Compiler Errors. catch (CompilerException compEx) { HandleCompilerErrors(compEx, logger); } finally { logger.Flush(); ResetProgressBar(); } } }