Ejemplo n.º 1
0
        // TODO: The method apply() should be defined in class Node
        // to report an error.  It should be overridden only in classes
        // BuiltIn and Closure.
        public override Node apply(Node args)
        {
            Node result  = null;
            int  numArgs = numArguments(args);

            switch (symbol.getName())
            {
            case "begin":
                // The value(s) of the last expression is(are) returned
                while (args.getCdr().isNull() == false)
                {
                    args = args.getCdr();
                }
                return(args.getCar());

            case "cond":
                // The value(s) of the last expression is(are) returned
                while (args.getCdr().isNull() == false)
                {
                    args = args.getCdr();
                }
                return(args.getCar());

            case "if":
                if (args.getCar() == BoolLit.getInstance(true))
                {
                    return(args.getCdr().getCar());
                }
                else if (args.getCdr().getCdr().isPair())
                {
                    return(args.getCdr().getCdr().getCar());
                }
                else
                {
                    return(new StringLit("#unspecified"));
                }

            case "let":
                // The value(s) of the last expression is(are) returned
                while (args.getCdr().isNull() == false)
                {
                    args = args.getCdr();
                }
                return(args.getCar());

            case "quote":
                return(args.getCdr().getCar());

            case "read":
                return((Node)args.parser.parseExp());

            case "write":
                args.print(0);
                // Not sure what Node to return here. Probably just return the blank Node
                break;

            case "symbol?":
                // symbol? only accepts 1 argument
                if (numArgs != 1)
                {
                    return(new StringLit("Error: wrong number of arguments for 'symbol?'"));
                }
                else
                {
                    if (args.getCar().isSymbol())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }

            case "number?":
                // number? only accepts 1 argument
                if (numArgs != 1)
                {
                    return(new StringLit("Error: wrong number of arguments for 'number?'"));
                }
                else
                {
                    if (args.getCar().isNumber())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }

            case "car":
                if (args.isPair() == false)
                {
                    return(new StringLit("Error: Argument to 'car' is not a pair."));
                }
                else
                {
                    return(args.getCar());
                }

            case "cdr":
                if (args.isPair() == false)
                {
                    return(new StringLit("Error: Argument to 'cdr' is not a pair."));
                }
                else
                {
                    return(args.getCdr());
                }

            case "cons":
                // make sure only two arguments are provided
                if (args.getCdr().isPair() != true && args.getCdr().getCdr().isNull() == false)
                {
                    return(new StringLit("Error: Function 'cons' requires two arguments."));
                }
                else
                {
                    return(args);
                }

            case "set-car!":
                // make sure only a list and value are provided
                if (args.getCar().isPair() == false || args.getCdr().getCar().isPair() == true || args.getCdr().getCdr().isNull() == false)
                {
                    return(new StringLit("Error: Function 'set-car!' requires a list and value"));
                }
                else
                {
                    args.getCar().setCar(args.getCdr().getCar());
                    return(new StringLit("no values returned;"));
                }

            case "set-cdr!":
                // make sure only a list and value are provided
                if (args.getCar().isPair() == false || args.getCdr().getCar().isPair() == true || args.getCdr().getCdr().isNull() == false)
                {
                    return(new StringLit("Error: Function 'set-cdr!' requires a list and value"));
                }
                else
                {
                    args.getCar().setCdr(args.getCdr().getCar());
                    return(new StringLit("no values returned;"));
                }

            case "null?":
                if (args.getCar().isNull() == true)
                {
                    return(BoolLit.getInstance(true));
                }
                // null? only accepts one argument
                else if (args.getCdr().isPair() == true)
                {
                    return(new StringLit("Error: 'null?' only accept one argument."));
                }
                else
                {
                    return(BoolLit.getInstance(false));
                }

            case "pair?":
                // pair? only accept one argument
                if (args.getCdr().isPair() == true)
                {
                    return(new StringLit("Error: 'pair?' only accepts one argument."));
                }
                else if (args.getCar().isPair())
                {
                    return(BoolLit.getInstance(true));
                }
                else
                {
                    return(BoolLit.getInstance(false));
                }

            case "eq?":
                // eq? only accepts two arguments
                if (args.getCdr().getCdr().isNull() == false)
                {
                    return(new StringLit("Error: 'eq?' only accepts one argument"));
                }
                else if (args.getCar() == args.getCdr().getCar())     // Not sure if this is going to work, actually
                {
                    return(BoolLit.getInstance(true));
                }
                else
                {
                    return(BoolLit.getInstance(false));
                }

            case "procedure?":
                //procedure only accepts 1 argument (I think)
                if (args.getCdr().isNull() == false)
                {
                    return(new StringLit("Error: 'procedure?' only accepts one argument"));
                }
                else if (args.getCar().isProcedure() == true)
                {
                    return(BoolLit.getInstance(true));
                }
                else
                {
                    return(BoolLit.getInstance(false));
                }

            default:
                break;
            }

            // Now we check for the binary arithmetic builtins
            IntLit num1 = new IntLit(0), num2;

            if (symbol.getName() == "b/") // The division function has 1 as the default value instead of 0 when only 1 argument is provided
            {
                num1 = new IntLit(1);
            }

            // If the arguments aren't numerical, the IntLit casts will fail and the catch block executes.
            // If there are 0 arguments the first cast will fail, and if there are more than 2 an Exception is thrown
            try
            {
                num2 = (IntLit)args.getCar();
                // Check for a second argument
                if (args.getCdr().isPair() == true)
                {
                    // We do this swap because if we have only 1 argument, we're doing 0 - num2. If we have 2, we're doing num1-num2.
                    num1 = num2;
                    num2 = (IntLit)args.getCdr().getCar();
                    if (args.getCdr().getCdr().isNull() == false)
                    {
                        throw new Exception();
                    }
                }
                else if (symbol.getName() == "b=" || symbol.getName() == "b<")
                {
                    return(result = new StringLit("Error: binary arithmetic operation '" + symbol.getName() + "' expects two numerical 2 arguments."));
                }
            }
            catch
            {
                return(result = new StringLit("Error: binary arithmetic operations expect 1 or 2 numerical arguments."));
            }

            if (symbol.getName() == "b+")
            {
                result = new IntLit(num1.getInt() + num2.getInt());
            }
            else if (symbol.getName() == "b-")
            {
                result = new IntLit(num1.getInt() - num2.getInt());
            }
            else if (symbol.getName() == "b*")
            {
                result = new IntLit(num1.getInt() * num2.getInt());
            }
            else if (symbol.getName() == "b/")
            {
                if (num2.getInt() == 0)
                {
                    return(result = new StringLit("Error: Dividing by 0."));
                }
                result = new IntLit(num1.getInt() / num2.getInt());
            }
            else if (symbol.getName() == "b=")
            {
                if (num1.getInt() == num2.getInt())
                {
                    result = BoolLit.getInstance(true);
                }
                else
                {
                    result = BoolLit.getInstance(false);
                }
            }
            else if (symbol.getName() == "b<")
            {
                if (num1.getInt() < num2.getInt())
                {
                    result = BoolLit.getInstance(true);
                }
                else
                {
                    result = BoolLit.getInstance(false);
                }
            }

            return(result);
        }
