internal Frame(IDictionary<String, Procedure> bindings, Frame parent, Frame callingFrame, Procedure proc, bool isSpecialForm, string name) { _bindings = bindings; if (_bindings == null) { _bindings = new Dictionary<String, Procedure>(); } ParentFrame = parent; CallingFrame = callingFrame; EvaluatedProcedure = proc; EvaluatedProcedureName = name; IsSpecialForm = isSpecialForm; Name = name; frameCount++; }
private Frame CreateGlobalFrame() { Dictionary<String, Procedure> globalBindings = new Dictionary<string, Procedure>(); Frame global = new Frame(globalBindings, null, null, new Identity(null, "0"), null); //TODO replace this with an eval proc global.AddBinding("+", new Add(global)); global.AddBinding("*", new Multiply(global)); global.AddBinding("-", new Subtract(global)); global.AddBinding("/", new Divide(global)); global.AddBinding(">", new GreaterThan(global)); global.AddBinding("<", new LessThan(global)); global.AddBinding(">=", new GreaterOrEqualThan(global)); global.AddBinding("<=", new LessOrEqualThan(global)); global.AddBinding("=>", new GreaterOrEqualThan(global)); global.AddBinding("=<", new LessOrEqualThan(global)); global.AddBinding("=", new Equals(global)); global.AddBinding("not", new Not(global)); global.AddBinding("remainder", new Remainder(global)); global.AddBinding("random", new SInterpreter.Native.Random(global)); global.AddBinding("true", new SInterpreter.Native.Boolean(global, true)); global.AddBinding("false", new SInterpreter.Native.Boolean(global, false)); global.AddBinding("display", new Display(global)); global.AddBinding("runtime", new Runtime(global)); global.AddBinding("newline", new Newline(global)); global.AddBinding("#t", new SInterpreter.Native.Boolean(global, true)); global.AddBinding("#f", new SInterpreter.Native.Boolean(global, false)); global.AddBinding("sin", new Sine(global)); global.AddBinding("cos", new Cosine(global)); global.AddBinding("log", new Logarithm(global)); global.AddBinding("expt", new Power(global)); global.AddBinding("floor", new Floor(global)); global.AddBinding("load", new Load(global)); global.AddBinding("cons", new Cons(global)); global.AddBinding("car", new Car(global)); global.AddBinding("cdr", new Cdr(global)); global.AddBinding("gcd", new GCD(global)); global.AddBinding("min", new Min(global)); global.AddBinding("max", new Max(global)); global.AddBinding("error", new Error(global)); global.AddBinding("list", new ListCreate(global)); global.AddBinding("null?", new NullCheck(global)); return global; }
internal Frame(IDictionary<String, Procedure> bindings, Frame parent, Frame callingFrame, Procedure proc,string name) : this(bindings,parent,callingFrame,proc,false,name) { }
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 Continuation(Expression call, Frame environment) { TailCall = call; this.Environment = environment; }
public override object Evaluate(Frame environment) { return environment.Evaluate(Body); }
internal Lambda(Frame defEnv, List<string> parameters, List<Expression> body) : base(defEnv, parameters, body) { }
public override object Evaluate(Frame frame) { return _value; }
internal Identity(Frame defEnv, object value) : base(defEnv, new List<String>(), new List<Expression>(1)) { this._value = value; }
public Interpreter() { _global = CreateGlobalFrame(); _running = new Frame(null, _global, null, null, null); }
public abstract object Evaluate(Frame environment);
internal Procedure(Frame definitionEnv, List<String> parameters, List<Expression> body) { Parameters = parameters; Body = body; DefinitionEnvironment = definitionEnv; }
internal Procedure(Frame environment) { Parameters = new List<string>(); }