Beispiel #1
0
        private Node evalArithmetic(int arg1, int arg2)
        {
            string name = symbol.getName();

            if (name.Equals("b+"))
            {
                return(new IntLit(arg1 + arg2));
            }
            if (name.Equals("b-"))
            {
                return(new IntLit(arg1 - arg2));
            }
            if (name.Equals("b*"))
            {
                return(new IntLit(arg1 * arg2));
            }
            if (name.Equals("b/"))
            {
                return(new IntLit(arg1 / arg2));
            }
            if (name.Equals("b="))
            {
                return(BoolLit.getInstance(arg1 == arg2));
            }
            if (name.Equals("b<"))
            {
                return(BoolLit.getInstance(arg1 < arg2));
            }
            Console.Error.WriteLine("Error: unknown arithmetic symbol");
            return(Nil.getInstance());
        }
Beispiel #2
0
        //syntax: if <test> <consequent> <alternate>
        //syntax: if <test> <consequent>

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

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

            var alternate = new Node();

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

            if (test.eval(env) != BoolLit.getInstance(false))
            {
                return(consequent.eval(env));
            }
            return(alternate.eval(env));
        }
        private Node BinArith(int arg1, int arg2, string s)
        {
            switch (s)
            {
            case "+":
                return(new IntLit(arg1 + arg2));

            case "-":
                return(new IntLit(arg1 - arg2));

            case "*":
                return(new IntLit(arg1 * arg2));

            case "/":
                return(new IntLit(arg1 / arg2));

            case "=":
                return(BoolLit.getInstance(arg1 == arg2));

            case "<":
                return(BoolLit.getInstance(arg1 < arg2));

            case ">":
                return(BoolLit.getInstance(arg1 > arg2));

            default:
                return(null);
            }
        }
Beispiel #4
0
        // to evaluate expressions of the form '(if b t e)',
        // evaluate b, then if b is not the boolean constant #f,
        // evaluate t and return the result. otherwise, evaluate
        // e and return the result.
        public override Node eval(Node t, Environment env)
        {
            // if cdr is nil, return nil (error state)
            if (t.getCdr() == Nil.getInstance())
            {
                Console.Error.WriteLine("Special form 'If' evaluated with no arguments");
                return(Nil.getInstance());
            }

            // get cdr of expression (conditional and execution statements)
            t = t.getCdr();

            // if cdr of t is nil, expression has a conditional but no executable statements (error state)
            if (t.getCdr() == Nil.getInstance())
            {
                Console.Error.WriteLine("Special form 'If' evaluated with insufficient arguments");
                return(Nil.getInstance());
            }

            // evaluate car of b (conditional). if b is not #f, evaluate and return t.
            if (t.getCar().eval(env) != BoolLit.getInstance(false))
            {
                return(t.getCdr().getCar().eval(env));
            }
            else
            {
                // otherwise, b is #f. evaluate and return e.
                // if e is nil, statement is still valid. interpreter will parse and return nil.
                return(t.getCdr().getCdr().getCar().eval(env));
            }
        }
Beispiel #5
0
        private Node apply2(Node arg1, Node arg2)
        {
            string name = symbol.getName();

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

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

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

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

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

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

            return(cdr.eval(env).apply(BoolLit.getInstance(true)));
        }
Beispiel #7
0
        public override Node eval(Node t, Environment env)
        {
            Node test  = t.getCdr().getCar();
            Node consq = t.getCdr().getCdr();
            Node alt   = consq.getCdr();

            if (test.eval(env) == BoolLit.getInstance(true))
            {
                return(consq.getCar().eval(env));
            }
            else if (!(alt is Nil))
            {
                return(alt.getCar().eval(env));
            }
            Console.Error.WriteLine("Error: If not properly formatted");
            return(Nil.getInstance());
        }
