예제 #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));
        }
예제 #2
0
        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)));
        }
예제 #3
0
        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.
        }
예제 #4
0
        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)));
        }
예제 #5
0
        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);
            }
        }
예제 #6
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));
            }
        }
예제 #7
0
 public void Set(String varName, LispNode lispNode)
 {
     Variables[varName] = lispNode;
 }
예제 #8
0
 public void Add(String varName, LispNode lispNode)
 {
     Variables.Add(varName, lispNode);
 }
예제 #9
0
 public DefineNode(String name, LispNode expression)
 {
     Name       = name;
     Expression = expression;
 }