示例#1
0
        public GTTree(IEnumerable<Value> list)
            : this()
        {
            var v = new GTTree();

            foreach (Value ex in list)
                v = (GTTree)v.Add(ex);

            // fake mutator
            this.Value = v.Value;
            this.Left = v.Left;
            this.Right = v.Right;
        }
示例#2
0
        public Value Evaluate(Scope scope)
        {
            // Evaluate the function
            Value v = Function.Evaluate(scope);
            Value ret = new GTTree();
            int c = v.Count;

            foreach (var res in v.Enumerate())
            {
                var r = res.Self();

                if (r.Type != GTType.Function)
                    if (c == 1)
                        throw new InvalidOperationException("Cannot call non-function type");
                    else
                        continue;

                GTFunction f = (GTFunction)res;

                // Check the parameter count
                if (Parameters.Count > f.Parameters.Count)
                    if (c == 1)
                        throw new InvalidOperationException("Too many arguments in call to function: " + Function.ToString());
                    else
                        continue;

                // Create evaluation context
                Scope s = new Scope(f.Container);

                // Add this() for recursion
                s.Add("this", f);

                for (int i = 0; i < Parameters.Count; i++)
                    s.Add(f.Parameters[i], Parameters[i].Evaluate(scope));

                // All parameters filled
                if (Parameters.Count == f.Parameters.Count)
                {
                    Value o;

                    if (f.Body == null)
                    {
                        // Invoke the method
                        var w = (WrapperFunc)f;
                        o = (Value)w.Method.Invoke(null, (from par in w.Parameters
                                                          select new Usage(par).Evaluate(s)).ToArray());
                    }
                    else
                        o = f.Body.Evaluate(s);

                    ret = ret.Add(o);
                    continue;
                }

                // No partial application in list context
                if (c > 1)
                    continue;

                // Partial application: Create a new function
                var newparams = new List<string>();

                for (int i = f.Parameters.Count - Parameters.Count; i < f.Parameters.Count; i++)
                    newparams.Add(f.Parameters[i]);

                return new GTFunction(f.Body, s, newparams);
            }

            if (ret.Count == 1)
                return ret[0]; // single values -> skip the list stuff
            else
                return ret;
        }