Beispiel #8
0
        private Node apply1(Node arg1)
        {
            string name = symbol.getName();

            if (name.Equals("car"))
            {
                return(arg1.getCar());
            }
            if (name.Equals("cdr"))
            {
                return(arg1.getCdr());
            }
            if (name.Equals("number?"))
            {
                return(BoolLit.getInstance(arg1.isNumber()));
            }
            if (name.Equals("symbol?"))
            {
                return(BoolLit.getInstance(arg1.isSymbol()));
            }
            if (name.Equals("null?"))
            {
                return(BoolLit.getInstance(arg1.isNull()));
            }
            if (name.Equals("pair?"))
            {
                return(BoolLit.getInstance(arg1.isPair()));
            }
            if (name.Equals("procedure?"))
            {
                return(BoolLit.getInstance(arg1.isProcedure()));
            }
            if (name.Equals("write"))
            {
                arg1.print(-1);
                return(Unspecific.getInstance());
            }
            if (name.Equals("display"))
            {
                Console.Write(arg1);
                return(Unspecific.getInstance());
            }
            Console.Error.WriteLine("Error: wrong number of arguments");
            return(Nil.getInstance());
        }
Beispiel #9
0
        public override Node eval(Node t, Environment env)
        {
            while (!(t.getCdr() is Nil))
            {
                t = t.getCdr();
                if (!(t.getCar() is Cons))
                {
                    Console.Error.WriteLine("Error: unexpected argument");
                }
                Node n = t.getCar().getCar().eval(env);
                if (t.getCar().getCar().eval(env).Equals(BoolLit.getInstance(true)))
                {
                    t = t.getCar();

                    return(t.getCdr().getCar().eval(env));
                }
            }
            // get else to work...?
            return(Void.getInstance());
        }
Beispiel #10
0
        public override Node eval(Node exp, Environment env)
        {
            int  numArgs = 0;
            Node expCdr  = exp.getCdr();

            while (!expCdr.isNull())
            {
                numArgs++;
                expCdr = expCdr.getCdr();
            }
            Node cnd;
            Node thn;
            Node els;

            if (numArgs < 2 || numArgs > 3)
            {
                Console.Error.WriteLine("Error: invalid expression");
                return(Nil.getInstance());
            }
            else
            {
                cnd = exp.getCdr().getCar();
                thn = exp.getCdr().getCdr().getCar();
                if (numArgs == 3)
                {
                    els = exp.getCdr().getCdr().getCdr().getCar();
                }
                else
                {
                    els = new StringLit("#{Unspecific}", false);
                }
            }
            if (cnd.eval(env) != BoolLit.getInstance(false))
            {
                return(thn.eval(env));
            }
            return(els.eval(env));
        }
Beispiel #11
0
        public override Node eval(Environment env, Node args)
        {
            Node result = BoolLit.getInstance(false), test, cases = args;

            // Iterate through each case test until it evaluates to true or we hit the end
            do
            {
                cases = cases.getCdr();
                test  = cases.getCar().getCar();
                if (test.getName() == "else")
                {
                    break;
                }
                result = test.eval(env);
            } while (cases.getCdr().isNull() == false && result == BoolLit.getInstance(false));

            // if a expr value returned true or we hit an else clause
            if (result != BoolLit.getInstance(false) || test.getName() == "else")
            {
                // If there was a test with no other expressions, apply the test
                if (cases.getCar().getCdr().isNull() == true)
                {
                    return(args.getCar().eval(env).apply(result));
                }
                // Otherwise apply the following expressions
                else
                {
                    Node debug = cases.getCar().getCdr(), debug2 = args.getCar();
                    return(args.getCar().eval(env).apply(cases.getCar().getCdr().eval(env)));
                }
            }
            else
            {
                return(new StringLit("#unspecified"));
            }
        }
Beispiel #12
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()));
        }
Beispiel #13
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);
        }
