Beispiel #1
0
 public override Node eval(Node t, Environment e)
 {
     if(t.getCdr() is Closure)
         return e.lookup(t.getCar()).apply(t.getCdr());
     else
     {
         Node args = t.getCdr();
         Node param;
         if (args.getCar().isSymbol())
             param = new Cons(e.lookup((Node)args.GetCar()), Nil.getInstance());
         else
             param = new Cons((Node)args.GetCar(), Nil.getInstance());
         Node currentNode = param;
         args = args.getCdr();
         while (args != Nil.getInstance())
         {
             if (args.getCar().isSymbol())
                 currentNode.setCdr(new Cons(e.lookup(args.getCar()), Nil.getInstance()));
             else
                 currentNode.setCdr(new Cons(args.getCar(), Nil.getInstance()));
             currentNode = currentNode.getCdr();
             args = args.getCdr();
         }
         return e.lookup(t.getCar()).apply(param);
     }
 }
Beispiel #2
0
        public override Node eval(Node exp, Environment env)
        {
            int length = Util.expLength(exp);
            if (length < 3)
            {
                Console.Error.WriteLine("Error: invalid expression");
                return Nil.getInstance();
            }
            Node second = exp.getCdr().getCar();
            Node name, value;
            if (length == 3 && second.isSymbol())
            {
                name = second;
                value = exp.getCdr().getCdr().getCar().eval(env);
                env.define(name, value);
                return null;
            }
            if (!second.isPair())
            {
                Console.Error.WriteLine("Error: invalid expression");
                return Nil.getInstance();
            }
            name = second.getCar();
            Node lambda = exp.getCdr();
            lambda.setCar(second.getCdr());
            lambda = new Cons(new Ident("lambda"), lambda);
            value = lambda.eval(env);
            env.define(name, value);

            return null;
        }
Beispiel #3
0
        public Node evalLetBody(Node t, Environment env)
        {
            if(t == Nil.getInstance()) //This isn't correct. What do?
            {
                Node l = new Cons(new Nil(), new Nil()); //tree with pair of ()
                return l;
            }
            else
            {
                Node restBody = t.getCdr();
                Node variable = t.getCar().getCar();
                Node value = t.getCar().getCdr().getCar();

                if(variable.isSymbol()) //was value earlier, should be variable?
                {
                    env.define(variable,value.eval(env));
                    return evalLetBody(restBody, env);
                }
                else if(!variable.isPair()) //if it is a cons node. ???
                {
                    Console.Write("Error in Let->evalLetBody, variable is not valid");
                    return new Nil();

                }
                else if(variable.isNull())
                {
                    return new Nil();
                }
                else
                {
                    return variable.eval(env);
                }
            }
        }
Beispiel #4
0
 // TODO: The method apply() should be defined in class Node
 // to report an error.  It should be overridden only in classes
 // BuiltIn and Closure.
 public override Node apply(Node args)
 {
     Environment funcEnvironment = new Environment(env);
     Node param = fun.getCdr().getCar();
     while (param != Nil.getInstance() && args != Nil.getInstance())
     {
         funcEnvironment.define(param.getCar(), args.getCar());
         param = param.getCdr();
         args = args.getCdr();
     }
     Node body = new Cons(new Ident("begin"), fun.getCdr().getCdr());
     return body.eval(funcEnvironment);
 }
Beispiel #5
0
        public override Node eval(Environment env, Node args)
        {
            // Evaluate the list
            Node evaluated = new Cons(args.getCar().eval(env), args.getCdr().eval(env));

            // If the car is a closure, apply it
            if (evaluated.getCar().isProcedure())
            {
                return(evaluated.getCar().apply(evaluated.getCdr()));
            }
            else
            {
                return(evaluated);
            }
        }
Beispiel #6
0
        public override Node apply(Node args)
        {
            Environment funcEnv = new Environment(env);
            Node        temp    = fun.getCdr().getCar();

            while (temp != Nil.getInstance())
            {
                funcEnv.define(temp.getCar(), args.getCar());
                temp = temp.getCdr();
                args = args.getCdr();
            }
            Node body = new Cons(new Ident("begin"), fun.getCdr().getCdr());

            return(body.eval(funcEnv));
        }
Beispiel #7
0
        public void assign(Node id, Node val)
        {
            // search for id in id_value_pair in frame heirarchy
            Node result_lookup = lookup(id);

            // if nothing found, report error.
            if (result_lookup == null)
            {
                Console.Error.WriteLine("Exception in assigning: variable with that name does not exist");
            }
            else
            {
                result_lookup = new Cons(val, Nil.getInstance());
            }
        }