Ejemplo n.º 2
0
    public static int Main(string[] args)
    {
        // Create scanner that reads from standard input
        Scanner scanner = new Scanner(Console.In);

        if (args.Length > 1 ||
            (args.Length == 1 && ! args[0].Equals("-d")))
        {
            Console.Error.WriteLine("Usage: mono SPP [-d]");
            return 1;
        }

        // If command line option -d is provided, debug the scanner.
        if (args.Length == 1 && args[0].Equals("-d"))
        {
            // Console.Write("Scheme 4101> ");
            Token tok = scanner.getNextToken();
            while (tok != null)
            {
                TokenType tt = tok.getType();

                Console.Write(tt);
                if (tt == TokenType.INT)
                    Console.WriteLine(", intVal = " + tok.getIntVal());
                else if (tt == TokenType.STRING)
                    Console.WriteLine(", stringVal = " + tok.getStringVal());
                else if (tt == TokenType.IDENT)
                    Console.WriteLine(", name = " + tok.getName());
                else
                    Console.WriteLine();

                // Console.Write("Scheme 4101> ");
                tok = scanner.getNextToken();
            }
            return 0;
        }

        // Create parser
        TreeBuilder builder = new TreeBuilder();
        Parser parser = new Parser(scanner, builder);
        Node root = new Node();

        // TODO: Create and populate the built-in environment and
        // create the top-level environment
        Tree.Environment env = new Tree.Environment();
        Ident id = new Ident("b+");
        env.define(id, new BuiltIn(id));
        env = new Tree.Environment(env);

        Ident test = new Ident("xxxx");
        IntLit test2 = new IntLit(3);

        env.define(test, test2);

        root = (Node) parser.parseExp();
        while (root != null)
        {
            root.eval(env).print(0);
            root = (Node) parser.parseExp();
        }

        // Read-eval-print loop

        // TODO: print prompt and evaluate the expression
        /*
        root = (Node) parser.parseExp();
        while (root != null)
        {
            root.print(0);
            root = (Node) parser.parseExp();
        }
        */

        return 0;
    }
