/// <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> /// List of particular items. /// </summary> /// <param name="items">Enumerable of items to use</param> public static GraceVariadicList Of(IEnumerable <GraceObject> items) { var ret = new GraceVariadicList(); foreach (var it in items) { ret.Add(it); } return(ret); }