Beispiel #8
0
 public override Node eval(Node t, Environment env)
 {
     Node variable = t.getCdr().getCar();
     if(variable.isPair())
     {
         //variable is of the form (decl params...), ex: (foo x y)
         Node declaration = variable.getCar();
         Node parameters = variable.getCdr();
         Cons lambda = new Cons(new Ident("lambda"),new Cons(parameters,t.getCdr().getCdr().getCar()));
         env.define(declaration,new Closure(lambda, env));
     }
     else
     {
         env.define(variable, t.getCdr().getCdr().getCar().eval(env));
     }
     return new StringLit("definition recorded");
 }
Beispiel #9
0
        public override Node eval(Node t, Environment env)
        {
            Node car1 = t.getCdr().getCar();
            Node car2 = t.getCdr().getCdr().getCar();

            if (car1.isSymbol())
            {
                // if first arg is not a list, define variable
                env.define(car1, car2);
            }
            else
            {
                // if first arg is list, define function and function body
                Cons funcbody   = new Cons(car1.getCdr(), t.getCdr().getCdr());
                Node closureFun = new Cons(new Ident("lambda"), funcbody).eval(env);
                env.define(car1.getCar(), closureFun);
            }
            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();
            }

            if (numArgs < 2)
            {
                Console.Error.WriteLine("Error: invalid expression");
                return(Nil.getInstance());
            }
            Node arg1 = exp.getCdr().getCar();

            if (numArgs == 2 && arg1.isSymbol())
            {
                Node val = exp.getCdr().getCdr().getCar();
                env.define(arg1, val.eval(env));
                return(new StringLit("; no values returned", false));
            }
            if (arg1.isPair())
            {
                Node fName     = arg1.getCar();
                Node fArgs     = arg1.getCdr();
                Node fBody     = exp.getCdr().getCdr();
                bool validArgs = verifyArgs(fArgs);
                if (fName.isSymbol() && validArgs)
                {
                    Node node = new Cons(new Ident("lambda"), new Cons(fArgs, fBody));
                    env.define(fName, node.eval(env));
                    return(new StringLit("; no values returned", false));
                }
                Console.Error.WriteLine("Error: ill-formed definition");
                return(Nil.getInstance());
            }
            Console.Error.WriteLine("Error: invalid expression");
            return(Nil.getInstance());
        }
Beispiel #11
0
        public override Node eval(Environment env, Node args)
        {
            Node expr1 = args.getCar();

            if (args.getCdr().isNull() == true)
            {
                return(new StringLit("Error: Only 1 argument passed to 'define.'"));
            }
            else if (args.getCdr().getCdr().isNull() == false)
            {
                return(new StringLit("Error: Too many arguments passed to 'define.'"));
            }
            // Is this defining a function?
            else if (expr1.isPair() == true)
            {
                if (expr1.getCar().isSymbol() == true)
                {
                    // Construct the lambda expression
                    Node formalsAndBody = new Cons(expr1.getCdr(), args.getCdr());
                    Node lambdaExpr     = new Cons(new Ident("lambda"), formalsAndBody);
                    // define.apply()
                    return(env.define(expr1.getCar(), lambdaExpr.eval(env)));
                }
                else
                {
                    return(new StringLit("Error: First argument to 'define' must be a <variable>"));
                }
            }
            else
            {
                if (expr1.isSymbol() == true)
                {
                    // define.apply()
                    return(env.define(expr1, args.getCdr().getCar().eval(env)));
                }
                else
                {
                    return(new StringLit("Error: First argument to 'define' must be a <variable>"));
                }
            }
        }
Beispiel #12
0
        public Node evalRest(Node t, Environment env)
        {
            Node c;
            if(t == null)
            {
                c = new Cons(new Nil(), new Nil());
            }
            else
            {
                Node car = t.getCar();
                Node cdr = t.getCdr();
                if(car.isSymbol())
                {
                    car = env.lookup(car);
                }

                c = new Cons(car.eval(env), evalRest(cdr, env));
                return c;
            }
            return c;
        }
Beispiel #13
0
        public override Node eval(Node t, Environment env)
        {
            // if cdr is null, define call has no arguments (error state)
            if (t.getCdr() == Nil.getInstance())
            {
                Console.Error.WriteLine("Special form 'Define' evaluated with no arguments");
                return(Nil.getInstance());
            }

            // to evaluate an expression of the form '(eval x e)',
            // evaluate e, store its value as e1, then look up x in the current scope.
            // if a binding for x exists, set the value to e1
            // otherwise, add (x e1) as the first element of the first association
            // lists into env.

            t = t.getCdr();

            // determine if the form is '(eval x e)'
            if (t.getCar().isSymbol())
            {
                // evaluate e, then store into e1
                Node e1 = t.getCdr().eval(env);
                env.define(t.getCar(), e1);
            }

            // if the expression is of the form '(define (x p1 ... pn) b1 ... bm)',
            // construct the lambda expression
            // (lambda(p1...pn) b1...bm)
            // then proceed as for the definition
            // (define x(lambda(p1...pn) b1...bm))

            if (t.getCar().isPair())
            {
                Node arg1 = t.getCar().getCar();
                Cons arg2 = new Cons(new Ident("lambda"), new Cons(t.getCdr().getCar(), t.getCdr().getCar().getCdr()));
                env.define(arg1, arg2);
            }
            return(null);
        }
