Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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));
            }
        }