Пример #1
0
        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));
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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. ===");
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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);
        }