예제 #1
0
 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."));
 }
예제 #2
0
 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."));
 }