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; }
public override object Evaluate(Frame environment) { return environment.Evaluate(Body); }