Пример #1
0
        /// <summary>
        /// Determine whether a Grace object is truthy or not.
        /// </summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="val">Grace object to test for truthiness</param>
        /// <remarks>
        /// If the value is the true or false boolean literal, this
        /// method returns the appropriate value immediately. If it is
        /// an object conforming to the boolean type, this method requests
        /// ifTrue ifFalse on the object with suitable blocks and returns
        /// the result. If it is neither, an error will be reported.
        /// </remarks>
        public static bool IsTrue(EvaluationContext ctx, GraceObject val)
        {
            if (val == True)
            {
                return(true);
            }
            if (val == False)
            {
                return(false);
            }
            var req = new MethodRequest();

            req.AddPart(new RequestPart("ifTrue",
                                        new List <GraceObject> {
                _trueBlock
            },
                                        RequestPart.EmptyList
                                        )
                        );
            req.AddPart(new RequestPart("ifFalse",
                                        new List <GraceObject> {
                _falseBlock
            },
                                        RequestPart.EmptyList
                                        )
                        );
            return(val.Request(ctx, req) == True);
        }
Пример #2
0
        /// <summary>Create a method request with a single part and
        /// a lone ordinary argument</summary>
        /// <param name="name">Name of method</param>
        /// <param name="arg">Value of lone argument</param>
        public static MethodRequest Single(string name, GraceObject arg)
        {
            var ret = new MethodRequest();

            ret.AddPart(RequestPart.Single(name, arg));
            return(ret);
        }
Пример #3
0
        /// <inheritdoc/>
        public override GraceObject Respond(
            EvaluationContext ctx,
            GraceObject self,
            MethodRequest req
            )
        {
            checkAccessibility(ctx, req);
            var arg = req[1].Arguments[0];

            if (Type != null)
            {
                if (Matching.TryMatch(ctx, Type, arg, out GraceObject result))
                {
                    arg = result;
                }
                else
                {
                    ErrorReporting.RaiseError(ctx, "R2025",
                                              new Dictionary <string, string> {
                        { "field", req[0].Name },
                        { "required", GraceString.AsNativeString(ctx, Type) }
                    },
                                              "TypeError: ${field} can only hold ${required}.");
                }
            }

            var tmp = cell.Value;

            cell.Value = arg;
            return(tmp);
        }
Пример #4
0
        private static GraceObject mAt(
            EvaluationContext ctx,
            GraceString self,
            GraceObject other
            )
        {
            var oth = other.FindNativeParent <GraceNumber>();

            if (oth == null)
            {
                return(GraceString.Create("bad index"));
            }
            int idx = oth.GetInt() - 1;

            if (idx >= self.graphemeIndices.Length || idx < 0)
            {
                ErrorReporting.RaiseError(ctx, "R2013",
                                          new Dictionary <string, string> {
                    { "index", "" + (idx + 1) },
                    { "valid", self.graphemeIndices.Length > 0 ?
                      "1 .. " + self.graphemeIndices.Length
                                : "none (empty)" }
                }, "Index must be a number");
            }
            int start = self.graphemeIndices[idx];

            return(GraceString.Create(
                       StringInfo.GetNextTextElement(self.Value, start)));
        }
Пример #5
0
 /// <inheritdoc/>
 public override GraceObject Respond(EvaluationContext ctx,
                                     GraceObject self,
                                     MethodRequest req)
 {
     MethodHelper.CheckArity(ctx, req, 1);
     return(method(ctx, (T)self, req[0].Arguments[0]));
 }
Пример #6
0
 /// <inheritdoc/>
 public override GraceObject Respond(EvaluationContext ctx,
                                     GraceObject self,
                                     MethodRequest req)
 {
     MethodHelper.CheckArity(ctx, req, 0);
     return(method((T)self));
 }
