예제 #1
0
        // also now need to   ensure that all arguments in regular expression
        // get their values looked up if they are symbols


        // implementation
        // Note : sometimes env1  will not conform, or be pertinent to what is written relation to c# loops and scheme code
        public override Node eval(Node node1, Environment env1)
        {
            if (node1 == null || node1.getCar() == null)
            {
                Console.WriteLine("Error: the expression is not initialized to values: null list and car");
                return(Nil.getInstance());
            }



            // for any regular defined function enclosed in parentheses,
            // the first element is supposed to be a function to be evaluated.

            // this variable will hold the final function head term we get.
            Node firstElem_car = node1.getCar();

            // step one   :  if Car is a pair, evaluate it and store resulting ident, ... which ought to be
            // another function once evaluated...
            if (node1.getCar().isPair())
            {
                // build new environment for this to be computed for.
                Environment envExtend = new Environment(env1);
                firstElem_car = node1.getCar().eval(envExtend);
                //report error if not   a builtin/  or /closure
                if (firstElem_car == null || !firstElem_car.isProcedure())
                {
                    Console.WriteLine("Error: regular expression needs a function builtin/closure for first term!, __ + returning null instead.");
                    return(Nil.getInstance());
                }
            }
            else if (node1.getCar().isSymbol())
            {
                // start loop to get closure from obstructing intermediate symbolic expression.
                bool first_element_is_not_closure = true;
                firstElem_car = node1.getCar();
                while (first_element_is_not_closure)
                {
                    firstElem_car = env1.lookup(firstElem_car);
                    //report error if not   a builtin/  or /closure
                    if (firstElem_car == null)
                    {
                        Console.WriteLine("Error: regular expression needs a function builtin/closure for first term!, __ + returning null instead.");
                        return(Nil.getInstance());
                    }
                    else if (firstElem_car.isProcedure())
                    {
                        first_element_is_not_closure = false;
                    }
                }
            }
            // this would be improper end for cons   regular expression.
            if (node1.getCdr() == null)
            {
                Console.WriteLine("error: one of regular expressions elements is null.");
                return(Nil.getInstance());
            }

            // special builtIn   eval  case.
            BuiltIn givenId = null;

            if (firstElem_car.isBuiltIn())
            {
                givenId = (BuiltIn)firstElem_car;


                // check if built in is eval
                // note carefully: if symbol == null, null pointer will happen.
                if (givenId.getSymbol().getName().Equals("eval"))
                {
                    // build new environment for this to be computed for.
                    Environment envExtend = new Environment(env1);

                    // check for null values now  so null pointer doesnt get encountered
                    if (node1.getCdr().getCar() == null || node1.getCdr().getCdr() == null ||
                        node1.getCdr().getCdr().getCar() == null)
                    {
                        Console.WriteLine("Error: lacking one of the following for eval : expression or environment.");
                        return(Nil.getInstance());
                    }


                    // side maneuver. _ work out the environment first...
                    bool environment_taken    = false;
                    Node env_symbol_to_lookup = node1.getCdr().getCdr().getCar();
                    Node environment_found    = null;
                    // check if symbol needs to be evaluated
                    if (env_symbol_to_lookup.isSymbol())
                    {
                        if (env1.lookup(env_symbol_to_lookup) != null)
                        {
                            environment_found = env1.lookup(env_symbol_to_lookup);
                        }
                        else
                        {
                            Console.WriteLine("Error: environment symbol was not found.");
                            return(Nil.getInstance());
                        }
                    }                     // check if expression needs to be evaluated
                    else if (env_symbol_to_lookup.isPair())
                    {
                        environment_found = env_symbol_to_lookup.eval(envExtend);
                    }

                    if (environment_found != null && environment_found.isEnvironment())
                    {
                        environment_taken = true;
                    }
                    else
                    {
                        Console.WriteLine("Error: evaluation op_ did not find a fitting environment.");
                        return(Nil.getInstance());
                    }
                    // working on expression now
                    Node args_to_eval = null;

                    Node localTerms_data = node1.getCdr().getCar();

                    // check if second argument is code
                    //   and then evaluate if it needs more processing
                    // for eval to implement as code
                    if (localTerms_data.isPair() && environment_taken)
                    {
                        if (localTerms_data.getCar() != null && localTerms_data.getCar().isSymbol() &&
                            localTerms_data.getCar().getName().Equals("quote"))
                        {
                            Node args_of_Quote = localTerms_data.eval(envExtend);

                            if (args_of_Quote != null)
                            {
                                // copy evaluated quote expression
                                args_to_eval = args_of_Quote;
                            }
                        }
                        else if (localTerms_data.getCar() != null && localTerms_data.getCar().isSymbol() &&
                                 localTerms_data.getCar().getName().Equals("lambda"))
                        {
                            Node args_of_Lambda = localTerms_data.eval(envExtend);

                            if (args_of_Lambda != null)
                            {
                                // copy evaluated lambda expression
                                args_to_eval = args_of_Lambda;
                            }
                        }
                        else
                        {
                            // this needs fine tuning for more special cases..\\

                            //("may have more cases... ")
                            //??
                            args_to_eval = localTerms_data;
                        }
                    }
                    else if (localTerms_data.isSymbol() && environment_taken)
                    {
                        Node node_symbol_expression = env1.lookup(localTerms_data);
                        if (node_symbol_expression != null)
                        {
                            // copy evaluated symbol and then the environment
                            args_to_eval = node_symbol_expression;
                        }
                        else
                        {
                            Console.WriteLine("Error: first expression argument symbol not found.");
                            return(Nil.getInstance());
                        }
                    }
                    // return the built in eval of args and environment given
                    if (args_to_eval != null)
                    {
                        Environment environment_copy_found = (Environment)environment_found;
                        if (args_to_eval.isPair())
                        {
                            return(args_to_eval.eval(environment_copy_found));
                        }
                        else
                        {
                            return(args_to_eval.eval(environment_copy_found));
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error: expression arg was null.");
                        return(Nil.getInstance());
                    }
                }



                // note: looking at special eq? case
                // check if built in is eq?    only look at case of (eq? 'exp 'exp)
                // note carefully: if symbol == null, null pointer will happen.
                if (givenId.getSymbol().getName().Equals("eq?") &&
                    node1.getCdr().getCar() != null &&
                    node1.getCdr().getCdr() != null &&
                    node1.getCdr().getCdr().getCar() != null &&
                    node1.getCdr().getCdr().getCdr() != null &&
                    node1.getCdr().getCdr().getCdr().isNull() &&

                    node1.getCdr().getCar().isPair() &&
                    node1.getCdr().getCdr().getCar().isPair()

                    )


                {
                    // first we must check if the arguments to (eq? ... )are in fact quote arguments.
                    Cons argument1 = (Cons)node1.getCdr().getCar();

                    Cons argument2 = (Cons)node1.getCdr().getCdr().getCar();

                    if (argument1.getForm_ofCons() is Tree.Quote && argument2.getForm_ofCons() is Tree.Quote)
                    {
                        String first_argument_printed  = "";
                        String second_argument_printed = "";



                        // redirect output to evaulate if print of Pair nodes is same

                        var originalConsoleOut = Console.Out;                         // preserve the original stream
                        using (var writer = new StringWriter())
                        {
                            Console.SetOut(writer);

                            argument1.print(0);

                            writer.Flush();

                            var myString = writer.ToString();

                            first_argument_printed = myString.TrimEnd('\n');
                        }
                        using (var writer1 = new StringWriter())
                        {
                            Console.SetOut(writer1);

                            argument2.print(0);

                            writer1.Flush();

                            var myString_2 = writer1.ToString();

                            second_argument_printed = myString_2.TrimEnd('\n');
                        }


                        Console.SetOut(originalConsoleOut);                         // restore Console.Out


                        if (first_argument_printed.Equals(second_argument_printed))
                        {
                            return(BoolLit.getInstance(true));
                        }
                        else
                        {
                            return(BoolLit.getInstance(false));
                        }
                    }
                }

                // security check for eof-object? builtIn test...
                if (givenId != null && givenId.getSymbol().getName().Equals("eof-object?"))
                {
                    if (node1.getCdr().isNull() || !node1.getCdr().isPair())
                    {
                        Console.WriteLine("Error: no argument for eof-object? test.  the BuiltIn function eof-object?  requires one argument to test.");
                        return(Nil.getInstance());
                    }
                }
            }



            // other cases  builtin or closure...



            Node args_given   = node1.getCdr();
            bool hasArguments = true;

            // test if there are arguments to this form  function
            if (args_given.isNull())
            {
                hasArguments = false;
            }



            if (hasArguments)
            {
                if (args_given.getCdr() == null || args_given.getCar() == null)
                {
                    Console.WriteLine("Error: one of passed arguments in function expression is null.");
                    return(Nil.getInstance());
                }


                // need to evaluate args (each car separately)... and then return what is resulting list of elements...

                // build new environment on hand _ for each car to be computed at times.
                Environment envExtend1 = new Environment(env1);

                // this will hold the list of evaluated arguments cumulatively.
                Cons evaluated_argsList__in_progress;


                // this will hold a latest fringe of for extending fringe items.

                Cons fringe_cons = null;


                bool hasMoreDescendents = !args_given.getCdr().isNull();


                if (hasMoreDescendents)
                {
                    // start this off as unassigned.
                    Cons added_fringe_con = null;

                    // this will hold the list of evaluated arguments cumulatively.
                    // Cons evaluated_argsList__in_progress;

                    // check if eval is not null
                    Node evalItem1 = args_given.getCar().eval(envExtend1);
                    if (evalItem1 != null)
                    {
                        evaluated_argsList__in_progress = new Cons(evalItem1, added_fringe_con);
                    }
                    else
                    {
                        // first a detour...
                        //
                        // check for special case of eof-object? builtIn test

                        if (givenId != null && givenId.getSymbol().getName().Equals("eof-object?"))
                        {
                            Console.WriteLine("Error: too many args for function eof-object? test. ");
                            return(Nil.getInstance());
                        }                          // normal case where regular expression argument evaluated to null  is to throw an error
                        else
                        {
                            Console.WriteLine("Error: one of the args items in regular function was null. ");
                            return(Nil.getInstance());
                        }
                    }

                    // under the alias of fringe_cons...
                    // we will continue this reference down to assess the next fringe branch
                    fringe_cons = evaluated_argsList__in_progress;
                }
                // dealt with the sole generation here.
                // no more fringes left.
                else
                {
                    // check if eval is not null
                    Node evalItem1 = args_given.getCar().eval(envExtend1);
                    if (evalItem1 != null)
                    {
                        // first a detour...
                        //
                        // check for special case of eof-object? builtIn test is false

                        if (givenId != null && givenId.getSymbol().getName().Equals("eof-object?"))
                        {
                            return(BoolLit.getInstance(false));
                        }                          // normal case where regular expression argument evaluated to null  is to throw an error
                        else
                        {
                            evaluated_argsList__in_progress = new Cons(evalItem1, Nil.getInstance());
                        }
                    }
                    else
                    {
                        // first a detour...
                        //
                        // check for special case of eof-object? builtIn test is true

                        if (givenId != null && givenId.getSymbol().getName().Equals("eof-object?"))
                        {
                            return(BoolLit.getInstance(true));
                        }                          // normal case where regular expression argument evaluated to null  is to throw an error
                        else
                        {
                            Console.WriteLine("Error: the sole additional argument item  in regular function was null. ");
                            return(Nil.getInstance());
                        }
                    }
                }

                // done with first step in two levels descendents


                // get rest of fringes
                while (hasMoreDescendents)
                {
                    if (args_given.getCdr() == null)
                    {
                        Console.WriteLine("Error: one of the later argument items  in regular function was null. ");
                        return(Nil.getInstance());
                    }
                    // precaution for null pointer   so it is legal to use the cdr after this test
                    if (args_given.getCdr().isPair())
                    {
                        // build new environment for this to be computed for.
                        Environment envExtend2 = new Environment(env1);

                        // get next fringe descendent.
                        args_given = args_given.getCdr();

                        // start this off as unassigned.
                        Cons added_fringe_con = null;


                        // check if additional eval items are not null
                        Node evalItem_more = args_given.getCar().eval(envExtend2);
                        if (evalItem_more != null)
                        {
                            fringe_cons.setCdr(new Cons(evalItem_more, added_fringe_con));
                        }
                        else
                        {
                            Console.WriteLine("Error: one of the later argument items  in regular function was null. ");
                            return(Nil.getInstance());
                        }

                        fringe_cons = (Cons)fringe_cons.getCdr();
                    }
                    else if (args_given.getCdr().isNull())
                    {
                        fringe_cons.setCdr(Nil.getInstance());
                        hasMoreDescendents = false;
                    }
                    else
                    {
                        // build new environment for this to be computed for.
                        Environment envExtend2 = new Environment(env1);

                        // get one remaining fringe descendent.
                        args_given = args_given.getCdr();

                        // check if additional eval items are not null
                        Node evalItem_more = args_given.getCar().eval(envExtend2);

                        if (evalItem_more != null)
                        {
                            fringe_cons.setCdr(new Cons(evalItem_more, Nil.getInstance()));
                        }
                        else
                        {
                            Console.WriteLine("Error: one of the later argument items  in regular function was null. ");
                            return(Nil.getInstance());
                        }

                        hasMoreDescendents = false;
                    }
                }

                return(firstElem_car.apply(evaluated_argsList__in_progress));
            }

            return(firstElem_car.apply(Nil.getInstance()));
        }
예제 #2
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());
            }
        }