예제 #1
0
 internal Combination(Expression oprt)
 {
     if (oprt == null)
     {
         throw new ArgumentException("Operator cannot be null");
     }
     _oprt = oprt;
 }
예제 #2
0
        private object ApplyProc(Expression expression,String name, Procedure proc, bool checkTailCall)
        {
            //Console.WriteLine(expression);
            //Console.WriteLine(name);
            //this.EvaluatedProcedure = proc;

            List<Expression> operands = expression.GetRest();
            if (proc is Identity && operands.Count > 0)
            {
                throw new Exception(String.Format("The object {0} is not applicable.",proc.Evaluate(this)));
            }
            if (operands.Count < proc.MinParameterCount)
            {
                throw new Exception("Insufficient arguments for procedure.");
            }
            if (!proc.HasVariableParameter && operands.Count > proc.Parameters.Count)
            {
                throw new Exception(String.Format("Procedure expects {0} arguments but {1} were supplied.",proc.Parameters.Count,operands.Count));
            }
            IDictionary<String, Procedure> bindings = new Dictionary<string, Procedure>();
            for (int i = 0; i < proc.Parameters.Count; i++)
            {
                Frame operandEnv = new Frame(new Dictionary<string, Procedure>(0), this, null, new Identity(this, null),false, "operand");
                if (proc.Parameters[i] == ".")
                {
                    RestParameters restParameters = new RestParameters();
                    int j = i;
                    while (operands.Count - j >= proc.Parameters.Count - i)
                    {
                        restParameters.Add(operandEnv.Evaluate(operands[j]));
                        j++;
                    }
                    if (restParameters.Values.Count > 0)
                    {
                        bindings.Add(".", new Identity(this, restParameters));
                    }
                    continue;
                }
                object result = operandEnv.Evaluate(operands[i]);
                if (result is Procedure)
                {
                    bindings.Add(proc.Parameters[i], (Procedure)result);
                }
                else if (result is Continuation)
                {
                    throw new Exception("");
                }
                else
                {
                    //Console.WriteLine(proc.Parameters[i] + " - " + result);
                    bindings.Add(proc.Parameters[i], new Identity(this, result));
                }
            }

            Frame env = new Frame(bindings, proc.DefinitionEnvironment, this,proc,name);
            object o;
            if (proc.Body != null && proc.Body.Count > 0)
            {
                o = env.Evaluate(proc.Body);
            }
            else
            {
                o = proc.Evaluate(env);
            }
            return o;
        }
예제 #3
0
        internal object Evaluate(Expression expression,bool checkTailCall)
        {
            EvaluatedExpression = expression;

            callCount++;

            if (expression == null)
            {
                throw new Exception("Invalid expression.");
            }

            if (expression.IsLiteral)
            {
                callCount--;
                return expression;
            }

            object oprt = Evaluate(expression.GetFirst());
            String procName = oprt.ToString();
            Procedure proc = null;
            if (oprt != null && oprt is Procedure)
            {
                proc = (Procedure)oprt;
            }
            else
            {
                proc = FindProcedure(procName);
            }

            if (proc == null)
            {
                ISpecialForm specialForm = FindSpecialForm(procName);
                if (specialForm == null)
                {
                    throw new Exception("No such binding found.");
                }
                else
                {
                    object o = specialForm.Evaluate(this, expression);
                    callCount--;
                    return o;
                }
            }

            if (proc.Parameters.Count > 0 && !(expression is Combination))
            {
                callCount--;
                return proc;
            }

            if (checkTailCall)
            {
                Frame tailCallFrame = FindCallingTailCallFrame(proc, procName);
                if (tailCallFrame != null)
                {
                    List<IDictionary<string, Procedure>> bindings = new List<IDictionary<string, Procedure>>();
                    Frame current = this;
                    while (current != null && current.ParentFrame != null)
                    {
                        if (current != tailCallFrame)
                        {
                            if (current._bindings.Count > 0)
                            {
                                bindings.Add(current._bindings);
                            }
                        }
                        else
                        {
                            break;
                        }
                        current = current.ParentFrame;
                    }
                    bindings.Reverse();
                    foreach (IDictionary<string, Procedure> binding in bindings)
                    {
                        tailCallFrame.ReplaceBindings(binding);
                    }

                    return new Continuation(expression, tailCallFrame);
                }
            }

            if (proc is Identity)
            {
                callCount--;
                return proc.Evaluate(null);
            }
            else
            {
                object o = ApplyProc(expression, procName, proc, checkTailCall);
                callCount--;
                return o;
            }
        }
예제 #4
0
 internal object Evaluate(Expression expression)
 {
     return Evaluate(expression,false);
 }
예제 #5
0
 internal Continuation(Expression call, Frame environment)
 {
     TailCall = call;
     this.Environment = environment;
 }
예제 #6
0
 internal void AddOperand(Expression operand)
 {
     _operands.Add(operand);
 }
예제 #7
0
 public object Evaluate(Expression expression)
 {
     return _running.Evaluate(expression);
 }