Beispiel #14
0
 public override Node eval(Environment env, Node args = null)
 {
     return(BoolLit.getInstance(boolVal));
 }
 public INode buildBoolLit(bool b)
 {
     return(BoolLit.getInstance(b));
 }
        // TODO: The method apply() should be defined in class Node
        // to report an error.  It should be overridden only in classes
        // BuiltIn and Closure.  Probably will have to include calls to eval
        public override Node apply(Node args)
        {
            if (args == null)
            {
                return(null);
            }

            String Symbol = symbol.getName();
            Node   arg1 = args.getCar(), arg2 = args.getCdr().getCar();

            switch (Symbol)
            {
            case "symbol?":
                return(BoolLit.getInstance(arg1.isSymbol()));

            case "number?":
                return(BoolLit.getInstance(arg1.isNumber()));

            case "b+":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), "+"));

            case "b-":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), "-"));

            case "b*":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), "*"));

            case "b/":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), "/"));

            case "b=":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), "="));

            case "b>":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), ">"));

            case "b<":
                return(BinArith(((IntLit)arg1).getValue(), ((IntLit)arg2).getValue(), "<"));

            case "car":
                if (arg1.isNull())
                {
                    return(arg1);    //arg1==nil or null?
                }
                else
                {
                    return(arg1.getCar());
                }

            case "cdr":      // ????????????????
                if (arg1.isNull())
                {
                    return(arg1);    //arg1==nil or null?
                }
                else
                {
                    return(arg1.getCdr());
                }

            case "cons":
                return(new Cons(arg1, arg2));

            case "set-car!":
                arg1.setCar(arg2);
                return(arg1);

            case "set-cdr!":
                arg1.setCdr(arg2);
                return(arg1);

            case "null?":
                return(BoolLit.getInstance(arg1.isNull()));

            case "pair?":
                return(BoolLit.getInstance(arg1.isPair()));

            case "eq?":
                return(BoolLit.getInstance(arg1 == arg2));

            case "procedure?":
                return(BoolLit.getInstance(arg1.isProcedure()));

            case "read":     //call parser and returns parse tree
                Parser parse = new Parser(new Scanner(Console.In), new TreeBuilder());
                return((Node)parse.parseExp());

            case "write":
                return(new StringLit("Cha{" + arg1.ToString() + "/*WRITE*\\}"));

            case "display":
                return(new StringLit("Cha{" + arg1.ToString() + "/*DISPLAY*\\}")); //not truly implemented, placeholder code I tink

            case "newline":                                                        //\n?
                return(new StringLit("\n"));

            case "eval":
                return(arg1.eval(new Environment()));

            case "apply":
                return(arg1.apply(arg2));

            case "interaction-environment":
                //args.env
                //do
                //{
                //    //TODO
                //    env = new Environment();
                //} while (env != null);
                return(new Environment());
            }
            return(null);
        }
Beispiel #17
0
        // check if null/end of last clause:
        //    return unspecific
        // check if else clause:
        //    yes: eval exps and return value of last exp
        // check if clause has exp
        //    if no exp: return value of test
        //    if test failed: go to next clause
        //    check alt or normal form
        //        eval expression(s) appropriately
        private Node evalConds(Node clauses, Environment env)
        {
            // if end of clauses and nothing has been returned, return unspecific
            if (clauses.isNull())
            {
                return(new StringLit("#{Unspecific}", false));
            }
            Node cnd = clauses.getCar();

            // make sure clause isnt empty
            if (cnd.isNull())
            {
                Console.Error.WriteLine("Error: invalid expression");
                return(Nil.getInstance());
            }
            Node test  = cnd.getCar();
            Node exprs = cnd.getCdr();
            Node expr;

            if (test.isSymbol() && test.getName().Equals("else"))
            {
                //erorr if no expression or else is not last clause
                if (exprs.isNull() || !clauses.getCdr().isNull())
                {
                    Console.Error.WriteLine("Error: invalid expression");
                    return(Nil.getInstance());
                }
                else
                {
                    // evaluate each expr in exprs then return the last one
                    Node car = Nil.getInstance();
                    while (!exprs.isNull())
                    {
                        expr = exprs.getCar();
                        car  = expr.eval(env);
                        if (expr.isPair())
                        {
                            Node cdr = expr.getCdr();
                            while (!cdr.isNull())
                            {
                                car = cdr.getCar().eval(env);
                                cdr = cdr.getCdr();
                            }
                        }
                        exprs = exprs.getCdr();
                    }
                    return(car);
                }
            }
            Node testEval = test.eval(env);

            // if clause is a test with no expressions
            if (exprs.isNull())
            {
                return(testEval);
            }
            // if test failed go to next clause
            if (testEval == BoolLit.getInstance(false))
            {
                return(evalConds(clauses.getCdr(), env));
            }
            // if alternate form
            if (exprs.getCar().getName().Equals("=>"))
            {
                return(exprs.getCdr().getCar().eval(env).apply(testEval));
            }
            //normal form: iterate exprs, evaluate each expr, then return last expr
            else
            {
                Node car = Nil.getInstance();
                while (!exprs.isNull())
                {
                    expr = exprs.getCar();
                    car  = expr.eval(env);
                    if (expr.isPair())
                    {
                        Node cdr = expr.getCdr();
                        while (!cdr.isNull())
                        {
                            car = cdr.getCar().eval(env);
                            cdr = cdr.getCdr();
                        }
                    }
                    exprs = exprs.getCdr();
                }
                return(car);
            }
        }
