Example #1
0
        /// <summary>The built-in Grace "print" method</summary>
        public GraceObject Print(EvaluationContext ctx, GraceObject arg)
        {
            Object obj = arg;
            var    gop = arg as GraceObjectProxy;

            if (gop != null)
            {
                obj = gop.Object;
            }
            var go = obj as GraceObject;

            if (go != null)
            {
                var req  = new MethodRequest();
                var part = RequestPart.Nullary("asString");
                req.AddPart(part);
                if (go.RespondsTo(req))
                {
                    obj = go.Request(ctx, req);
                }
            }
            GraceString gs = null;

            go = obj as GraceObject;
            if (go != null)
            {
                gs = go.FindNativeParent <GraceString>();
            }
            if (gs != null)
            {
                obj = gs.Value.Replace("\u2028", Environment.NewLine);
            }
            sink.WriteLine("" + obj);
            return(GraceObject.Done);
        }
Example #2
0
        /// <inheritdoc />
        public Method AddMinorDef(string name, GraceObject val)
        {
            var m = scope.scope as LocalScope;

            if (m == null)
            {
                var s = scope.next;
                while (s != null)
                {
                    if (s.minor)
                    {
                        m = s.scope as LocalScope;
                    }
                    if (m != null)
                    {
                        break;
                    }
                    s = s.next;
                }
                if (m == null)
                {
                    return(null);
                }
            }
            return(m.AddLocalDef(name, val));
        }
Example #3
0
        private GraceObject mYieldFor(EvaluationContext ctx, GraceObject arg)
        {
            var n = arg.FindNativeParent <GraceNumber>();

            if (n == null)
            {
                return(GraceObject.Done);
            }
            var         sw = System.Diagnostics.Stopwatch.StartNew();
            GraceObject block;

            object[] args;
            var      ms = (int)(n.Double);

            while (sw.ElapsedMilliseconds < ms)
            {
                var delay = (int)(ms - sw.ElapsedMilliseconds);
                if (delay < 0)
                {
                    delay = 0;
                }
                if (sink.AwaitRemoteCallback(delay, out block, out args))
                {
                    processCallback(ctx, block, args);
                }
            }
            return(GraceObject.Done);
        }
Example #4
0
        /// <inheritdoc />
        public GraceObject FindReceiver(MethodRequest req, int skipRedirects)
        {
            ScopeLink   sl      = scope;
            GraceObject capture = null;

            while (sl != null && sl.scope != null)
            {
                if (skipRedirects > 0 &&
                    sl.scope.HasFlag(GraceObject.Flags.ObjectConstructor))
                {
                    sl = sl.next;
                    skipRedirects--;
                    continue;
                }
                if (sl.scope.RespondsTo(req))
                {
                    return(capture ?? sl.scope);
                }
                capture = null;
                var ls = sl.scope as LocalScope;
                if (ls != null)
                {
                    if (ls.RedirectSurrounding != null)
                    {
                        capture = ls.RedirectSurrounding;
                    }
                }
                sl = sl.next;
            }
            return(null);
        }
Example #5
0
        private static GraceObject objectFromElement(XElement root)
        {
            GraceObject obj      = GraceObject.Done;
            var         stringEl = root.XPathSelectElement("//string");

            if (stringEl != null)
            {
                obj = GraceString.Create(stringEl.Value);
            }
            var numberEl = root.XPathSelectElement("//number");

            if (numberEl != null)
            {
                double d;
                if (double.TryParse(numberEl.Value, out d))
                {
                    obj = GraceNumber.Create(d);
                }
            }
            var objectEl = root.XPathSelectElement("//object");

            if (objectEl != null)
            {
                int objKey;
                if (int.TryParse(objectEl.Value, out objKey))
                {
                    obj = new GraceForeignObject(objKey);
                }
            }
            return(obj);
        }
Example #6
0
 /// <param name="next">Next element in the list, or null</param>
 /// <param name="scope">Grace object to be used as a scope</param>
 /// <param name="minor">True if this link represents a "minor"
 /// scope that is used for internal names</param>
 public ScopeLink(ScopeLink next, GraceObject scope,
                  bool minor)
 {
     this.next  = next;
     this.scope = scope;
     this.minor = minor;
 }
Example #7
0
        private GraceObject mAlloc(GraceObject arg)
        {
            var num = arg.FindNativeParent <GraceNumber>();
            var i   = (int)num.Double;

            return(new FixedSizeArray(i));
        }
Example #8
0
        /// <summary>
        /// Load extensions to builtins from traits in an
        /// existing object.
        /// </summary>
        /// <param name="ext">Object containing extension traits.</param>
        public void LoadExtensionsFromObject(GraceObject ext)
        {
            var req = MethodRequest.Nullary("ObjectExtension");

            req.IsInherits = true;
            if (ext.RespondsTo(req))
            {
                var uo = new UserObject();
                req.InheritingObject = uo;
                ext.Request(this, req);
                GraceObject.ExtendDefaultMethods(req.InheritedMethods);
            }
            req            = MethodRequest.Nullary("NumberExtension");
            req.IsInherits = true;
            if (ext.RespondsTo(req))
            {
                var uo = new UserObject();
                req.InheritingObject = uo;
                ext.Request(this, req);
                GraceNumber.ExtendWith(req.InheritedMethods);
            }
            req            = MethodRequest.Nullary("StringExtension");
            req.IsInherits = true;
            if (ext.RespondsTo(req))
            {
                var uo = new UserObject();
                req.InheritingObject = uo;
                ext.Request(this, req);
                GraceString.ExtendWith(req.InheritedMethods);
            }
        }