Beispiel #14
0
        public void define(Node id, Node val)
        {
            // it should be noted  that when parsing the written structure
            //   print elements,... if there is a left parenthesis in front
            //  in front of variable name, ... we are dealing with a function definition.
            //
            //  and the variable name ought to be considered an identifier.



            // function example  : where root cons node is given by: identifier
            // a   .

            // a equals  : (define (xoo x) (+ x x))

            // to get  expression for lambda out of any function defintion...

            // node funcLambda = (cons 'lambda (cons (cdr (car (cdr a))) (cdr (cdr a))))

            // xoo    can be looked up by querying:  (car (car (cdr a)))



            // we only want to define this in the frontmost frame at hand.
            Node result_lookup = find(id, frame.get_root_of_frame());

            if (result_lookup == null)
            {
                Cons node_being_added = new Cons(id, new Cons(val, Nil.getInstance()));
                // put new definition in front of frame ( association list structure )
                frame.set_root_car_node(node_being_added);
            }
            else
            // if preexisting...
            // update  node for value (,  in innermost scope).
            {
                result_lookup = new Cons(val, Nil.getInstance());
            }
        }
Beispiel #15
0
        // to evaluate expressions of the regular form '(f a1 ... an)',
        // i.e. function calls that don't fit under another Special
        // subclass, recursively evaluate f, a1, ... an, calling the
        // results f', a1', ... an', then call apply with f' as the
        // first argument, and (a1', ... an') as the second argument.
        public override Node eval(Node t, Environment env)
        {
            // get f' from t to use for apply call later.
            Node fPrime = t.getCar().eval(env);

            // create node for holding list (a1' ... an')
            Node aPrime = Nil.getInstance();

            // get cdr of regular (a1 ... an)
            t = t.getCdr();

            // recursively evaluate a1 ... a(n-1)
            while (t.getCdr() != Nil.getInstance())
            {
                aPrime = new Cons(aPrime, t.getCar().eval(env));
                t      = t.getCdr();
            }

            // evaluate an, add to list, and return a'
            aPrime = new Cons(aPrime, t.getCar().eval(env));
            return(fPrime.apply(aPrime));
        }
Beispiel #16
0
        public Node define(Node id, Node val)
        {
            Node oldVal = find(id, frame);

            if (oldVal != null)
            {
                // id exists in environment, update the value
                oldVal.setCar(val);
                return(new StringLit("no values returned."));
            }

            else
            {
                // Add the new frame to the environment (front of the association list)
                Node newFrame = new Cons(new Cons(id, new Cons(val, null)), null); // New variable for clarity

                newFrame.setCdr(frame);
                frame = newFrame;

                return(new StringLit("no values returned."));
            }
        }
Beispiel #17
0
        public override Node eval(Node t, Environment env)
        {
            Node iden = t.getCdr().getCar();
            Node val  = t.getCdr().getCdr().getCar();

            if (iden.isSymbol())
            {
                env.define(iden, val);
            }
            else
            {
                Closure close = new Closure(new Cons(t.getCdr().getCar().getCdr(), t.getCdr().getCdr()), env);
                env.define(iden.getCar(), close);
            }
            if (iden.isPair())
            {
                Node func = iden.getCar();

                Cons list = new Cons(new Ident("lambda"), new Cons(val, t.getCdr().getCar().getCdr()));
                env.define(func, list);
            }
            return(new StringLit("Values are null (Define)"));
        }
Beispiel #18
0
 public Node evalRegList(Node t, Environment env)
 {
     if (t == null || t.isNull())
     {
         Node list = new Cons(Nil.getInstance(), Nil.getInstance());
         return(list);
     }
     else
     {
         Node arg  = t.getCar();
         Node rest = t.getCdr();
         if (arg.isSymbol())
         {
             arg = env.lookup(arg);
         }
         if (arg == null || arg.isNull())
         {
             return(Nil.getInstance());
         }
         Node list = new Cons(arg.eval(env), evalRegList(rest, env));
         return(list);
     }
 }
