/// <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); }
/// <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); }
/// <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); }
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))); }
/// <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])); }
/// <inheritdoc/> public override GraceObject Respond(EvaluationContext ctx, GraceObject self, MethodRequest req) { MethodHelper.CheckArity(ctx, req, 0); return(method((T)self)); }
/// <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)); }
/// <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); }
/// <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); }
/// <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 })); }
/// <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); }
private GraceRequestBlock(EvaluationContext ctx, GraceObject receiver, MethodRequest req) { AddMethod("apply", new DelegateMethodReq(new NativeMethodReq(this.Apply))); this.receiver = receiver; this.request = req; }
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)); }
/// <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); }
/// <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)); }
private GraceObject mIfFalse(EvaluationContext ctx, GraceObject b) { if (!Success) { return(b.Request(ctx, MethodRequest.Nullary("apply"))); } return(GraceObject.Done); }
private static GraceObject mMatch( EvaluationContext ctx, GraceString self, GraceObject target) { return((mEqualsEquals(self, target) == GraceBoolean.True) ? Matching.SuccessfulMatch(ctx, target) : Matching.FailedMatch(ctx, target)); }
public WithBlock(List <GraceObject> elements, GraceObject block) { _elements = elements; _block = block; AddMethod("apply(_)", new DelegateMethod1Ctx( new NativeMethod1Ctx(this.apply))); }
/// <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 mLessEqual( GraceNumber self, GraceObject other ) { var oth = other.FindNativeParent <GraceNumber>(); return(GraceBoolean.Create(self.Value <= oth.Value)); }
/// <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))); }
/// <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)); }
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)); }
/// <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); }
/// <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)); }
private static GraceObject mNotEquals( GraceString self, GraceObject other ) { var oth = other.FindNativeParent <GraceString>(); return((oth == null) ? GraceBoolean.True : GraceBoolean.Create(self.nfc != oth.nfc)); }
/// <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"; }
/// <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); }
/// <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)); }
/// <inheritdoc/> public override GraceObject Respond( EvaluationContext ctx, GraceObject self, MethodRequest req ) { checkAccessibility(ctx, req); cell.Value = req[1].Arguments[0]; return(GraceObject.Done); }
/// <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)); }