Beispiel #18
0
        // DONE :: 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)
        {
            string name    = symbol.getName();
            int    numArgs = 0;
            Node   arg1;
            Node   arg2;
            Node   tempArgs = args;

            while (!tempArgs.isNull())
            {
                numArgs++;
                tempArgs = tempArgs.getCdr();
            }

            if (numArgs == 0)
            {
                if (name.Equals("read"))
                {
                    Parser parser = new Parser(new Scanner(Console.In), new TreeBuilder());
                    Node   exp    = (Node)parser.parseExp();
                    if (!exp.isNull())
                    {
                        return(exp);
                    }
                    return(new StringLit("End of file", false));
                }
                else if (name.Equals("newline"))
                {
                    Console.WriteLine();
                    return(new StringLit("#{Unspecific}", false));
                }
                else if (name.Equals("interaction-environment"))
                {
                    return(Scheme4101.env);
                }
                Console.Error.WriteLine("Error: invalid input");
                return(Nil.getInstance());
            }
            else if (numArgs == 1)
            {
                arg1 = args.getCar();
                if (name.Equals("symbol?"))
                {
                    return(BoolLit.getInstance(arg1.isSymbol()));
                }
                if (name.Equals("number?"))
                {
                    return(BoolLit.getInstance(arg1.isNumber()));
                }
                if (name.Equals("car"))
                {
                    return(arg1.getCar());
                }
                if (name.Equals("cdr"))
                {
                    return(arg1.getCdr());
                }
                if (name.Equals("null?"))
                {
                    return(BoolLit.getInstance(arg1.isNull()));
                }
                if (name.Equals("pair?"))
                {
                    return(BoolLit.getInstance(arg1.isPair()));
                }
                if (name.Equals("procedure?"))
                {
                    return(BoolLit.getInstance(arg1.isProcedure()));
                }
                if (name.Equals("write"))
                {
                    arg1.print(0);
                    return(new StringLit("#{Unspecific}", false));
                }
                if (name.Equals("display"))
                {
                    StringLit.printQuotes = false;
                    arg1.print(0);
                    StringLit.printQuotes = true;
                    return(new StringLit("#{Unspecific}", false));
                }
                Console.Error.WriteLine("Error: invalid input");
                return(Nil.getInstance());
            }
            else if (numArgs == 2)
            {
                arg1 = args.getCar();
                arg2 = args.getCdr().getCar();
                if (name.Equals("eq?"))
                {
                    if (arg1.isSymbol() && arg2.isSymbol())
                    {
                        return(BoolLit.getInstance(arg1.getName().Equals(arg2.getName())));
                    }
                    return(BoolLit.getInstance(arg1 == arg2));
                }
                if (name.Equals("cons"))
                {
                    return(new Cons(arg1, arg2));
                }
                if (name.Equals("set-car!"))
                {
                    arg1.setCar(arg2);
                    return(new StringLit("#{Unspecific}", false));
                }
                if (name.Equals("set-cdr!"))
                {
                    arg1.setCdr(arg2);
                    return(new StringLit("#{Unspecific}", false));
                }
                if (name.Equals("eval"))
                {
                    return(arg1.eval((Environment)arg2));
                }
                if (name.Equals("apply"))
                {
                    return(arg1.apply(arg2));
                }

                int int1;
                int int2;
                if (arg1.isNumber() && arg2.isNumber())
                {
                    int1 = arg1.getValue();
                    int2 = arg2.getValue();
                }
                else
                {
                    Console.Error.WriteLine("Error: invalid argument types");
                    return(Nil.getInstance());
                }
                if (name.Equals("b+"))
                {
                    if (arg1.isNumber() && arg2.isNumber())
                    {
                        return(new IntLit(int1 + int2));
                    }
                }
                if (name.Equals("b-"))
                {
                    return(new IntLit(int1 - int2));
                }
                if (name.Equals("b*"))
                {
                    return(new IntLit(int1 * int2));
                }
                if (name.Equals("b/"))
                {
                    return(new IntLit(int1 / int2));
                }
                if (name.Equals("b="))
                {
                    return(BoolLit.getInstance(int1 == int2));
                }
                if (name.Equals("b<"))
                {
                    return(BoolLit.getInstance(int1 < int2));
                }
                Console.Error.WriteLine("Error: invalid function");
                return(Nil.getInstance());
            }
            else
            {
                Console.Error.WriteLine("Error: wrong number of args");
                return(Nil.getInstance());
            }
        }
