internal Combination(Expression oprt) { if (oprt == null) { throw new ArgumentException("Operator cannot be null"); } _oprt = oprt; }
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; }
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; } }
internal object Evaluate(Expression expression) { return Evaluate(expression,false); }
internal Continuation(Expression call, Frame environment) { TailCall = call; this.Environment = environment; }
internal void AddOperand(Expression operand) { _operands.Add(operand); }
public object Evaluate(Expression expression) { return _running.Evaluate(expression); }