Ejemplo n.º 3
0
 //Function for evaluating binary arithmetic operations
 private Node apply2(int arg1, int arg2)
 {
     string name = this.symbol.getName();
     bool flag = name.Equals("b+");
     Node result;
     if (flag)
     {
         result = new IntLit(arg1 + arg2);
     }
     else
     {
         bool flag2 = name.Equals("b-");
         if (flag2)
         {
             result = new IntLit(arg1 - arg2);
         }
         else
         {
             bool flag3 = name.Equals("b*");
             if (flag3)
             {
                 result = new IntLit(arg1 * arg2);
             }
             else
             {
                 bool flag4 = name.Equals("b/");
                 if (flag4)
                 {
                     result = new IntLit(arg1 / arg2);
                 }
                 else
                 {
                     bool flag5 = name.Equals("b=");
                     if (flag5)
                     {
                         result = BoolLit.getInstance(arg1 == arg2);
                     }
                     else
                     {
                         bool flag6 = name.Equals("b<");
                         if (flag6)
                         {
                             result = BoolLit.getInstance(arg1 < arg2);
                         }
                         else
                         {
                             Console.Error.WriteLine("Error: unknown built-in function");
                             result = Nil.getInstance();
                         }
                     }
                 }
             }
         }
     }
     return result;
 }