Beispiel #19
0
        // to evaluate expressions of the form '(cond (b1 ...) ... (bn ...))',
        // evaluate b1 through bn until a condition not equal to #f is found.
        // if this case is of the form '(bi)', return bi.
        // if this case is of the form '(bi e1 ... en)', evaluate e1-en and return
        // the result of evaluating en
        public override Node eval(Node t, Environment env)
        {
            // if cond expression has no cdr, invalid syntax (error state)
            if (t.getCdr() == Nil.getInstance())
            {
                Console.Error.WriteLine("Special form 'cond' evaluated with no arguments");
                return(Nil.getInstance());
            }

            // get cdr of expression
            t = t.getCdr();

            // while cond statement has a cdr and its car (bi) evaluates to #f, keep moving down the tree
            while (t.getCdr() != Nil.getInstance() && t.getCar().getCar().eval(env) == BoolLit.getInstance(false))
            {
                t = t.getCdr();
            }

            // once a condition is found that is not #f or end of statement,
            // get car of t to evaluate
            t = t.getCar();

            // if cdr of t is null, statement is of form '(bi)', so return bi
            if (t.getCdr().eval(env) == Nil.getInstance())
            {
                return(t.getCar());
            }

            // otherwise, statement is of form (bi e1 ... en)
            // evaluate e1 through en, then return the result of evaluating en
            // first evaluate e1 through e(n-1)
            while (t.getCdr() != Nil.getInstance())
            {
                t.getCdr().getCar().eval(env);
                t = t.getCdr();
            }

            // finally evaluate and return en
            return(t.getCar().eval(env));
        }