Example #9
0
        /// <summary>Finds the standard prelude file, loads and
        /// interprets it, and places the created module in scope</summary>
        public void LoadPrelude()
        {
            if (loadedPrelude)
            {
                return;
            }
            if (JSIL && loadedPreludeObject != null)
            {
                Extend(loadedPreludeObject);
                return;
            }
            string dir         = Path.GetDirectoryName(typeof(Interpreter).Assembly.Location);
            string preludePath = Path.Combine(dir, "prelude.grace");

            using (StreamReader preludeReader = File.OpenText(preludePath))
            {
                var parser = new Parser("prelude", preludeReader.ReadToEnd());
                var pt     = parser.Parse() as ObjectParseNode;
                var eMod   = new ExecutionTreeTranslator().Translate(pt);
                prelude = eMod.Evaluate(this);
                Extend(prelude);
                loadedPrelude       = true;
                loadedPreludeObject = prelude;
                Interpreter.Debug("========== END PRELUDE ==========");
            }
        }
Example #10
0
        /// <summary>Performs set-up behaviour shared by multiple
        /// constructors</summary>
        private void initialise()
        {
            var s = new LocalScope();

            scope.scope = s;
            majorScope  = s;
            s.AddMethod("print(_)",
                        new DelegateMethod1Ctx(Print));
            s.AddLocalDef("true", GraceBoolean.True);
            s.AddLocalDef("false", GraceBoolean.False);
            s.AddMethod("_base_while_do(_,_)",
                        new DelegateMethodReq(BaseWhileDo));
            s.AddMethod("_base_try_catch_finally(_,_)",
                        new DelegateMethodReq(BaseTryCatchFinally));
            s.AddMethod("_base_try_catch_finally(_,_,_)",
                        new DelegateMethodReq(BaseTryCatchFinally));
            s.AddMethod("_base_try_catch_finally(_,_,_,_)",
                        new DelegateMethodReq(BaseTryCatchFinally));
            s.AddMethod("_base_try_catch_finally(_,_,_,_,_)",
                        new DelegateMethodReq(BaseTryCatchFinally));
            s.AddMethod("_base_try_catch_finally(_,_,_,_,_,_)",
                        new DelegateMethodReq(BaseTryCatchFinally));
            s.AddMethod("_base_try_catch_finally(_,_,_,_,_,_,_)",
                        new DelegateMethodReq(BaseTryCatchFinally));
            s.AddMethod("Exception",
                        new ConstantMethod(
                            new GraceExceptionKind("Exception")));
        }
Example #11
0
        private GraceObject mParse(GraceObject code)
        {
            GraceString gs = code.FindNativeParent <GraceString>();
            string      s  = gs.Value;
            var         p  = new Parser(s);

            return(new GraceObjectProxy(p.Parse()));
        }
Example #12
0
        /// <inheritdoc />
        public Method AddDef(string name, GraceObject val)
        {
            var m = majorScope as LocalScope;

            if (m == null)
            {
                return(null);
            }
            return(m.AddLocalDef(name, val));
        }
Example #13
0
        /// <summary>Set the majorScope field to the closest non-minor
        /// scope</summary>
        private void restoreMajor()
        {
            ScopeLink s = scope;

            while (s.minor)
            {
                s = s.next;
            }
            majorScope = s.scope;
        }
Example #14
0
        private GraceObject mSleep(GraceObject arg)
        {
            var n = arg.FindNativeParent <GraceNumber>();

            if (n == null)
            {
                return(GraceObject.Done);
            }
            Thread.Sleep((int)(n.Double));
            return(GraceObject.Done);
        }
Example #15
0
        private GraceObject mParseFile(GraceObject code)
        {
            GraceString gs   = code.FindNativeParent <GraceString>();
            string      path = gs.Value;

            using (StreamReader reader = File.OpenText(path))
            {
                var p = new Parser(reader.ReadToEnd());
                return(new GraceObjectProxy(p.Parse()));
            }
        }
Example #16
0
        /// <inheritdoc />
        public ReaderWriterPair AddVar(string name, GraceObject val)
        {
            var m = majorScope as LocalScope;

            if (m == null)
            {
                return(new ReaderWriterPair());
            }
            var pair = m.AddLocalVar(name, val);

            return(pair);
        }
Example #17
0
        /// <summary>Native version of the built-in Grace "while-do" method
        /// </summary>
        /// <remarks>This while-do is more efficient than is possible to
        /// implement in bare Grace without it.</remarks>
        public static GraceObject BaseWhileDo(EvaluationContext ctx,
                                              MethodRequest req)
        {
            GraceObject   cond  = req[0].Arguments[0];
            GraceObject   block = req[0].Arguments[1];
            MethodRequest apply = MethodRequest.Nullary("apply");

            while (cond.Request(ctx, apply) == GraceBoolean.True)
            {
                block.Request(ctx, apply);
            }
            return(GraceObject.Done);
        }
