private static int repl(string filename, string builtinsExtensionFile) { Console.WriteLine("* Grace REPL with runtime " + Interpreter.GetRuntimeVersion()); Console.WriteLine("Copyright (C) 2015, 2016 its authors."); Console.WriteLine("This program comes with ABSOLUTELY NO WARRANTY;" + " for details type `--about'."); ParseNode module; var ls = new LocalScope("repl-inner"); var obj = new UserObject(); var interp = REPL.CreateInterpreter(obj, ls); if (builtinsExtensionFile != null) { interp.LoadExtensionFile(builtinsExtensionFile); } else { interp.LoadExtensionFile(); } if (filename != null) { if (!File.Exists(filename)) { return(error("File `" + filename + "` does not exist.")); } var dir = Path.GetDirectoryName(Path.GetFullPath(filename)); interp.AddModuleRoot(dir); Console.WriteLine("* Loading " + filename + "..."); using (StreamReader reader = File.OpenText(filename)) { var parser = new Parser( Path.GetFileNameWithoutExtension(filename), reader.ReadToEnd()); module = parser.Parse(); ExecutionTreeTranslator ett = new ExecutionTreeTranslator(); Node eModule = ett.Translate(module as ObjectParseNode); try { obj = (UserObject)eModule.Evaluate(interp); } catch (GraceExceptionPacketException e) { Console.Error.WriteLine("Uncaught exception:"); ErrorReporting.WriteException(e.ExceptionPacket); if (e.ExceptionPacket.StackTrace != null) { foreach (var l in e.ExceptionPacket.StackTrace) { Console.Error.WriteLine(" from " + l); } } return(1); } } Console.WriteLine("* Loaded."); } else { var dir = Path.GetFullPath("."); interp.AddModuleRoot(dir); } Console.WriteLine("* Enter code at the prompt.\n"); ErrorReporting.SilenceError("P1001"); var memo = interp.Memorise(); var edit = new Editor(s => completion(obj, s)); string accum = String.Empty; bool unfinished = false; GraceObject result; string line = edit.GetLine(">>> "); while (line != null) { if (line.StartsWith("--about")) { var spl = line.Split(' '); about(spl.Length > 1 ? spl[1] : null); line = edit.GetLine(">>> "); continue; } accum += line.Replace("\u0000", "") + "\n"; var r = REPL.RunLine(interp, obj, memo, accum, out unfinished, out result); if (result != null) { ls["LAST"] = result; } if (unfinished) { // "Unexpected end of file" is expected here // for unfinished statements. line = edit.GetLine("... "); unfinished = false; continue; } else if (r != 0) { // All other errors are errors, and should // clear the accumulated buffer and let the // user start again. accum = String.Empty; } else { accum = String.Empty; } line = edit.GetLine(">>> "); } return(0); }
static int Main(string[] args) { var enc = new UTF8Encoding(false); Console.OutputEncoding = enc; Console.InputEncoding = enc; ParseNode module; string filename = null; string mode = "run"; string prettyOption = ""; bool verbose = false; string errorCodeTarget = null; var lines = new List <string>(); string builtinsExtensionFile = null; int lastArgs = 0; for (int i = 0; i < args.Length; i++) { var arg = args[i]; lastArgs = i; if (arg == "--help") { return(help()); } if (arg == "--about") { return(about(i + 1 < args.Length ? args[i + 1] : null)); } if (arg == "--parse-tree") { mode = "parse-tree"; } else if (arg.StartsWith("--pretty-print=")) { mode = "pretty-print"; prettyOption = arg.Substring(15); } else if (arg == "--pretty-print") { mode = "pretty-print"; } else if (arg == "--execution-tree") { mode = "execution-tree"; } else if (arg == "--no-run") { mode = "no-run"; } else if (arg == "--repl") { mode = "repl"; } else if (arg == "--ws") { mode = "ws"; } else if (arg == "--verbose") { Interpreter.ActivateDebuggingMessages(); verbose = true; } else if (arg == "--builtins-extension") { builtinsExtensionFile = args[++i]; } else if (arg == "--errors-to-file") { errorCodeTarget = args[++i]; } else if (arg == "-c") { mode = "line"; if (i >= args.Length - 1) { return(error("Expected code argument after `-c`.")); } lines.Add(args[++i]); } else if (arg == "--") { if (i < args.Length - 1) { filename = args[++i]; } i++; break; } else if (arg.StartsWith("-")) { return(error("Unknown option `" + arg + "`.")); } else { filename = arg; break; } } for (int i = lastArgs + 1; i < args.Length; i++) { UnusedArgs.Add(args[i]); } if (mode == "repl" || (mode == "run" && filename == null)) { return(repl(filename, builtinsExtensionFile)); } if (mode == "ws") { return(WebSocketEndpoint.WSServe()); } if (filename == null && lines.Count == 0) { return(error("Required filename argument missing.")); } if (!File.Exists(filename) && lines.Count == 0) { return(error("File `" + filename + "` does not exist.")); } var interp = new Interpreter(); if (filename != null) { interp.AddModuleRoot( Path.GetDirectoryName(Path.GetFullPath(filename))); } interp.AddModuleRoot(Path.GetFullPath(".")); interp.FailedImportHook = promptInstallModule; interp.LoadPrelude(); if (builtinsExtensionFile != null) { interp.LoadExtensionFile(builtinsExtensionFile); } else { interp.LoadExtensionFile(); } if (runLines(interp, lines) != 0) { return(1); } if (filename == null) { return(0); } using (StreamReader reader = File.OpenText(filename)) { Parser parser = new Parser( Path.GetFileNameWithoutExtension(filename), reader.ReadToEnd()); try { //Console.WriteLine("========== PARSING =========="); module = parser.Parse(); if (mode == "parse-tree") { module.DebugPrint(System.Console.Out, ""); return(0); } if (mode == "pretty-print") { Console.Write( ParseNodeMeta.PrettyPrintModule( interp, (ObjectParseNode)module, prettyOption == "semicolons")); return(0); } //Console.WriteLine("========== TRANSLATING =========="); ExecutionTreeTranslator ett = new ExecutionTreeTranslator(); Node eModule = ett.Translate(module as ObjectParseNode); if (mode == "execution-tree") { eModule.DebugPrint(Console.Out, ""); return(0); } if (mode == "no-run") { return(0); } interp.EnterModule( Path.GetFileNameWithoutExtension(filename)); try { eModule.Evaluate(interp); } catch (GraceExceptionPacketException e) { System.Console.Error.WriteLine("Uncaught exception:"); ErrorReporting.WriteException(e.ExceptionPacket); if (e.ExceptionPacket.StackTrace != null) { foreach (var l in e.ExceptionPacket.StackTrace) { System.Console.Error.WriteLine(" from " + l); } } return(1); } } catch (StaticErrorException e) { if (verbose) { System.Console.WriteLine(e.StackTrace); } if (errorCodeTarget != null) { File.WriteAllText(errorCodeTarget, e.Code); } ErrorReporting.WriteAllRecorded(); return(1); } catch (Exception e) { System.Console.Error.WriteLine( "An internal error occurred. " + "Debugging information follows."); System.Console.Error.WriteLine("Runtime version: " + Interpreter.GetRuntimeVersion()); System.Console.Error.WriteLine(e); System.Console.Error.WriteLine(e.StackTrace); var gepe = e as GraceExceptionPacketException; if (gepe != null) { System.Console.Error.WriteLine("\nThe error was a native Grace exception, whose information follows:"); var gep = gepe.ExceptionPacket; System.Console.Error.WriteLine(gep.Description); foreach (var l in gep.StackTrace) { System.Console.Error.WriteLine(" " + l); } } System.Console.Error.WriteLine( "\nAn internal error occurred. " + "This is a bug in the implementation."); return(1); } } return(0); }