Beispiel #20
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)
        {
            // return new StringLit("Error: BuiltIn.apply not yet implemented");
            Node   arg1    = Nil.getInstance();
            String symName = symbol.getName();

            if (symName.Equals("interaction-environment"))
            {
                return(global);
            }
            if (symName.Equals("newline"))
            {
                Console.WriteLine();
                return(Void.getInstance());
            }
            if (!(args.getCar() is Nil))
            {
                arg1 = args.getCar();
            }
            Node arg2 = Nil.getInstance();

            if (!args.getCdr().isNull())
            {
                arg2 = args.getCdr().getCar();
            }
            if (symName.Equals("symbol?"))
            {
                return(BoolLit.getInstance(arg1.isSymbol()));
            }
            if (symName.Equals("number?"))
            {
                return(BoolLit.getInstance(arg1.isNumber()));
            }
            if (symName.Equals("b+"))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(new IntLit(arg1.getVal() + arg2.getVal()));
                }
            }
            if (symName.Equals("b-"))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(new IntLit(arg1.getVal() - arg2.getVal()));
                }
            }
            if (symName.Equals("b*"))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(new IntLit(arg1.getVal() * arg2.getVal()));
                }
            }
            if (symName.Equals("b/"))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(new IntLit(arg1.getVal() / arg2.getVal()));
                }
            }
            if (symName.Equals("b="))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(BoolLit.getInstance(arg1.getVal() == arg2.getVal()));
                }
            }
            if (symName.Equals("b<"))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(BoolLit.getInstance(arg1.getVal() < arg2.getVal()));
                }
            }
            if (symName.Equals("b>"))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(BoolLit.getInstance(arg1.getVal() > arg2.getVal()));
                }
            }
            if (symName.Equals("b>="))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(BoolLit.getInstance(arg1.getVal() >= arg2.getVal()));
                }
            }
            if (symName.Equals("b<="))
            {
                if (arg1.isNumber() & arg2.isNumber())
                {
                    return(BoolLit.getInstance(arg1.getVal() <= arg2.getVal()));
                }
            }
            if (symName.Equals("car"))
            {
                return(arg1.getCar());
            }
            if (symName.Equals("cdr"))
            {
                return(arg1.getCdr());
            }
            if (symName.Equals("set-car!"))
            {
                arg1.setCar(arg2);
                return(Void.getInstance());
            }
            if (symName.Equals("set-cdr!"))
            {
                arg1.setCdr(arg2);
                return(Void.getInstance());
            }
            if (symName.Equals("null?"))
            {
                return(BoolLit.getInstance(arg1.isNull()));
            }
            if (symName.Equals("pair?"))
            {
                return(BoolLit.getInstance(arg1.isPair()));
            }
            if (symName.Equals("eq?"))
            {
                if (arg1.isSymbol() && arg2.isSymbol())
                {
                    return(BoolLit.getInstance(arg1.getName().Equals(arg2.getName())));
                }
                return(BoolLit.getInstance(arg1 == arg2));
            }
            if (symName.Equals("procedure?"))
            {
                return(BoolLit.getInstance(arg1.isProcedure()));
            }
            if (symName.Equals("read"))
            {
                Scanner     scanner = new Scanner(Console.In);
                TreeBuilder builder = new TreeBuilder();
                Parser      parser  = new Parser(scanner, builder);
                Node        root    = (Node)parser.parseExp();
                return(Void.getInstance());
            }
            if (symName.Equals("write"))
            {
                arg1.print(0);
                return(Void.getInstance());
            }
            if (symName.Equals("display"))
            {
                ((StringLit)arg1).displayPrint();
                return(Void.getInstance());
            }
            if (symName.Equals("eval"))
            {
                return(arg1.eval((Environment)arg2));
            }
            if (symName.Equals("apply"))
            {
                return(arg1.apply(arg2));
            }
            return(Void.getInstance());
        }