Beispiel #19
0
        // sets first as function, args as function arguments, and performs apply() on first
        public override Node eval(Node t, Environment env)
        {
            Node first = t.getCar();
            Node args  = t.getCdr();

            if (!(args is Nil))
            {
                if (t.getCdr().getCar().isSymbol())
                {
                    args = getArgs(t.getCdr(), env);
                }
                if (t.getCdr().getCar().isPair() && !t.getCdr().getCar().getCar().isNumber())
                {
                    args = new Cons(t.getCdr().getCar().eval(env), Nil.getInstance());
                }
                if (env.lookup(first).isProcedure())
                {
                    first = env.lookup(first);
                    Node temp = first.apply(args);
                    return(temp);
                }
                else
                {
                    Console.WriteLine("Error: Procedure not specified.");
                }
            }
            else
            {
                if (env.lookup(first).isProcedure())
                {
                    first = env.lookup(first);
                    Node temp = first.apply(Nil.getInstance());
                    return(temp);
                }
            }
            return(Void.getInstance());
        }
Beispiel #20
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 #21
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());
            }
        }
Beispiel #22
0
 public void define(Node id, Node value)
 {
     Node a = new Cons(id, new Cons(value, Nil.getInstance()));
     this.frame = new Cons(a, this.frame);
 }
Beispiel #23
0
        public override Node eval(Node cons_expression, Environment env1)
        {
            bool it_is_variable_Identifier__notFunction = false;

            // check for null  in construct of (define elem1 elem2)...  and ends current method
            // test1 checks if there might even be elements in expression
            // test 2 checks if elem1 is a Identifier or not
            // test 3 checks if elem2 exists
            if (cons_expression.getCdr().isNull() || cons_expression.getCdr().getCar().isNull() ||
                cons_expression.getCdr().getCdr().isNull())
            {
                return(new StringLit("Error: lacking items to be defined in (define ...) ."));
            }


            // the key of a frame is represented by the alist.getCar().getCar().getName();

            // the val of a frame is represented by the alist.getCar().getCdr


            // check if thing being defined is a function ... or just a variable
            if (!cons_expression.getCdr().getCar().isPair())
            {
                it_is_variable_Identifier__notFunction = true;
            }
            else
            {
                it_is_variable_Identifier__notFunction = false;
            }



            if (it_is_variable_Identifier__notFunction)
            {
                if (cons_expression.getCdr().getCdr().getCar() == null)
                {
                    return(new StringLit("Error: node with value in definition is null. cannot define."));
                }

                Node place_of_Node_with_Value = cons_expression.getCdr().getCdr().getCar();

                if (place_of_Node_with_Value.isPair())
                {
                    // assign val to id variable
                    // this in fact might assign our variable to point to a function term   [indirectly.]
                    env1.define(cons_expression.getCdr().getCar(), place_of_Node_with_Value.eval(env1));

                    // finish here.
                    return(null);
                }
                else
                {
                    if (place_of_Node_with_Value.isSymbol())
                    {
                        Node lookedUp_val_term = env1.lookup(place_of_Node_with_Value);

                        // error ... value to be assigned is undefined.
                        if (lookedUp_val_term == null)
                        {
                            return(new StringLit("Error: value to be assigned is undefined expression."));
                        }
                        else
                        {
                            // assign val looked up , unto id variable
                            // this in fact might assign our variable to point to a function term   [indirectly.]
                            env1.define(cons_expression.getCdr().getCar(), lookedUp_val_term);
                        }
                    }
                    else
                    {
                        // assign val onto id variable
                        // this in fact might assign our variable to point to a function term   [indirectly.]
                        env1.define(cons_expression.getCdr().getCar(), place_of_Node_with_Value);
                    }

                    // finish here.
                    return(null);
                }
            }
            // work out storing function in environment

            else
            {
                // "function assignment";

                if (cons_expression.getCdr().getCar().getCdr().isNull() || cons_expression.getCdr().getCar().getCdr().isPair())
                {
                    // normal case without dot in parameters of express

                    // create a lambda of this definition of a function
                    // lambda node = (cons 'lambda (cons (cdr (car (cdr a))) (cdr (cdr a))))
                    Node lambda_function = new Cons(new Ident("lambda"), new Cons(cons_expression.getCdr().getCar().getCdr(),
                                                                                  cons_expression.getCdr().getCdr()));

                    Closure defined_closure = new Closure(lambda_function, env1);

                    env1.define(cons_expression.getCdr().getCar().getCar(), defined_closure);
                }
                else
                {
                    // particular spec case with a dot expression for parameters ... that ends the list without a nil

                    // create a lambda of this definition of a function
                    // lambda node = (cons 'lambda (cons (cdr (car (cdr a))) (cdr (cdr a))))
                    Node lambda_function = new Cons(new Ident("lambda"),
                                                    new Cons(

                                                        new Cons(cons_expression.getCdr().getCar().getCdr(), Nil.getInstance())

                                                        ,

                                                        cons_expression.getCdr().getCdr()));

                    Closure defined_closure = new Closure(lambda_function, env1);

                    env1.define(cons_expression.getCdr().getCar().getCar(), defined_closure);
                }
            }

            return(null);
        }
