Beispiel #1
0
        //syntax: if <test> <consequent> <alternate>
        //syntax: if <test> <consequent>

        public override Node eval(Node exp, Environment env)
        {
            var length = Node.length(exp);

            if (length < 3 || length > 4)
            {
                Console.Error.WriteLine("Error: Invalid length for if expression");
                return(Nil.getInstance());
            }
            var test       = exp.getCdr().getCar();
            var consequent = exp.getCdr().getCdr().getCar();

            var alternate = new Node();

            if (length == 4) //has alternates
            {
                alternate = exp.getCdr().getCdr().getCdr().getCar();
            }
            else //If <test> yields a false value and no <alternate> is specified, then the result of the expression is unspecified.
            {
                alternate = Unspecific.getInstance();
            }

            if (test.eval(env) != BoolLit.getInstance(false))
            {
                return(consequent.eval(env));
            }
            return(alternate.eval(env));
        }
Beispiel #2
0
        private Node apply0()
        {
            string name = symbol.getName();

            if (name.Equals("read"))
            {
                var parser = new Parser(new Scanner(Console.In), new TreeBuilder());
                var exp    = (Node)parser.parseExp();
                if (exp != null)
                {
                    return(exp);
                }
                return(new Ident("end-of-file"));
            }
            if (name.Equals("newline"))
            {
                Console.WriteLine();
                return(Unspecific.getInstance());
            }
            if (name.Equals("interaction-environment"))
            {
                return(Scheme4101.env);
            }
            Console.Error.WriteLine("Error: wrong number of arguments");
            return(Nil.getInstance());
        }
Beispiel #3
0
        private Node apply2(Node arg1, Node arg2)
        {
            string name = symbol.getName();

            if (name.Equals("eq?"))
            {
                if (arg1.isSymbol() && arg2.isSymbol())
                {
                    return(BoolLit.getInstance(arg1.getName().Equals(arg2.getName())));
                }
                return(BoolLit.getInstance(arg1 == arg2));
            }
            if (name.Equals("cons"))
            {
                return(new Cons(arg1, arg2));
            }
            if (name.Equals("set-car!"))
            {
                arg1.setCar(arg2);
                return(Unspecific.getInstance());
            }
            if (name.Equals("set-cdr!"))
            {
                arg1.setCdr(arg2);
                return(Unspecific.getInstance());
            }
            if (name.Equals("eval"))
            {
                if (arg2.isEnvironment())
                {
                    Environment envArg1 = (Environment)arg1;
                    return(arg1.eval(envArg1));
                }
                Console.Error.WriteLine("Error: argument is not an environment");
                return(Nil.getInstance());
            }
            if (name.Equals("apply"))
            {
                return(arg1.apply(arg2));
            }
            if (name[0].Equals('b') && name.Length == 2)
            {
                if (arg1.isNumber() && arg2.isNumber())
                {
                    return(evalArithmetic(arg1.getIntVal(), arg2.getIntVal()));
                }
                Console.Error.WriteLine("Error: invalid arguments");
                return(Nil.getInstance());
            }
            Console.Error.WriteLine("Error: wrong number of arguments");
            return(Nil.getInstance());
        }
Beispiel #4
0
        private Node evalClauses(Node exp, Environment env)
        {
            if (exp.isNull())
            {
                return(Unspecific.getInstance());
            }
            var clause = exp.getCar();

            if (Node.length(clause) <= 0)
            {
                Console.Error.WriteLine("Error: invalid cond expression");
                return(Nil.getInstance());
            }

            var testExp    = clause.getCar();
            var expression = clause.getCdr();

            if (testExp.isSymbol() && testExp.getName().Equals("else"))
            {
                if (!expression.isNull() && exp.getCdr().isNull())
                {
                    return(evalExp(expression, env));
                }
                Console.Error.WriteLine("Error: invalid expression");
                return((Node)Nil.getInstance());
            }
            var testValid = testExp.eval(env);

            if (testValid == BoolLit.getInstance(false))
            {
                var nextExps = exp.getCdr();
                return(evalClauses(nextExps, env));
            }
            if (expression.isNull())
            {
                return(BoolLit.getInstance(true));
            }
            var exp1 = expression.getCar();

            if (!exp1.isSymbol() || !exp1.getName().Equals("=>"))
            {
                return(evalExp(expression, env));
            }
            if (Node.length(expression) != 2)
            {
                Console.Error.WriteLine("Error: invalid cond expression");
                return(Nil.getInstance());
            }
            var cdr = expression.getCdr().getCar();

            return(cdr.eval(env).apply(BoolLit.getInstance(true)));
        }
Beispiel #5
0
        public override Node eval(Node exp, Environment env)
        {
            if (Node.length(exp) != 3)
            {
                Console.Error.WriteLine("Error: invalid set expression");
                return((Node)Nil.getInstance());
            }
            Node var    = exp.getCdr().getCar();
            Node varExp = exp.getCdr().getCdr().getCar();

            env.assign(var, varExp.eval(env));
            return(Unspecific.getInstance());
        }
Beispiel #6
0
        private Node apply1(Node arg1)
        {
            string name = symbol.getName();

            if (name.Equals("car"))
            {
                return(arg1.getCar());
            }
            if (name.Equals("cdr"))
            {
                return(arg1.getCdr());
            }
            if (name.Equals("number?"))
            {
                return(BoolLit.getInstance(arg1.isNumber()));
            }
            if (name.Equals("symbol?"))
            {
                return(BoolLit.getInstance(arg1.isSymbol()));
            }
            if (name.Equals("null?"))
            {
                return(BoolLit.getInstance(arg1.isNull()));
            }
            if (name.Equals("pair?"))
            {
                return(BoolLit.getInstance(arg1.isPair()));
            }
            if (name.Equals("procedure?"))
            {
                return(BoolLit.getInstance(arg1.isProcedure()));
            }
            if (name.Equals("write"))
            {
                arg1.print(-1);
                return(Unspecific.getInstance());
            }
            if (name.Equals("display"))
            {
                Console.Write(arg1);
                return(Unspecific.getInstance());
            }
            Console.Error.WriteLine("Error: wrong number of arguments");
            return(Nil.getInstance());
        }