Example #18
0
        /// <summary>Native method for Grace match</summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="target">Target of the match</param>
        private GraceObject mMatch(EvaluationContext ctx, GraceObject target)
        {
            var gop = target as GraceObjectProxy;

            if (gop == null)
            {
                return(Matching.FailedMatch(ctx, target));
            }
            if (gop.Object is T)
            {
                return(Matching.SuccessfulMatch(ctx, target));
            }
            return(Matching.FailedMatch(ctx, target));
        }
Example #19
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);
            }
        }
Example #20
0
        /// <inheritdoc />
        public void InsertOuter(GraceObject obj)
        {
            var s = scope;

            while (s != null)
            {
                if (s.scope.HasFlag(GraceObject.Flags.ObjectConstructor))
                {
                    break;
                }
                s = s.next;
            }
            var newScope = new ScopeLink(s.next, obj);

            s.next = newScope;
        }
Example #21
0
        /// <inheritdoc/>
        public bool AwaitRemoteCallback(int time,
                                        out GraceObject block,
                                        out object[] args)
        {
            Callback c;

            if (!callbacks.TryTake(out c, time))
            {
                block = null;
                args  = new object[0];
                return(false);
            }
            block = c.block;
            args  = c.args;
            return(true);
        }
Example #22
0
        private static void processResponse(XElement root)
        {
            var keyEl = root.XPathSelectElement("//key");

            if (keyEl == null)
            {
                return;
            }
            int key;

            int.TryParse(keyEl.Value, out key);
            GraceObject obj = objectFromElement(root);

            responses[key] = obj;
            eventWaitHandlers[key].Set();
        }
Example #23
0
        private GraceObject mAt(EvaluationContext ctx, GraceObject index)
        {
            var num = index.FindNativeParent <GraceNumber>();
            var i   = (int)num.Double;

            checkIndex(ctx, i, data);
            var ret = data[i];

            if (ret == null)
            {
                ErrorReporting.RaiseError(ctx, "R2008",
                                          new Dictionary <string, string> {
                    { "name", "index " + i },
                    { "receiver", ToString() }
                },
                                          "UninitialisedReadError: Cannot read from index " + i
                                          );
            }
            return(ret);
        }
Example #24
0
        private void processCallback(EvaluationContext ctx,
                                     GraceObject block, object[] args)
        {
            var lArgs = new List <GraceObject>();

            foreach (var arg in args)
            {
                var gfo = arg as GraceForeignObject;
                if (gfo != null)
                {
                    lArgs.Add(new DomObject((int)gfo.IdentifyingData, sink));
                }
                else
                {
                    lArgs.Add((GraceObject)arg);
                }
            }
            var req = MethodRequest.WithArgs("apply", lArgs);

            block.Request(ctx, req);
        }
Example #25
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);
        }
Example #26
0
 /// <inheritdoc />
 public void ExtendMinor(GraceObject o)
 {
     scope = new ScopeLink(scope, o, true);
 }
Example #27
0
 /// <inheritdoc />
 public void Unextend(GraceObject o)
 {
     scope = scope.next;
     restoreMajor();
 }
Example #28
0
        public override GraceObject Request(EvaluationContext ctx,
                                            MethodRequest req, GraceObject receiver)
        {
            var part     = req[0];
            var isAssign = false;

            if (req.Count > 1)
            {
                if (req[1].Name == ":=(_)")
                {
                    part     = req[1];
                    isAssign = true;
                }
            }
            object[] args = new object[part.Arguments.Count];
            int      i    = 0;

            foreach (var a in part.Arguments)
            {
                var d = a as DomObject;
                var s = a as GraceString;
                if (d != null)
                {
                    args[i++] = new int[1] {
                        d.key
                    }
                }
                ;
                else if (s != null)
                {
                    args[i++] = s.Value;
                }
                else
                {
                    args[i++] = a;
                }
            }
            // Request names include arities, which
            // the DOM doesn't understand.
            var name = req.Name;
            var idx  = name.IndexOf('(');

            if (idx != -1)
            {
                name = name.Substring(0, idx);
            }
            if (isAssign)
            {
                return(sink.SendRPCNoResult(key, name, args));
            }
            if (ignoredMethodResults != null)
            {
                if (ignoredMethodResults.Contains(name))
                {
                    return(sink.SendRPCNoResult(key, name, args));
                }
            }
            var ret = sink.SendRPC(key, name, args);
            var gfo = ret as GraceForeignObject;

            if (gfo == null)
            {
                return(ret);
            }
            int okey = (int)gfo.IdentifyingData;

            return(new DomObject(okey, sink));
        }
Example #29
0
File: REPL.cs Project: smarr/kernan
        /// <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);
        }
Example #30
0
 public Callback(GraceObject _block, object[] _args)
 {
     block = _block;
     args  = _args;
 }