Beispiel #24
0
 private Node ConstructList(Hashtable dict)
 {
     Node values = new Node();
     foreach (object kvp in dict)
     {
         values = new Cons(values, new Cons(new Ident((string) kvp), (Node)dict[kvp]));
     }
     return values;
 }
Beispiel #25
0
        public void define(Node id, Node val)
        {
            var newFrame = new Cons(id, new Cons(val, Nil.getInstance()));

            frame = new Cons(newFrame, frame);
        }
Beispiel #26
0
 public void define(Node id, Node val)
 {
     Node definition = find(id, frame);
     if (definition != null)
     {
         definition.setCar(val);
     }
     else
     {
         Node frame = new Cons(id, new Cons(val, Nil.getInstance()));
         this.frame = new Cons(frame, this.frame);
     }
 }
Beispiel #27
0
 public void define(Node id, Node val)
 {
     Node pair = new Cons(id, new Cons(val, Nil.getInstance()));
     frame = new Cons(pair, frame);
 }
        // 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)
        {
            if (args == null)
            {
                return(null);
            }

            String name = symbol.getName();
            Node   car  = args.getCar();

            if (car == null || car.isNull())
            {
                car = Nil.getInstance();
            }
            Node cdr = args.getCdr();

            if (cdr == null || cdr.isNull())
            {
                cdr = Nil.getInstance();
            }
            else
            {
                cdr = cdr.getCar();
            }

            if (name.equals("b+"))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new IntLit(car.getVal() + cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b+");
                    return(new StringLit(""));
                }
            }
            else if (name.equals("b-"))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new IntLit(car.getVal() - cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b-");
                    return(new StringLit(""));
                }
            }
            else if (name.equals("b*"))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new IntLit(car.getVal() * cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b*");
                    return(new StringLit(""));
                }
            }
            else if (name.equals("b/"))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new IntLit(car.getVal() / cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b/");
                    return(new StringLit(""));
                }
            }
            else if (name.equals("b="))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new BoolLit(car.getVal() == cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b=");
                }
            }
            else if (name.equals("b>"))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new BoolLit(car.getVal() > cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b>");
                }
            }
            else if (name.equals("b<"))
            {
                if (car.isNumber() && cdr.isNumber())
                {
                    return(new BoolLit(car.getVal() < cdr.getVal()));
                }
                else
                {
                    Console.Error.WriteLine("Invalid arguments for b<");
                }
            }
            else if (name.equals("car"))
            {
                if (car.isNull())
                {
                    return(car);
                }
                return(car.getCar());
            }
            else if (name.equals("cdr"))
            {
                if (car.isNull())
                {
                    return(cdr);
                }
                return(cdr.getCdr());
            }
            else if (name.equals("cons"))
            {
                return(new Cons(car, cdr));
            }
            else if (name.equals("set-cdr!"))
            {
                car.setCdr(cdr);
                return(car);
            }
            else if (name.equals("set-car!"))
            {
                car.setCar(cdr);
                return(car);
            }
            else if (name.equals("symbol?"))
            {
                return(new BoolLit(car.isSymbol()));
            }
            else if (name.equals("number?"))
            {
                return(new BoolLit(car.isNumber()));
            }
            else if (name.equals("null?"))
            {
                return(new BoolLit(car.isNull()));
            }
            else if (name.equals("pair?"))
            {
                return(new BoolLit(car.isPair()));
            }
            else if (name.equals("eq?"))
            {
                if (car.isBoolean() && cdr.isBoolean())
                {
                    return(new BoolLit(car.getBoolean() == cdr.getBoolean()));
                }
                else if (car.isNumber && cdr.isNumber())
                {
                    return(new BoolLit(car.getVal() == cdr.getVal()));
                }
                else if (car.isString() && cdr.isString())
                {
                    return(new BoolLit(car.getStringVal().equals(cdr.getStringVal())));
                }
                else if (car.isSymbol() && cdr.isSymbol)
                {
                    return(new BoolLit(car.getName().equals(cdr.getName())));
                }
                else if (car.isNull() && cdr.isNull())
                {
                    return(new BoolLit(true));
                }
                else if (car.isPair() && cdr.isPair())
                {
                    Node opener = new Cons(car.getCar(), new Cons(cdr.getCar(), Nil.getInstance()));
                    Node closer = new Cons(car.getCdr(), new Cons(cdr.getCdr(), Nil.getInstance()));
                    return(new BoolLit(apply(opener).getBoolean() && apply(closer.getBoolean())));
                }
                return(new BoolLit(false));
            }
            else if (name.equals("procedure?"))
            {
                return(new BoolLit(car.isProcedure()));
            }
            else if (name.equals("display"))
            {
                return(car);
            }
            else if (name.equals("newline"))
            {
                return(new StringLit("", false));
            }
            else if (name.equals("exit") || name.equals("quit"))
            {
                return(0);
            }
            else if (name.equals("write"))
            {
                car.print(0);
                return(new StringLit(""));
            }
            else if (name.equals("eval"))
            {
                return(car);
            }
            else if (name.equals("apply"))
            {
                return car.apply(cdr)
            }
            else if (name.equals("read"))
            {
                Parser isParsingMeOff = new Parser(new Scanner(Console.in));

                return(isParsingMeOff.parseExp());
            }
            else
            {
                car.print(0);
                return(Nil.getInstance());
            }
            return(new StringLit(">"));
        }