Пример #7
0
 /// <summary>Native method implementing the .match Grace method
 /// for types</summary>
 /// <remarks>At present, this matching uses only the method
 /// names in both the object and the type.</remarks>
 public GraceObject Match(EvaluationContext ctx, GraceObject target)
 {
     if (requests == null)
     {
         var l = new List <MethodRequest>();
         foreach (var m in methods)
         {
             var req = new MethodRequest();
             foreach (var p in m)
             {
                 var rp = RequestPart.Nullary(p.Name);
                 req.AddPart(rp);
             }
             l.Add(req);
         }
         requests = l;
     }
     foreach (var req in requests)
     {
         if (!target.RespondsTo(req))
         {
             return(Matching.FailedMatch(ctx, target));
         }
     }
     return(Matching.SuccessfulMatch(ctx, target));
 }
Пример #8
0
        /// <summary>Native method for Grace ||</summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="other">Argument to the method</param>
        public GraceObject OrOr(EvaluationContext ctx, GraceObject other)
        {
            GraceBoolean oth = other as GraceBoolean;

            if (oth != null)
            {
                return(GraceBoolean.Create(this.Boolean || oth.Boolean));
            }
            GraceObjectProxy op = other as GraceObjectProxy;

            if (op != null)
            {
                return(GraceBoolean.Create(this.Boolean || (dynamic)op.Object));
            }
            ErrorReporting.RaiseError(ctx, "R2001",
                                      new Dictionary <string, string>()
            {
                { "method", "||" },
                { "index", "1" },
                { "part", "||" },
                { "required", "Boolean" }
            },
                                      "ArgumentTypeError: || requires a Boolean argument"
                                      );
            return(GraceBoolean.False);
        }
Пример #9
0
        /// <summary>Native method representing the apply method</summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="req">Request that obtained this method</param>
        public GraceObject Apply(EvaluationContext ctx, MethodRequest req)
        {
            GraceObject ret = GraceObject.Done;

            MethodNode.CheckArgCount(ctx, "apply", "apply",
                                     parameters.Count, Variadic,
                                     req[0].Arguments.Count);
            ctx.Remember(lexicalScope);
            var myScope = new LocalScope(req.Name);

            // Bind any local methods (types) on the scope
            foreach (var localMeth in body.OfType <MethodNode>())
            {
                myScope.AddMethod(localMeth.Name, new Method(localMeth,
                                                             lexicalScope));
            }
            // Bind parameters and arguments
            foreach (var arg in parameters.Zip(req[0].Arguments, (a, b) => new { name = a, val = b }))
            {
                var id = arg.name as ParameterNode;
                if (id != null && id.Variadic)
                {
                    // Populate variadic parameter with all remaining
                    // arguments.
                    var gvl = new GraceVariadicList();
                    for (var i = parameters.Count - 1;
                         i < req[0].Arguments.Count;
                         i++)
                    {
                        gvl.Add(req[0].Arguments[i]);
                    }
                    myScope.AddLocalDef(id.Name, gvl);
                }
                else
                {
                    string name = ((IdentifierNode)arg.name).Name;
                    myScope.AddLocalDef(name, arg.val);
                }
            }
            if (Variadic && parameters.Count > req[0].Arguments.Count)
            {
                // Empty variadic parameter.
                var param  = parameters.Last();
                var idNode = param as ParameterNode;
                if (idNode != null && idNode.Variadic)
                {
                    var gvl = new GraceVariadicList();
                    myScope.AddLocalDef(idNode.Name, gvl);
                }
            }
            ctx.Extend(myScope);
            foreach (Node n in body)
            {
                ret = n.Evaluate(ctx);
            }
            ctx.Unextend(myScope);
            ctx.Forget(lexicalScope);
            return(ret);
        }
Пример #10
0
 /// <summary>Create a new part with a single argument</summary>
 /// <param name="name">Name of this part</param>
 /// <param name="arg">Value of the lone argument</param>
 internal static RequestPart Single(string name, GraceObject arg)
 {
     return(new RequestPart(name, EmptyList,
                            new List <GraceObject>()
     {
         arg
     }));
 }