Beispiel #21
0
        public override Node apply(Node args)
        {
            //set initial values
            string argsName   = symbol.getName();
            int    argsAmount = 0;

            //initialize
            Node firstArgs  = null;
            bool b1         = false;
            Node secondArgs = null;
            bool b2         = false;

            //setup initial Args
            while (!args.isNull())
            {
                argsAmount = argsAmount + 1;
                if (argsAmount == 1)
                {
                    firstArgs = args.getCar();
                    b1        = true;
                }
                if (argsAmount == 2)
                {
                    secondArgs = args.getCar();
                    b2         = true;
                }
                args = args.getCdr();
            }

            //start apply based on amount or arguements and type of arguement
            //switch statement possibly
            if (argsAmount == 0)
            {
                // read
                if (argsName.Equals("read"))
                {
                    Scanner     s  = new Scanner(Console.In);
                    TreeBuilder tb = new TreeBuilder();
                    Parser      p  = new Parser(s, tb);
                    Node        n  = (Node)p.parseExp();
                    if (n != null)
                    {
                        return(n);
                    }
                }
                //newline
                else if (argsName.Equals("newline"))
                {
                    Console.WriteLine();
                    //check value upspecified
                    return(new StringLit(" "));
                }
                //i-e
                else if (argsName.Equals("interaction-environment"))
                {
                    return(Scheme4101.env);
                }
                //invalid argsName given
                else
                {
                    Console.Error.WriteLine("invalid arguemtent name given");
                    return(Nil.getInstance());
                }
            }
            else if (argsAmount == 1)
            {
                //symbol?
                if (argsName.Equals("symbol?"))
                {
                    bool b = firstArgs.isSymbol();
                    return(BoolLit.getInstance(b));
                }
                //number?
                else if (argsName.Equals("number?"))
                {
                    bool b = firstArgs.isNumber();
                    return(BoolLit.getInstance(b));
                }
                //car
                else if (argsName.Equals("car"))
                {
                    return(firstArgs.getCar());
                }
                //cdr
                else if (argsName.Equals("cdr"))
                {
                    return(firstArgs.getCdr());
                }
                //null?
                //b1?
                else if (argsName.Equals("null?") && b1)
                {
                    bool b = firstArgs.isNull();
                    return(BoolLit.getInstance(b));
                }
                //pair
                else if (argsName.Equals("pair?"))
                {
                    bool b = firstArgs.isPair();
                    return(BoolLit.getInstance(b));
                }
                //precedure
                else if (argsName.Equals("procedure?"))
                {
                    bool b = firstArgs.isProcedure();
                    return(BoolLit.getInstance(b));
                }
                //write
                else if (argsName.Equals("write"))
                {
                    firstArgs.print(0);
                    //return value unspecified
                    return(new StringLit(" "));
                }
                //display
                else if (argsName.Equals("display"))
                {
                    //temp change value
                    StringLit.quoted = false;
                    firstArgs.print(0);
                    //reset changed value
                    StringLit.quoted = true;
                    //return value unspecified
                    return(new StringLit(" "));
                }
            }
            else if (argsAmount == 2)
            {
                //eq?
                if (argsName.Equals("eq?"))
                {
                    bool bt1 = firstArgs.isSymbol();
                    bool bt2 = secondArgs.isSymbol();
                    if (bt1 && bt2)
                    {
                        bool bt3 = firstArgs.getName().Equals(secondArgs.getName());
                        return(BoolLit.getInstance(bt3));
                    }
                    else
                    {
                        bool bt4 = firstArgs == secondArgs;
                        return(BoolLit.getInstance(bt4));
                    }
                }
                //cons
                else if (argsName.Equals("cons"))
                {
                    return(new Cons(firstArgs, secondArgs));
                }
                //set-car!
                else if (argsName.Equals("set-car!"))
                {
                    firstArgs.setCar(secondArgs);
                    //return value unspecified
                    return(new StringLit(" "));
                }
                //set-cdr!
                else if (argsName.Equals("set-cdr!"))
                {
                    firstArgs.setCdr(secondArgs);
                    //return value unspecified
                    return(new StringLit(" "));
                }
                //eval
                else if (argsName.Equals("eval"))
                {
                    return(firstArgs.eval((Environment)secondArgs));
                }
                //apply
                else if (argsName.Equals("apply"))
                {
                    return(firstArgs.apply(secondArgs));
                }
                else
                {
                    return(Nil.getInstance());
                }

                //binary arithematic opecations tmp vars
                int bo1 = 0;
                int bo2 = 0;
                if (firstArgs.isNumber())
                {
                    bo1 = firstArgs.getValue();
                }
                else if (secondArgs.isNumber())
                {
                    bo2 = secondArgs.getValue();
                }
                else
                {
                    Console.Error.WriteLine("invalid arguemtent name given");
                    return(Nil.getInstance());
                }
                //b+
                if (argsName.Equals("b+"))
                {
                    return(new IntLit(bo1 + bo2));
                }
                //b-
                else if (argsName.Equals("b-"))
                {
                    return(new IntLit(bo1 - bo2));
                }
                //b*
                else if (argsName.Equals("b*"))
                {
                    return(new IntLit(bo1 * bo2));
                }
                //b/
                else if (argsName.Equals("b/"))
                {
                    return(new IntLit(bo1 / bo2));
                }
                //b=
                else if (argsName.Equals("b="))
                {
                    bool b = bo1 == bo2;
                    return(BoolLit.getInstance(b));
                }
                //b<
                else if (argsName.Equals("b<"))
                {
                    bool b = bo1 < bo2;
                    return(BoolLit.getInstance(b));
                }
                else
                {
                    Console.Error.WriteLine("Aritheatic Operation Error");
                    return(Nil.getInstance());
                }
            }
            //invalid argsName given
            else
            {
                Console.Error.WriteLine("invalid arguemtent name given");
                return(Nil.getInstance());
            }

            return(Nil.getInstance());
        }
Beispiel #22
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());
            }
        }