Beispiel #29
0
 private Node apply2(Node arg1, Node arg2)
 {
     string name = this.symbol.getName();
     bool flag = name.Equals("eq?");
     Node result;
     if (flag)
     {
         bool flag2 = arg1.isSymbol() && arg2.isSymbol();
         if (flag2)
         {
             string name2 = arg1.getName();
             string name3 = arg2.getName();
             result = BoolLit.getInstance(name2.Equals(name3));
         }
         else
         {
             result = BoolLit.getInstance(arg1 == arg2);
         }
     }
     else
     {
         bool flag3 = name.Equals("cons");
         if (flag3)
         {
             result = new Cons(arg1, arg2);
         }
         else
         {
             bool flag4 = name.Equals("set-car!");
             if (flag4)
             {
                 arg1.setCar(arg2);
                 result = Unspecific.getInstance();
             }
             else
             {
                 bool flag5 = name.Equals("set-cdr!");
                 if (flag5)
                 {
                     arg1.setCdr(arg2);
                     result = Unspecific.getInstance();
                 }
                 else
                 {
                     bool flag6 = name.Equals("eval");
                     if (flag6)
                     {
                         bool flag7 = arg2.isEnvironment();
                         if (flag7)
                         {
                             result = arg1.eval((Environment)arg2);
                         }
                         else
                         {
                             Console.Error.WriteLine("Error: wrong type of argument");
                             result = Nil.getInstance();
                         }
                     }
                     else
                     {
                         bool flag8 = name.Equals("apply");
                         if (flag8)
                         {
                             result = arg1.apply(arg2);
                         }
                         else
                         {
                             bool flag9 = name[0] == 'b' && name.Length == 2;
                             if (flag9)
                             {
                                 bool flag10 = arg1.isNumber() && arg2.isNumber();
                                 if (flag10)
                                 {
                                     result = this.apply2(arg1.getIntVal(), arg2.getIntVal());
                                 }
                                 else
                                 {
                                     Console.Error.WriteLine("Error: invalid arguments");
                                     result = Nil.getInstance();
                                 }
                             }
                             else
                             {
                                 Console.Error.WriteLine("Error: wrong number of arguments");
                                 result = Nil.getInstance();
                             }
                         }
                     }
                 }
             }
         }
     }
     return result;
 }