Ejemplo n.º 4
0
        // TODO: The method apply() should be defined in class Node
        // to report an error.  It should be overridden only in classes
        // BuiltIn and Closure.
        public override Node apply(Node args)
        {
            // note for all built in functions that need arguments...
            //
            // the function will never do a test to check whether args is a pair, because
            // args is always made a pair in special Regular for launching builtin_function apply.


            if (this.symbol.getName().Equals("read"))
            {
                if (args == null || !args.isNull())
                {
                    Console.WriteLine("Error: Read only needs no arguments for use.");
                    return(Nil.getInstance());
                }
                return((Node)Scheme4101.parser.parseExp());
            }

            else if (this.symbol.getName().Equals("write"))
            {
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: incorrect arguments. Nil passed, which cannot be used.");
                    return(Nil.getInstance());
                }

                args.getCar().print(0);

                return(Nil.getInstance());
            }
            else if (this.symbol.getName().equals("set-car!"))
            {
                arg1.setCar(arg2);

                return(arg1);
            }
            else if (this.symbol.getName().equals("set-cdr!"))
            {
                arg1.setCdr(arg2);

                return(arg1);
            }
            else if (this.symbol.getName().Equals("display"))
            {
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: incorrect arguments. Nil passed, which cannot be used.");
                    return(Nil.getInstance());
                }

                Tree.BuiltIn.builtIn_display__do_not_print_double_quotes = true;

                args.getCar().print(0);

                Tree.BuiltIn.builtIn_display__do_not_print_double_quotes = false;

                return(Nil.getInstance());
            }

            else if (this.symbol.getName().Equals("b+"))
            {
                // if there are no arguments, report error
                if (args == null)
                {
                    Console.WriteLine("Error: no arguments given for binary addition operation.");
                    return(Nil.getInstance());
                }

                // return zero if there are no arguments
                if (args.isNull())
                {
                    return(new IntLit(0));
                }
                // extend for all argument vars
                // and
                //check if first args have null
                if (args.getCar() != null &&
                    args.getCdr() != null)
                {
                    bool twoArguments_or_more;
                    // check if second argument is is nil.
                    if (args.getCdr().isNull())
                    {
                        twoArguments_or_more = false;
                    }
                    // see if there is a second item ,    ... and check that last tail of args is nil.
                    else if (args.getCdr().getCar() != null && args.getCdr().getCdr().isNull())
                    {
                        twoArguments_or_more = true;
                    }
                    else if (args.getCdr().getCar() != null && !args.getCdr().getCdr().isNull())
                    {
                        Console.WriteLine("Error: cannot process more than two args for binary addition.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        Console.WriteLine("Error: in b+ , one of arguments for expression has null node.");
                        return(Nil.getInstance());
                    }

                    if (twoArguments_or_more == false)
                    {
                        // check if argument is an intLit
                        if (args.getCar().isNumber())
                        {
                            // return the sole int lit node.
                            return(args.getCar());
                        }
                        else
                        {
                            Console.WriteLine("Error: in b+ , one of arguments for expression has null node.");
                            return(Nil.getInstance());
                        }
                    }
                    else
                    {
                        if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                        {
                            Console.WriteLine("Error: arguments must be IntLit for binary addition.");
                            return(Nil.getInstance());
                        }
                        else
                        {
                            IntLit int1 = (IntLit)args.getCar();
                            IntLit int2 = (IntLit)args.getCdr().getCar();
                            return(new IntLit(int1.getInt() + int2.getInt()));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: in b+ , there is a null  external node");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b-"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary subtraction operation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary subtraction.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();
                        return(new IntLit(int1.getInt() - int2.getInt()));
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary subtraction is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b*"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary multiplication operation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary multiplication.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();
                        return(new IntLit(int1.getInt() * int2.getInt()));
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary multiplication is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b/"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary division operation.");
                    return(Nil.getInstance());
                }
                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary division.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();
                        if (int2.getInt() == 0)
                        {
                            Console.WriteLine("Error: input not acceptable. cannot divide by zero.");
                            return(Nil.getInstance());
                        }
                        else
                        {
                            return(new IntLit(int1.getInt() / int2.getInt()));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary division is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b="))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary equality test operation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary equality test.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();

                        bool resultOfTest = (int1.getInt() == int2.getInt());

                        if (resultOfTest)
                        {
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary equality test is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b<"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary less than test operation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary less than test.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();

                        bool resultOfTest = (int1.getInt() < int2.getInt());

                        if (resultOfTest)
                        {
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary less than test is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b>"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary greater than test operation.");
                    return(Nil.getInstance());
                }
                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary greater than test.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();

                        bool resultOfTest = (int1.getInt() > int2.getInt());

                        if (resultOfTest)
                        {
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary greater than test is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b<="))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary less than equal than test operation.");
                    return(Nil.getInstance());
                }
                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary less than equal than test.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();

                        bool resultOfTest = (int1.getInt() <= int2.getInt());

                        if (resultOfTest)
                        {
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary less than equal than test is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("b>="))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for binary greater than equal than test operation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    if (!args.getCar().isNumber() || !args.getCdr().getCar().isNumber())
                    {
                        Console.WriteLine("Error: arguments must be IntLit for binary greater than equal than test.");
                        return(Nil.getInstance());
                    }
                    else
                    {
                        IntLit int1 = (IntLit)args.getCar();
                        IntLit int2 = (IntLit)args.getCdr().getCar();

                        bool resultOfTest = (int1.getInt() >= int2.getInt());

                        if (resultOfTest)
                        {
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Error: more than two arguments for binary greater than equal than test is not permissable.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("null?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing null evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isNull())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("symbol?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing symbol evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isSymbol())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("number?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing number evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isNumber())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("boolean?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing boolean evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isBool())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("procedure?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing procedure evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isProcedure())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("pair?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing pair evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isPair())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("environment?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing environment evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isEnvironment())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }
            else if (this.symbol.getName().Equals("string?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for testing string evaluation.");
                    return(Nil.getInstance());
                }

                // extend for all argument vars

                // check if number of args is correct
                bool argument_number_good = false;
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().isNull())
                {
                    argument_number_good = true;
                }

                if (argument_number_good)
                {
                    if (args.getCar().isString())
                    {
                        return(BoolLit.getInstance(true));
                    }
                    else
                    {
                        return(BoolLit.getInstance(false));
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for test. only need 1 cons node with nil tail for argument.");
                    return(Nil.getInstance());
                }
            }

            // working on predicate built in :    eq?
            else if (this.symbol.getName().Equals("eq?"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for eq?   test operation.");
                    return(Nil.getInstance());
                }
                // extend for all argument vars
                // and
                //check if any args have null or nil.
                if (args != null && args.getCar() != null &&
                    args.getCdr() != null && args.getCdr().getCar() != null &&
                    args.getCdr().getCdr().isNull())
                {
                    //if (!args.getCar () || !args.getCdr ().getCar () )


                    // check nil/null? first

                    // first car is nil but  second item is not nil...
                    // or the other way around   (vice versa)
                    if ((args.getCar().isNull() && !args.getCdr().getCar().isNull()) ||
                        (!args.getCar().isNull() && args.getCdr().getCar().isNull()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // success: both nil
                    else if (args.getCar().isNull() && args.getCdr().getCar().isNull())
                    {
                        return(BoolLit.getInstance(true));
                    }

                    // first car is type symbol but  second item is not symbol...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isSymbol() && !args.getCdr().getCar().isSymbol()) ||
                             (!args.getCar().isSymbol() && args.getCdr().getCar().isSymbol()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both symbol   now...
                    else if (args.getCar().isSymbol() && args.getCdr().getCar().isSymbol())
                    {
                        // check if the symbol's are identical

                        if (args.getCar().getName().Equals(args.getCdr().getCar().getName()))
                        {
                            // success:    both same symbol!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }

                    // first car is type number but  second item is not number...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isNumber() && !args.getCdr().getCar().isNumber()) ||
                             (!args.getCar().isNumber() && args.getCdr().getCar().isNumber()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both number   now...
                    else if (args.getCar().isNumber() && args.getCdr().getCar().isNumber())
                    {
                        // cast to new IntLits
                        IntLit intLit_1 = (IntLit)args.getCar();
                        IntLit intLit_2 = (IntLit)args.getCdr().getCar();


                        // check if the int values's are equal

                        if (intLit_1.getInt() == intLit_2.getInt())
                        {
                            // success:    both same integer!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }


                    // first car is type boolean but  second item is not boolean...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isBool() && !args.getCdr().getCar().isBool()) ||
                             (!args.getCar().isBool() && args.getCdr().getCar().isBool()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both boolean   now...
                    else if (args.getCar().isBool() && args.getCdr().getCar().isBool())
                    {
                        // cast nodes as new booleanNodes

                        BoolLit boolVal1 = (BoolLit)args.getCar();
                        BoolLit boolVal2 = (BoolLit)args.getCdr().getCar();

                        // check if the bool's equal

                        if (boolVal1.Equals(boolVal2))
                        {
                            // success:    both same bool!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }



                    // first car is type builtIn but  second item is not builtIn...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isBuiltIn() && !args.getCdr().getCar().isBuiltIn()) ||
                             (!args.getCar().isBuiltIn() && args.getCdr().getCar().isBuiltIn()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both builtIn   now...
                    else if (args.getCar().isBuiltIn() && args.getCdr().getCar().isBuiltIn())
                    {
                        // cast nodes as new builtIn
                        BuiltIn builtIn_val_1 = (BuiltIn)args.getCar();
                        BuiltIn builtIn_val_2 = (BuiltIn)args.getCdr().getCar();

                        // check if the builtIn's are identical

                        if (builtIn_val_1.getSymbol().Equals(builtIn_val_2.getSymbol()))
                        {
                            // success:    both same builtIn!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }

                    // by process of elimination
                    //now
                    // a object that ends up tested here would be surely a closure...

                    // first car is type closure but  second item is not closure...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isProcedure() && !args.getCdr().getCar().isProcedure()) ||
                             (!args.getCar().isProcedure() && args.getCdr().getCar().isProcedure()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both closure   now...
                    else if (args.getCar().isProcedure() && args.getCdr().getCar().isProcedure())
                    {
                        // cast nodes as new builtIn
                        Closure closure_val_1 = (Closure)args.getCar();
                        Closure closure_val_2 = (Closure)args.getCdr().getCar();

                        // check if the closure's are identical

                        if (closure_val_1.Equals(closure_val_2))
                        {
                            // success:    both same closure!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }



                    // first car is type environment but  second item is not environment...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isEnvironment() && !args.getCdr().getCar().isEnvironment()) ||
                             (!args.getCar().isEnvironment() && args.getCdr().getCar().isEnvironment()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both environment   now...
                    else if (args.getCar().isEnvironment() && args.getCdr().getCar().isEnvironment())
                    {
                        // cast nodes as new Environment
                        Environment environ_1 = (Environment)args.getCar();
                        Environment environ_2 = (Environment)args.getCdr().getCar();

                        // check if the environment's are identical

                        if (environ_1.Equals(environ_2))
                        {
                            // success:    both same environment!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }

                    // first car is type String but  second item is not String...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isString() && !args.getCdr().getCar().isString()) ||
                             (!args.getCar().isString() && args.getCdr().getCar().isString()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both String   now...
                    else if (args.getCar().isString() && args.getCdr().getCar().isString())
                    {
                        // cast nodes as new StringLits
                        StringLit String_1 = (StringLit)args.getCar();
                        StringLit String_2 = (StringLit)args.getCdr().getCar();

                        // check if the StringLit's are identical

                        if (String_1.getString().Equals(String_2.getString()))
                        {
                            // success:    both same StringLit!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }


                    // eq? test note:  there is one caveat.  If the items are both quote terms... this will be handled directly in regular eval

                    // first car is type Pair but  second item is not Pair...
                    // or the other way around   (vice versa)
                    else if ((args.getCar().isPair() && !args.getCdr().getCar().isPair()) ||
                             (!args.getCar().isPair() && args.getCdr().getCar().isPair()))
                    {
                        return(BoolLit.getInstance(false));
                    }
                    // check if both are type Pair   now...
                    else if (args.getCar().isPair() && args.getCdr().getCar().isPair())
                    {
                        // cast nodes as new cons Pair
                        Cons cons_1 = (Cons)args.getCar();
                        Cons cons_2 = (Cons)args.getCdr().getCar();

                        // check if the Cons's are identical

                        if (cons_1.Equals(cons_2))
                        {
                            // success:    both same pair reference!
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }

                        // illegal function for argument
                    }
                    else
                    {
                        Console.WriteLine("Error: Argument types for eq? cannot be recognized in context.");
                        return(Nil.getInstance());
                    }
                }
                else
                {
                    Console.WriteLine("Error: null parameter _ or _ more than two arguments for eq?  test is not permissable.");
                    return(Nil.getInstance());
                }
            }

            else if (this.symbol.getName().Equals("car"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for car operation.");
                    return(Nil.getInstance());
                }

                // check if args first item given is a pair   and check if the number of arguments given is correctly 1
                if (args.getCar() != null && args.getCdr() != null && args.getCdr().isNull())
                {
                    if (args.getCar().isPair())
                    {
                        if (args.getCar().getCar() != null)
                        {
                            return(args.getCar().getCar());
                        }
                        else
                        {
                            Console.WriteLine("Error: for car function_ , one of arguments to return is null.");
                            return(Nil.getInstance());
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error: for car function_ , item given is not a pair.");
                        return(Nil.getInstance());
                    }
                }
                else
                {
                    Console.WriteLine("Error: wrong number of arguments for car, tail is not nil.  or element in arguments is null.");
                    return(Nil.getInstance());
                }
            }

            else if (this.symbol.getName().Equals("cdr"))
            {
                // if there are no arguments, report error
                if (args == null || args.isNull())
                {
                    Console.WriteLine("Error: no arguments given for cdr operation.");
                    return(Nil.getInstance());
                }


                // check if args first item given is a pair   and check if the number of arguments given is correctly 1
                if (args.getCar() != null && args.getCar().isPair() && args.getCdr() != null && args.getCdr().isNull())
                {
                    // check if argument's cdr is not null
                    if (args.getCar().getCdr() != null)
                    {
                        return(args.getCar().getCdr());
                    }
                    else
                    {
                        Console.WriteLine("Error: for cdr function_ , one of arguments to return is null.");
                        return(Nil.getInstance());
                    }
                }
                else
                {
                    Console.WriteLine("Error: for cdr, item is not pair  or wrong number of arguments for cdr: tail is not nil.  or element in arguments is null.");
                    return(Nil.getInstance());
                }
            }

            else
            {
                Console.WriteLine("Error: builtin is not identifiable.");
                return(Nil.getInstance());
            }
        }