Пример #11
0
            /// <summary>Native method for Grace do</summary>
            /// <param name="ctx">Current interpreter</param>
            /// <param name="block">Block to apply for each element</param>
            public GraceObject Do(EvaluationContext ctx, GraceObject block)
            {
                var req = MethodRequest.Single("do", block);

                left.Request(ctx, req);
                right.Request(ctx, req);
                return(GraceObject.Done);
            }
Пример #12
0
 private GraceRequestBlock(EvaluationContext ctx, GraceObject receiver,
                           MethodRequest req)
 {
     AddMethod("apply",
               new DelegateMethodReq(new NativeMethodReq(this.Apply)));
     this.receiver = receiver;
     this.request  = req;
 }
Пример #13
0
 private GraceObject mMatch(EvaluationContext ctx, GraceObject target)
 {
     if (Matching.TryMatch(ctx, lhs, target, out _))
     {
         return(new MatchResult(true, target));
     }
     return(new MatchResult(Matching.TryMatch(ctx, rhs, target, out _), target));
 }
Пример #14
0
        /// <summary>
        /// Add method to this object representing a def
        /// declaration
        /// </summary>
        /// <param name="name">Name of the def to add</param>
        /// <param name="val">Value of this def</param>
        /// <returns>Added method</returns>
        public virtual Method AddLocalDef(string name, GraceObject val)
        {
            var c    = new Cell(val);
            var read = new FieldReaderMethod(c);

            AddMethod(name, read);
            return(read);
        }
Пример #15
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)
 {
     if (predicate(target))
     {
         return(Matching.SuccessfulMatch(ctx, target));
     }
     return(Matching.FailedMatch(ctx, target));
 }
Пример #16
0
 private GraceObject mIfFalse(EvaluationContext ctx, GraceObject b)
 {
     if (!Success)
     {
         return(b.Request(ctx, MethodRequest.Nullary("apply")));
     }
     return(GraceObject.Done);
 }
Пример #17
0
 private static GraceObject mMatch(
     EvaluationContext ctx,
     GraceString self,
     GraceObject target)
 {
     return((mEqualsEquals(self, target) == GraceBoolean.True)
         ? Matching.SuccessfulMatch(ctx, target)
         : Matching.FailedMatch(ctx, target));
 }
Пример #18
0
 public WithBlock(List <GraceObject> elements,
                  GraceObject block)
 {
     _elements = elements;
     _block    = block;
     AddMethod("apply(_)",
               new DelegateMethod1Ctx(
                   new NativeMethod1Ctx(this.apply)));
 }
Пример #19
0
        /// <summary>Native method for Grace &lt;=</summary>
        /// <param name="self">Receiver of the method</param>
        /// <param name="other">Argument to the method</param>
        private static GraceObject mLessEqual(
            GraceNumber self,
            GraceObject other
            )
        {
            var oth = other.FindNativeParent <GraceNumber>();

            return(GraceBoolean.Create(self.Value <= oth.Value));
        }
Пример #20
0
        /// <summary>Native method for Grace ^</summary>
        /// <param name="self">Receiver of the method</param>
        /// <param name="other">Argument to the method</param>
        private static GraceObject mExponentiate(
            GraceNumber self,
            GraceObject other
            )
        {
            var oth = other.FindNativeParent <GraceNumber>();

            return(GraceNumber.Create(self.Value.Exponentiate(oth.Value)));
        }
Пример #21
0
        /// <summary>Native method for Grace -</summary>
        /// <param name="self">Receiver of the method</param>
        /// <param name="other">Argument to the method</param>
        private static GraceObject mSubtract(
            GraceNumber self,
            GraceObject other
            )
        {
            var oth = other.FindNativeParent <GraceNumber>();

            return(GraceNumber.Create(self.Value - oth.Value));
        }
