//Fatal error, with token context. public static void Fatal(ParserRuleContext context, string errMessage) { //Is error catching on? if (AlgoRuntimeInformation.CatchExceptions) { //Don't actually perform any error tasks, just set the caught message. AlgoRuntimeInformation.SetExceptionMessage(errMessage); throw new Exception("Error caught, you shouldn't be seeing this message."); } //Set console colours. Console.ForegroundColor = ConsoleColor.White; Console.BackgroundColor = ConsoleColor.Red; //Check the loaded file is right. if (AlgoRuntimeInformation.FileLoaded == "") { AlgoRuntimeInformation.FileLoaded = "No File"; } //Print the actual error message. if (context == null) { Console.WriteLine("Algo Runtime Error: " + AlgoRuntimeInformation.FileLoaded + ", NOCONTEXT - " + errMessage); } else { Console.WriteLine("Algo Runtime Error: " + AlgoRuntimeInformation.FileLoaded + ", Line " + context.Start.Line + ":" + context.Start.StartIndex + " - " + errMessage); } Console.ResetColor(); //Only print the scopes in developer mode. if (AlgoRuntimeInformation.DeveloperMode) { ANTLRDebug.PrintScopes(); } //Test mode? Throw instead of exit. if (AlgoRuntimeInformation.UnitTestMode) { throw new Exception(errMessage); } //Check if we're in continuous mode. If so, just restart (no header). if (AlgoRuntimeInformation.ContinuousMode) { //If in continuous mode, just keep going and run the interpreter again. Program.Main(new string[] { "--nohead" }); Environment.Exit(0); } else { //Normal mode, just exit. Environment.Exit(-1); } }
//When a try/catch block is executed. public override object VisitStat_try_catch([NotNull] algoParser.Stat_try_catchContext context) { //Turn on execution catch mode. AlgoRuntimeInformation.CatchExceptions = true; //Loop over the statements, execute all. bool foundError = false; string errorMessage = ""; Scopes.AddScope(); foreach (var statement in context.block()[0].statement()) { //Execute statement. AlgoValue returned = null; try { returned = (AlgoValue)VisitStatement(statement); } catch (Exception e) { //C# error somewhere up the heirarchy, 90% means an error has been thrown. foundError = true; errorMessage = "Internal Language Error: " + e.Message; } //Check if an error has been found. if (AlgoRuntimeInformation.ExceptionCaught()) { //Yep, break out to the catch block. foundError = true; errorMessage = AlgoRuntimeInformation.GetExceptionMessage(); AlgoRuntimeInformation.CatchExceptions = false; break; } //If something was actually returned, return it up. if (returned != null) { AlgoRuntimeInformation.CatchExceptions = false; Scopes.RemoveScope(); return(returned); } } Scopes.RemoveScope(); //Turn off error catching. AlgoRuntimeInformation.CatchExceptions = false; //Done executing try statements, did an error come back? if (!foundError) { return(null); } //Yep, get the identifier to use for the error message, check it doesn't exist. if (Scopes.VariableExists(context.IDENTIFIER().GetText())) { Error.Fatal(context, "A variable already exists named '" + context.IDENTIFIER().GetText() + "', cannot use for catch parameter."); return(null); } //Create it, assign it the caught value. Scopes.AddScope(); Scopes.AddVariable(context.IDENTIFIER().GetText(), new AlgoValue() { Type = AlgoValueType.String, Value = errorMessage }, context); //Execute what's in the catch scope. foreach (var statement in context.block()[1].statement()) { AlgoValue returned = (AlgoValue)VisitStatement(statement); if (returned != null) { Scopes.RemoveScope(); return(returned); } } //Finished! return(null); }