public override LispNode Evaluate(Env env) { LispNode func = null; LambdaNode lambdaNode = null; func = What.Evaluate(env); if (!(func is LambdaNode)) { return(null); } lambdaNode = func as LambdaNode; if (lambdaNode.Arguments.Count != Arguments.Count) { return(null); } Env newEnv = new Env(lambdaNode.Env); // use the lambda env, not the global env, for lexical closures for (int i = 0; i < Arguments.Count; i++) { newEnv.Add(lambdaNode.Arguments[i], Arguments[i].Evaluate(env)); } return(lambdaNode.Call(newEnv)); }
public override LispNode Call(Env env) { LispNode lispArg1 = env.Find("__argument1"); if (!(lispArg1 is BoolNode)) { return(null); } bool arg1 = (lispArg1 as BoolNode).Value; return(new BoolNode(Function(arg1))); }
public override LispNode Evaluate(Env env) { if (env.Find(VariableName) == null) { return(null); } LispNode exp = Expression.Evaluate(env); env.Set(VariableName, exp); return(exp); // probably not ideomatic scheme but we can chain set!s. }
public override LispNode Call(Env env) { LispNode lispArg1 = env.Find("__argument1"); LispNode lispArg2 = env.Find("__argument2"); if (!(lispArg1 is IntNode || lispArg2 is IntNode)) { return(null); } int arg1 = (lispArg1 as IntNode).Value; int arg2 = (lispArg2 as IntNode).Value; return(new BoolNode(Function(arg1, arg2))); }
public object Execute(String exp) { LispNode program = Read(TokenizeStream(exp)); Env env = CreateGlobals(); LispNode result = program.Evaluate(env); if (result is IntNode) { return((result as IntNode).Value); } else if (result is BoolNode) { return((result as BoolNode).Value); } else if (result is QuoteNode) { return((result as QuoteNode).Value); } else { return(null); } }
static LispNode Read(List <String> tokens) { if (tokens.Count() == 0) { return(null); } String token = tokens[0]; tokens.RemoveAt(0); if (token == "(") { token = tokens[0]; if (token == "if") { tokens.RemoveAt(0); IfNode ifNode = new IfNode(); ifNode.a = Read(tokens); ifNode.b = Read(tokens); ifNode.c = Read(tokens); if (tokens[0] != ")") { return(null); } else { tokens.RemoveAt(0); // eat close paren return(ifNode); } } else if (token == "quote") { tokens.RemoveAt(0); StringBuilder builder = new StringBuilder(); while (tokens[0] != ")") { builder.Append(tokens[0]); tokens.RemoveAt(0); } QuoteNode quoteNode = new QuoteNode(builder.ToString()); tokens.RemoveAt(0); return(quoteNode); } else if (token == "define") { tokens.RemoveAt(0); String name = tokens[0]; tokens.RemoveAt(0); LispNode expression = Read(tokens); DefineNode defNode = new DefineNode(name, expression); if (tokens[0] != ")") { return(null); } else { tokens.RemoveAt(0); // eat close paren return(defNode); } } else if (token == "begin") { tokens.RemoveAt(0); BeginNode beginNode = new BeginNode(); do { beginNode.Expressions.Add(Read(tokens)); } while (tokens[0] != ")"); tokens.RemoveAt(0); // eat close paren return(beginNode); } else if (token == "lambda") { tokens.RemoveAt(0); LambdaNode lambdaNode = new LambdaNode(); if (tokens[0] != "(") { return(null); } tokens.RemoveAt(0); while (tokens[0] != ")") { lambdaNode.Arguments.Add(tokens[0]); tokens.RemoveAt(0); } tokens.RemoveAt(0); lambdaNode.Body = Read(tokens); tokens.RemoveAt(0); return(lambdaNode); } else if (token == "set!") { tokens.RemoveAt(0); SetNode setNode = new SetNode(); setNode.VariableName = tokens[0]; tokens.RemoveAt(0); setNode.Expression = Read(tokens); return(setNode); } else //if(token == "call") { CallNode callNode = new CallNode(); callNode.What = Read(tokens); while (tokens[0] != ")") { callNode.Arguments.Add(Read(tokens)); } tokens.RemoveAt(0); return(callNode); } //return null; } else if (token == ")") { return(null); } else { return(ParseAtom(token)); } }
public void Set(String varName, LispNode lispNode) { Variables[varName] = lispNode; }
public void Add(String varName, LispNode lispNode) { Variables.Add(varName, lispNode); }
public DefineNode(String name, LispNode expression) { Name = name; Expression = expression; }