Пример #22
0
 public OrPattern(GraceObject l, GraceObject r)
 {
     lhs = l;
     rhs = r;
     AddMethod("match(_)", new DelegateMethod1Ctx(mMatch));
     AddMethod("|(_)", Matching.OrMethod);
     AddMethod("&(_)", Matching.AndMethod);
     AddMethod("asString", new DelegateMethod0Ctx(mAsString));
 }
Пример #23
0
        /// <inheritdoc/>
        /// <remarks>This method uses the indexer on the LocalScope
        /// object the method was requested on.</remarks>
        public override GraceObject Respond(EvaluationContext ctx, GraceObject self, MethodRequest req)
        {
            checkAccessibility(ctx, req);
            LocalScope s    = self as LocalScope;
            string     name = req[0].Name;

            s[name] = req[1].Arguments[0];
            return(GraceObject.Done);
        }
Пример #24
0
        /// <summary>Create a failed match</summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="obj">Result value</param>
        public static GraceObject FailedMatch(EvaluationContext ctx,
                                              GraceObject obj)
        {
            var successfulMatchReq = MethodRequest.Single("_FailedMatch",
                                                          obj);
            GraceObject smRec = ctx.FindReceiver(successfulMatchReq);

            return(smRec.Request(ctx, successfulMatchReq));
        }
Пример #25
0
        private static GraceObject mNotEquals(
            GraceString self,
            GraceObject other
            )
        {
            var oth = other.FindNativeParent <GraceString>();

            return((oth == null) ? GraceBoolean.True
                                 : GraceBoolean.Create(self.nfc != oth.nfc));
        }
Пример #26
0
 /// <param name="l">First iterable</param>
 /// <param name="r">Second iterable</param>
 public Concatenated(GraceObject l, GraceObject r)
 {
     left  = l;
     right = r;
     AddMethod("do(_)",
               new DelegateMethod1Ctx(
                   new NativeMethod1Ctx(this.Do)));
     AddMethod("++(_)", Iterables.ConcatMethod);
     TagName = "ConcatenatedIterables";
 }
Пример #27
0
        /// <summary>
        /// Execute a block of native code for each element
        /// of an iterable.
        /// </summary>
        /// <param name="ctx">Interpreter to use</param>
        /// <param name="iterable">Iterable to loop over</param>
        /// <param name="block">
        /// Block of code to execute.
        /// </param>
        public static void ForEach(
            EvaluationContext ctx,
            GraceObject iterable,
            GraceObject block
            )
        {
            var req = MethodRequest.Single("do", block);

            iterable.Request(ctx, req);
        }
Пример #28
0
        /// <summary>Native method for Grace match</summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="target">Target of the match</param>
        public GraceObject Match(EvaluationContext ctx, GraceObject target)
        {
            var b = target as GraceBoolean;

            if (b != null && b.Boolean == Boolean)
            {
                return(Matching.SuccessfulMatch(ctx, target));
            }
            return(Matching.FailedMatch(ctx, target));
        }
Пример #29
0
 /// <inheritdoc/>
 public override GraceObject Respond(
     EvaluationContext ctx,
     GraceObject self,
     MethodRequest req
     )
 {
     checkAccessibility(ctx, req);
     cell.Value = req[1].Arguments[0];
     return(GraceObject.Done);
 }
Пример #30
0
        /// <summary>Native method for Grace refine</summary>
        /// <param name="ctx">Current interpreter</param>
        /// <param name="name">Name of the sub-exception</param>
        public GraceObject Refine(EvaluationContext ctx, GraceObject name)
        {
            var asGraceString = name.Request(ctx,
                                             MethodRequest.Nullary("asString"))
                                .FindNativeParent <GraceString>();
            var nameStr = asGraceString.Value;

            AddDescendant(nameStr);
            return(new GraceExceptionKind(this, nameStr));
        }