Beispiel #30
0
        public override Node eval(Node node1, Environment env1)
        {
            // set up environment for scope of this let body
            Environment current_env_of_let = new Environment(env1);

            bool need_to_make_bindings = true;

            // this will hold the list of evaluated arguments cumulatively.
            // dummy value to start with
            Cons evaluated_argsList__in_progress = new Cons(new IntLit(1), Nil.getInstance());

            // check if there are items to assign to environment...
            // and
            // check if there is an body item for evaluation of let.
            if (node1.getCdr() != null && node1.getCdr().isPair()

                && node1.getCdr().getCar() != null

                && node1.getCdr().getCdr() != null

                && node1.getCdr().getCdr().isPair())
            {
                // Make a list of values to be bound to keys given...

                // __list_of_terms
                Node current_lead_binding_node = node1.getCdr().getCar();

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

                // assign a dummy value
                Cons current_fringe_of_argList = new Cons(new IntLit(1), Nil.getInstance());

                bool has_more_bindings_in_list = true;

                // this is the case that there are no items to be associated in Frame.
                if (current_lead_binding_node.isNull() || !current_lead_binding_node.isPair())
                {
                    has_more_bindings_in_list = false;
                    // now it is not necessary to bind anything
                    need_to_make_bindings = false;
                }

                bool first_run = true;

                while (has_more_bindings_in_list)
                {
                    if (current_lead_binding_node == null)
                    {
                        Console.WriteLine("Error: in Let, one of items in terms being bound has null lead node.");
                        return(Nil.getInstance());
                    }

                    //stopping criteria
                    if (current_lead_binding_node.isNull())
                    {
                        has_more_bindings_in_list = false;
                        break;
                    }

                    // get values if otherwise
                    if (current_lead_binding_node.isPair())
                    {
                        Node current_key_value_pair_item = current_lead_binding_node.getCar();


                        // check if this term is null or empty list

                        if (current_key_value_pair_item == null || current_key_value_pair_item.isNull())
                        {
                            Console.WriteLine("Error: in Let, one of key value pairs is either null    or an empty list , nil.");
                            return(Nil.getInstance());
                        }
                        // check if this term is not a pair
                        if (!current_key_value_pair_item.isPair())
                        {
                            Console.WriteLine("Error: in Let, one of key value pairs is not a key value pair cons node.");
                            return(Nil.getInstance());
                        }

                        // get evaluated value here
                        Node node_to_add;


                        if (current_key_value_pair_item.getCdr() != null &&

                            !current_key_value_pair_item.getCdr().isNull() &&

                            current_key_value_pair_item.getCdr().isPair())
                        {
                            // first check if there is the right number of value, namely just one

                            if (current_key_value_pair_item.getCdr().getCdr() == null ||
                                !current_key_value_pair_item.getCdr().getCdr().isNull())
                            {
                                Console.WriteLine("Error: in let function call,... one of key value pairs has more than one value or a null for a tail.");
                                return(Nil.getInstance());
                            }


                            // check if item holding value is an expression that needs to be evaluated
                            if (current_key_value_pair_item.getCdr().getCar() != null &&
                                current_key_value_pair_item.getCdr().getCar().isPair())
                            {
                                // build new environment for this to be computed for.
                                Environment envExtend = new Environment(current_env_of_let);

                                node_to_add = current_key_value_pair_item.getCdr().getCar().eval(envExtend);
                            }
                            // lookup value from symbol in next case...

                            else if (current_key_value_pair_item.getCdr().getCar() != null &&

                                     !current_key_value_pair_item.getCdr().getCar().isNull() &&

                                     current_key_value_pair_item.getCdr().getCar().isSymbol())
                            {
                                node_to_add = current_env_of_let.lookup(current_key_value_pair_item.getCdr().getCar());

                                if (node_to_add == null)
                                {
                                    Console.WriteLine("Error: one of values being bound in let  is undefined in lookup, and thus null.");
                                    return(Nil.getInstance());
                                }
                                // case where value is not an expression or a symbol, but only a literal
                            }
                            else if (current_key_value_pair_item.getCdr().getCar() != null)
                            {
                                node_to_add = current_key_value_pair_item.getCdr().getCar();
                            }
                            else
                            {
                                Console.WriteLine("Error: one of values being bound in let  is null.");
                                return(Nil.getInstance());
                            }
                        }
                        else
                        {
                            Console.WriteLine("Error: in Let, one of items that should represent value, in a key value pair, is null or holds no value.");
                            return(Nil.getInstance());
                        }

                        // add latest value of key value pairs  to cumulative list of values
                        if (first_run)
                        {
                            evaluated_argsList__in_progress = new Cons(node_to_add, Nil.getInstance());

                            current_fringe_of_argList = evaluated_argsList__in_progress;
                            first_run = false;
                        }
                        else
                        {
                            current_fringe_of_argList.setCdr(new Cons(node_to_add, Nil.getInstance()));

                            current_fringe_of_argList = (Cons)current_fringe_of_argList.getCdr();
                        }

                        // increment to next fringe key value pair item...
                        current_lead_binding_node = current_lead_binding_node.getCdr();
                    }
                    else
                    {
                        Console.WriteLine("Error: in Let, one of bindings does not have cons format.");
                        return(Nil.getInstance());
                    }
                }
            }
            else
            {
                Console.WriteLine("Error: In let expression, ... either not enought arguments given , or null node encountered.");
                return(Nil.getInstance());
            }


            if (need_to_make_bindings)
            {
                // bind each variable in key value pair


                // current pair of all terms being binding
                Node current_binding_node = node1.getCdr().getCar();

                // current fring of value list
                Node current_fringe_of_list_of_values = evaluated_argsList__in_progress;

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

                bool more_key_val_pairs_to_bind = true;


                while (more_key_val_pairs_to_bind)
                {
                    if (current_binding_node == null)
                    {
                        Console.WriteLine("Error: one of key value pairs lead node is null");
                        return(Nil.getInstance());
                    }

                    if (current_binding_node.isNull())
                    {
                        more_key_val_pairs_to_bind = false;
                        break;
                    }

                    if (current_binding_node.isPair())
                    {
                        if (current_binding_node.getCar() == null || current_binding_node.getCar().isNull())
                        {
                            Console.WriteLine("Error: in Let, one of key value pairs is either null    or an empty list , nil.");
                            return(Nil.getInstance());
                        }
                        else if (!current_binding_node.getCar().isPair())
                        {
                            Console.WriteLine("Error: in Let, one of bindings does not have cons format.");
                            return(Nil.getInstance());
                            // go into binding association list
                        }
                        else if (current_binding_node.getCar().isPair())
                        {
                            if (current_binding_node.getCar().getCar() == null)
                            {
                                Console.WriteLine("Error: in Let, one of key/symbol fields is null.");
                                return(Nil.getInstance());
                            }
                            // check if this key is actually an identifier.
                            else if (current_binding_node.getCar().getCar().isSymbol())
                            {
                                current_env_of_let.define(current_binding_node.getCar().getCar(), current_fringe_of_list_of_values.getCar());

                                current_fringe_of_list_of_values = current_fringe_of_list_of_values.getCdr();

                                current_binding_node = current_binding_node.getCdr();
                            }
                            else
                            {
                                Console.WriteLine("Error: in Let, one of keys is not an identifier.");
                                return(Nil.getInstance());
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error: in Let, pair field outer group does not have cons format.");
                        return(Nil.getInstance());
                    }
                }
            }


            // jump ahead to body function expression of let.



            Node current_locale_of_body = node1.getCdr().getCdr();


            if (current_locale_of_body == null)
            {
                Console.WriteLine("Error: Let's  body is Null");

                return(Nil.getInstance());
            }
            // then check if the nil at list end      without having anything fulfilled.
            // also check to rule out there not being a child  a cons node.
            else if (current_locale_of_body.isNull() || !current_locale_of_body.isPair())
            {
                Console.WriteLine("Error: no arguments for evaluating in Begin statement .");

                return(Nil.getInstance());
            }
            // start loop that flips through elements until we get at the last destination expression.
            else
            {
                // initialize the item that may be returned.
                Node returnItem;

                // set a conditional and (on hold prospect)  return element.
                if (current_locale_of_body.getCar() == null)
                {
                    Console.WriteLine("Error: one of expressions in begin's arguments null .");

                    return(Nil.getInstance());
                }
                else
                {
                    returnItem = current_locale_of_body.getCar().eval(current_env_of_let);
                }
                bool hasAdditionalExp = false;

                Node one_further_outExtending_tail = current_locale_of_body.getCdr();

                // set one item extra in store of members of set of further tail items...
                // if it is something to start a third part in a chain of further tail cycle.
                // & nil term test
                if (one_further_outExtending_tail != null && !one_further_outExtending_tail.isNull())
                {
                    if (!one_further_outExtending_tail.isPair())
                    {
                        Console.WriteLine("Error: one of tail expressions is not in correct pair procession .");

                        return(Nil.getInstance());
                    }
                    else if (one_further_outExtending_tail.getCar() == null)
                    {
                        Console.WriteLine("Error: one of expressions in begin's arguments null .");

                        return(Nil.getInstance());
                    }
                    else
                    {
                        // set a conditional and (on hold prospect)  return element.
                        returnItem       = one_further_outExtending_tail.getCar().eval(current_env_of_let);
                        hasAdditionalExp = true;
                    }
                }
                // terminates with current return item.   // because cant go further in chain for begin expression chain
                else if (one_further_outExtending_tail != null && one_further_outExtending_tail.isNull())
                {
                    hasAdditionalExp = false;
                    // end
                    return(returnItem);
                }
                else                                                            // ends here with error
                {
                    Console.WriteLine("Error: Null encountered further on in Begin's  expressions.");

                    return(Nil.getInstance());
                }

                // loops over each expression leading up to last.
                while (hasAdditionalExp)
                {
                    // set end now.
                    if (one_further_outExtending_tail.getCdr() != null && one_further_outExtending_tail.getCdr().isNull())
                    {
                        //end
                        hasAdditionalExp = false;
                    }
                    // go to next in sequence of cdr's
                    else if (one_further_outExtending_tail.getCdr() != null &&
                             !one_further_outExtending_tail.getCdr().isNull())
                    {
                        if (!one_further_outExtending_tail.getCdr().isPair())
                        {
                            Console.WriteLine("Error: one of expressions is not in correct pair procession .");

                            return(Nil.getInstance());
                        }
                        else if (one_further_outExtending_tail.getCdr().getCar() == null)
                        {
                            Console.WriteLine("Error: one of expressions in begin's arguments null .");

                            return(Nil.getInstance());
                        }
                        else
                        {
                            // set a conditional and (on hold prospect)  return element.
                            returnItem = one_further_outExtending_tail.getCdr().getCar().eval(current_env_of_let);

                            hasAdditionalExp = true;
                            // increment to next in sequence of cdr's
                            one_further_outExtending_tail = one_further_outExtending_tail.getCdr();
                        }
                    }
                    else                                                                        // ends here with error
                    {
                        Console.WriteLine("Error: Null encountered further on in Begin's  expressions.");

                        return(Nil.getInstance());
                    }
                }                 // while loop ended

                return(returnItem);
            }
        }