private static bool conditionMet( string condition, Dictionary <string, string> data, Interpreter interpreter ) { var p = (ObjectParseNode) new Parser(condition).Parse(); var e = new ExecutionTreeTranslator(); var t = p.Body[0].Visit(e); var b = t.Evaluate(interpreter); return(GraceBoolean.IsTrue(interpreter, b)); }
private GraceObject mTranslateFile(GraceObject code) { GraceString gs = code.FindNativeParent <GraceString>(); string path = gs.Value; using (StreamReader reader = File.OpenText(path)) { var p = new Parser(reader.ReadToEnd()); var module = p.Parse(); ExecutionTreeTranslator ett = new ExecutionTreeTranslator(); Node eModule = ett.Translate(module as ObjectParseNode); return(eModule); } }
private void runButton_Click(object sender, EventArgs e) { OutputSink sink = new TextboxSink(outputText); outputText.Text = ""; var interp = new Interpreter(sink); interp.LoadPrelude(); try { var p = new Parser(codeText.Text); var module = p.Parse(); var ett = new ExecutionTreeTranslator(); var eModule = ett.Translate(module as ObjectParseNode); try { eModule.Evaluate(interp); } catch (GraceExceptionPacketException gep) { sink.WriteLine("Uncaught exception:"); ErrorReporting.WriteException(gep.ExceptionPacket); if (gep.ExceptionPacket.StackTrace != null) { foreach (var l in gep.ExceptionPacket.StackTrace) { sink.WriteLine(" from " + l); } } } catch (Exception ex) { sink.WriteLine("=== A run-time error occurred: " + ex.Message + " ==="); } } catch (StaticErrorException) { sink.WriteLine("=== A static error prevented the program from running. ==="); } catch (Exception) { sink.WriteLine("=== An internal error occurred. ==="); } }
private static IList <Editor.Completion> completion( GraceObject obj, string line) { var ret = new List <Editor.Completion>(); var lparenIndex = line.LastIndexOf("("); var commaIndex = line.LastIndexOf(","); var lbraceIndex = line.LastIndexOf("["); var spaceIndex = line.LastIndexOf(" "); var dotIndex = line.LastIndexOf("."); var last = Math.Max(Math.Max(Math.Max(lparenIndex, commaIndex), Math.Max(lbraceIndex, dotIndex)), spaceIndex); if (last == -1) { // Nothing to look at foreach (var k in obj.DotMethods) { if (k == "asString") { continue; } if (k.StartsWith(line)) { var append = k; var space = k.IndexOf(' '); if (space != -1) { append = k.Substring(0, space); } append = append.Substring(line.Length); ret.Add(Editor.CreateCompletion(append, k, "")); } } } else if (commaIndex == last || lbraceIndex == last || lparenIndex == last || spaceIndex == last) { // If we found one of these, ignore everything leading // up to it and make base completions for the rest. ret.AddRange(completion(obj, line.Substring(last + 1).Trim())); } else { // We end with a dot. Check for a preceding // bracket, comma, or space, and perform the // same truncation as above if applicable. var untilDot = dotIndex >= 0 ? line.Substring(0, dotIndex) : ""; var rbraceIndex = untilDot.LastIndexOf(']'); var commaIndex2 = untilDot.LastIndexOf(','); var spaceIndex2 = untilDot.LastIndexOf(' '); var rparenIndex = untilDot.LastIndexOf(')'); var m = Math.Max(Math.Max(rbraceIndex, spaceIndex2), Math.Max(commaIndex2, rparenIndex)); if (m != -1 && (m == commaIndex2 || m == spaceIndex2)) { // Rudimentary quote check - if we find one of these // with an odd number of quotation marks before it, // we retry from before the quote. if (countChars(untilDot.Substring(0, m), '"') % 2 == 1) { // Assume it's inside a quote var qIndex = untilDot.LastIndexOf('"', m); rparenIndex = untilDot.LastIndexOf(")", qIndex); commaIndex2 = untilDot.LastIndexOf(",", qIndex); rbraceIndex = untilDot.LastIndexOf("]", qIndex); spaceIndex2 = untilDot.LastIndexOf(" ", qIndex); m = Math.Max(Math.Max(rbraceIndex, spaceIndex2), Math.Max(commaIndex2, rparenIndex)); } // Update untilDot to include only the now-relevant // part of the line. if (m != -1 && (m == commaIndex2 || m == spaceIndex2)) { untilDot = untilDot.Substring(m + 1); } else if (m < lbraceIndex || m < lparenIndex) { untilDot = untilDot.Substring( Math.Max(lbraceIndex, lparenIndex) + 1); } } else if (m < lbraceIndex || m < lparenIndex) { // Start after a still-open bracket. untilDot = untilDot.Substring( Math.Max(lbraceIndex, lparenIndex) + 1); } // We will speculatively parse and execute the code, // and then examine the actual object that comes of // it. The code may have side effects, which will be // visible; it would be better to detect such code, // but the information is not presently available. if (untilDot != "") { ErrorReporting.SuppressAllErrors = true; try { var p = new Parser("tab completion", untilDot); var module = p.Parse(); var trans = new ExecutionTreeTranslator(); var mod = (ObjectConstructorNode) trans.Translate((ObjectParseNode)module); if (mod.Body.Count > 0) { var element = mod.Body[0]; var interp = new Interpreter(); interp.Extend(obj); var o = element.Evaluate(interp); // Re-run completion with the rest of the // string and the obtained object. ret.AddRange(completion(o, line.Substring(dotIndex + 1))); } } catch (Exception) { // Eat everything silently - the code isn't meant // to be running, so we don't want to report any // errors. } finally { ErrorReporting.SuppressAllErrors = false; } } } return(ret); }
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); }
/// <summary> /// REPL-execute a given line in an interpreter, /// indicating whether it was incomplete, and /// restoring the interpreter afterwards. /// </summary> /// <param name="interp"> /// Interpreter to use /// </param> /// <param name="obj"> /// Module object where method declarations will be added. /// </param> /// <param name="memo"> /// Restoration point for the interpreter context. /// </param> /// <param name="line"> /// Line of code to execute. /// </param> /// <param name="unfinished"> /// Set to true if this line was incomplete and could not /// be executed for that reason. /// </param> /// <param name="result"> /// Result of the executed expression. /// </param> public static int RunLine(Interpreter interp, UserObject obj, Interpreter.ScopeMemo memo, string line, out bool unfinished, out GraceObject result) { result = null; ParseNode module; ObjectConstructorNode mod = null; var isExtensionTrait = false; try { var p = new Parser("source code", line); module = p.Parse(); var opm = (ObjectParseNode)module; if (opm.Body.Count == 1) { // Tricky hack to let extensions be defined interactively. var trait = opm.Body[0] as TraitDeclarationParseNode; isExtensionTrait = (trait != null && trait.Signature.Name.EndsWith("Extension")); } var trans = new ExecutionTreeTranslator(); mod = (ObjectConstructorNode)trans.Translate(opm); } catch (StaticErrorException ex) { if (ex.Code == "P1001") { // "Unexpected end of file" is expected in the // repl for unfinished statements. unfinished = true; return(1); } else { // All other errors are errors. unfinished = false; return(1); } } unfinished = false; if (mod != null) { try { // The "module" object can only really have // a single element, but we don't know whether // it's a method, statement, or expression yet. foreach (var meth in mod.Methods.Values) { obj.AddMethod(meth.Name, new Method(meth, memo)); } foreach (var node in mod.Body) { var inherits = node as InheritsNode; if (inherits != null) { var ms = inherits.Inherit(interp, obj); obj.AddMethods(ms); obj.RunInitialisers(interp); } var v = node as VarDeclarationNode; var d = node as DefDeclarationNode; Cell cell; var meths = new Dictionary <string, Method>(); if (v != null) { obj.CreateVar(v.Name, meths, v.Readable, v.Writable, out cell); obj.AddMethods(meths); if (v.Value != null) { cell.Value = v.Value.Evaluate(interp); } result = GraceObject.Done; continue; } if (d != null) { obj.CreateDef(d.Name, meths, d.Public, out cell); obj.AddMethods(meths); cell.Value = d.Value.Evaluate(interp); result = GraceObject.Done; continue; } var ret = node.Evaluate(interp); if (ret != null && ret != GraceObject.Done && ret != GraceObject.Uninitialised) { interp.Print(interp, ret); } result = ret; } if (isExtensionTrait) { interp.LoadExtensionsFromObject(obj); } } catch (GraceExceptionPacketException e) { ErrorReporting.WriteLine("Uncaught exception:"); ErrorReporting.WriteException(e.ExceptionPacket); if (e.ExceptionPacket.StackTrace != null) { foreach (var l in e.ExceptionPacket.StackTrace) { ErrorReporting.WriteLine(" from " + l); } } return(1); } finally { // No matter what happened, restore the interpreter // to as pristine a state as we can manage before // the next time. interp.RestoreExactly(memo); interp.PopCallStackTo(0); mod = null; } } return(0); }
private static int runModule(string code, string modname, string mode, WSOutputSink sink) { var interp = new Interpreter(sink); ErrorReporting.SetSink(new OutputSinkWrapper(Console.Error)); interp.RPCSink = sink; interp.AddModuleRoot(Path.GetFullPath(".")); interp.FailedImportHook = loadCachedModule; interp.LoadPrelude(); Parser parser = new Parser(modname, code); ParseNode module; try { module = parser.Parse(); ExecutionTreeTranslator ett = new ExecutionTreeTranslator(); Node eModule = ett.Translate(module as ObjectParseNode); sink.SendEvent("build-succeeded", modname); if (mode == "build") { return(0); } interp.EnterModule(modname); try { eModule.Evaluate(interp); } catch (GraceExceptionPacketException ex) { sink.SendRuntimeError(ex.ExceptionPacket.Description, ex.ExceptionPacket.StackTrace); } } catch (StaticErrorException ex) { sink.SendStaticError(ex.Code, ex.Module, ex.Line, ex.Message); } catch (ThreadAbortException) { throw; } catch (WebSocketClosedException) { return(0); } catch (Exception ex) { System.Console.Error.WriteLine( "An internal error occurred. " + "Debugging information follows."); System.Console.Error.WriteLine("Runtime version: " + Interpreter.GetRuntimeVersion()); System.Console.Error.WriteLine(ex); System.Console.Error.WriteLine(ex.StackTrace); System.Console.Error.WriteLine( "\nAn internal error occurred. " + "This is a bug in the implementation."); } sink.SendEvent("execution-complete", modname); return(0); }