public virtual IType Evaluate(IType[] args) { if (args.Length == fparams.Length || (elipsis && args.Length >= fparams.Length - 1)) { if (memoize && memos.TryGetValue(GetArgListHashCode(args), out IType v)) { return(v); } var newScopeVars = new Dictionary <string, IType>(); IType[] extra = new IType[args.Length - fparams.Length + 1]; for (int i = 0; i < args.Length; i++) { //if (args[i] is Union un) //{ // return un.Apply(x => Evaluate(args[0..i].Concat(new IType[] { x }).Concat(args[(i + 1)..]).ToArray())); //} if (args[i] is Error) { return(args[i]); } if (elipsis && i >= fparams.Length - 1) { extra[i - fparams.Length + 1] = args[i]; } else { newScopeVars[fparams[i]] = args[i]; } } if (elipsis) { newScopeVars[fparams[fparams.Length - 1]] = new UnevaluatedTuple(extra); } newScopeVars["self"] = this; var ret = expression; var newScope = new Scope(scope, newScopeVars); if (ret is IUnevaluated u) { ret = new BakedExpression(u, newScope); } if (memoize) { return(new CallbackWrapper(ret, x => memos[GetArgListHashCode(args)] = x)); } return(ret); } return(new Error("BadArguments", $"The function {this} can't fit {args.Length} arguments.")); }
public virtual IType Evaluate(IType[] args) { if (args.Length == fparams.Length || (elipsis && args.Length >= fparams.Length - 1)) { if (memoize && memos.TryGetValue(GetArgListHashCode(args), out IType v)) { return(v); } Dictionary <string, IType> lookup = new Dictionary <string, IType>(); IType[] extra = new IType[args.Length - fparams.Length + 1]; for (int i = 0; i < args.Length; i++) { if (args[i] is Union un) { IType[] results = new IType[un.values.Length]; for (int j = 0; j < results.Length; j++) { IType[] newArgs = new IType[args.Length]; for (int k = 0; k < newArgs.Length; k++) { if (i == k) { newArgs[k] = un.values[j]; } else { newArgs[k] = args[k]; } } results[j] = Evaluate(newArgs); } return(new Union(results).Evaluate(lookup)); } if (args[i] is Error) { return(args[i]); } if (elipsis && i >= fparams.Length - 1) { extra[i - fparams.Length + 1] = args[i]; } else { lookup[fparams[i]] = args[i]; } } if (elipsis) { lookup[fparams[fparams.Length - 1]] = new UnevaluatedTuple(extra); } lookup["self"] = this; var ret = expression; if (ret is IUnevaluated u) { ret = new BakedExpression(u, lookup); } if (memoize) { return(new CallbackWrapper(ret, x => memos[GetArgListHashCode(args)] = x)); } return(ret); } return(new Error("BadArguments", $"The function {this} can't fit {args.Length} arguments.")); }