Started changing car/cdr to first/rest, modified acceptance test fixture
This commit is contained in:
		
							parent
							
								
									496f30cded
								
							
						
					
					
						commit
						0855789fde
					
				@ -29,20 +29,13 @@ public class LispInterpreterFixture {
 | 
				
			|||||||
        return builder.build();
 | 
					        return builder.build();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void input(String input) throws IOException {
 | 
					    public String evaluate(String input) throws IOException {
 | 
				
			||||||
        environment.setInput(new ByteArrayInputStream(input.getBytes()));
 | 
					        environment.setInput(new ByteArrayInputStream(input.getBytes()));
 | 
				
			||||||
        interpreter.interpret();
 | 
					        interpreter.interpret();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String output() {
 | 
					 | 
				
			||||||
        String output = outputStream.toString();
 | 
					        String output = outputStream.toString();
 | 
				
			||||||
        discardOutput();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return output;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void discardOutput() {
 | 
					 | 
				
			||||||
        outputStream.reset();
 | 
					        outputStream.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return output.trim();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										7
									
								
								fitnesse/FitNesseRoot/LispInterpreter/Closure.wiki
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								fitnesse/FitNesseRoot/LispInterpreter/Closure.wiki
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					Test
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					| script           | lisp interpreter fixture                |
 | 
				
			||||||
 | 
					| evaluate         | (defun adderx (x) (lambda (y) (+ x y))) |
 | 
				
			||||||
 | 
					| evaluate         | (setf adder20 (adderx 20))              |
 | 
				
			||||||
 | 
					| check | evaluate | (funcall adder20 2)                     | 22 |
 | 
				
			||||||
@ -1,9 +0,0 @@
 | 
				
			|||||||
| script         | lisp interpreter fixture                |
 | 
					 | 
				
			||||||
| input          | (defun adderx (x) (lambda (y) (+ x y))) |
 | 
					 | 
				
			||||||
| discard output |
 | 
					 | 
				
			||||||
| input          | (setf adder20 (adderx 20))              |
 | 
					 | 
				
			||||||
| discard output |
 | 
					 | 
				
			||||||
| input          | (funcall adder20 2)                     |
 | 
					 | 
				
			||||||
| check          | output                             |!-22
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-!|
 | 
					 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
 | 
					|LispInterpreter.TestOne||09:26:08 Fri, Feb 24, 2017|
 | 
				
			||||||
|LispInterpreter.SuiteSetUp||14:27:52 Wed, Feb 22, 2017|
 | 
					|LispInterpreter.SuiteSetUp||14:27:52 Wed, Feb 22, 2017|
 | 
				
			||||||
|LispInterpreter.TestOne||14:27:42 Wed, Feb 22, 2017|
 | 
					 | 
				
			||||||
|LispInterpreter||14:24:41 Wed, Feb 22, 2017|
 | 
					|LispInterpreter||14:24:41 Wed, Feb 22, 2017|
 | 
				
			||||||
|FrontPage||14:15:03 Wed, Feb 22, 2017|
 | 
					|FrontPage||14:15:03 Wed, Feb 22, 2017|
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
package function;
 | 
					package function;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static function.builtin.cons.LENGTH.getLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.math.BigInteger;
 | 
					import java.math.BigInteger;
 | 
				
			||||||
import java.text.MessageFormat;
 | 
					import java.text.MessageFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import error.LispException;
 | 
					import error.LispException;
 | 
				
			||||||
import function.builtin.cons.LENGTH;
 | 
					 | 
				
			||||||
import sexpression.*;
 | 
					import sexpression.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ArgumentValidator {
 | 
					public class ArgumentValidator {
 | 
				
			||||||
@ -62,9 +63,9 @@ public class ArgumentValidator {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void validateListNotDotted(Cons argumentList) {
 | 
					    private void validateListNotDotted(Cons argumentList) {
 | 
				
			||||||
        SExpression next = argumentList.getCdr();
 | 
					        SExpression next = argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (Cons current = argumentList; next.consp(); next = current.getCdr())
 | 
					        for (Cons current = argumentList; next.consp(); next = current.getRest())
 | 
				
			||||||
            current = (Cons) next;
 | 
					            current = (Cons) next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!next.nullp())
 | 
					        if (!next.nullp())
 | 
				
			||||||
@ -79,13 +80,27 @@ public class ArgumentValidator {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean containsTooFewArguments(Cons argumentList) {
 | 
					    private boolean containsTooFewArguments(Cons argumentList) {
 | 
				
			||||||
        return (minimumNumberOfArguments != null)
 | 
					        return isMinimum() && isLengthLessThanMinimum(argumentList);
 | 
				
			||||||
               && (LENGTH.getLength(argumentList).compareTo(minimumNumberOfArguments) < 0);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private boolean isMinimum() {
 | 
				
			||||||
 | 
					        return minimumNumberOfArguments != null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private boolean isLengthLessThanMinimum(Cons argumentList) {
 | 
				
			||||||
 | 
					        return getLength(argumentList).compareTo(minimumNumberOfArguments) < 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean containsTooManyArguments(Cons argumentList) {
 | 
					    private boolean containsTooManyArguments(Cons argumentList) {
 | 
				
			||||||
        return (maximumNumberOfArguments != null)
 | 
					        return isMaximum() && isLengthGreaterThanMaximum(argumentList);
 | 
				
			||||||
               && (LENGTH.getLength(argumentList).compareTo(maximumNumberOfArguments) > 0);
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private boolean isMaximum() {
 | 
				
			||||||
 | 
					        return maximumNumberOfArguments != null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private boolean isLengthGreaterThanMaximum(Cons argumentList) {
 | 
				
			||||||
 | 
					        return getLength(argumentList).compareTo(maximumNumberOfArguments) > 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void validateArgumentTypes(Cons argumentList) {
 | 
					    private void validateArgumentTypes(Cons argumentList) {
 | 
				
			||||||
@ -95,11 +110,11 @@ public class ArgumentValidator {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private void validateFirstArgument(Cons argumentList) {
 | 
					    private void validateFirstArgument(Cons argumentList) {
 | 
				
			||||||
        if (!isFirstArgumentValid(argumentList))
 | 
					        if (!isFirstArgumentValid(argumentList))
 | 
				
			||||||
            throw new BadArgumentTypeException(functionName, argumentList.getCar(), firstArgumentType);
 | 
					            throw new BadArgumentTypeException(functionName, argumentList.getFirst(), firstArgumentType);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean isFirstArgumentValid(Cons argumentList) {
 | 
					    private boolean isFirstArgumentValid(Cons argumentList) {
 | 
				
			||||||
        return argumentList.nullp() || isExpectedFirstArgumentType(argumentList.getCar());
 | 
					        return argumentList.nullp() || isExpectedFirstArgumentType(argumentList.getFirst());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean isExpectedFirstArgumentType(SExpression firstArgument) {
 | 
					    private boolean isExpectedFirstArgumentType(SExpression firstArgument) {
 | 
				
			||||||
@ -111,9 +126,9 @@ public class ArgumentValidator {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void validateTrailingArguments(Cons argumentList) {
 | 
					    private void validateTrailingArguments(Cons argumentList) {
 | 
				
			||||||
        for (Cons cons = (Cons) argumentList.getCdr(); !cons.nullp(); cons = (Cons) cons.getCdr())
 | 
					        for (Cons cons = (Cons) argumentList.getRest(); !cons.nullp(); cons = (Cons) cons.getRest())
 | 
				
			||||||
            if (!isExpectedTrailingArgumentType(cons.getCar()))
 | 
					            if (!isExpectedTrailingArgumentType(cons.getFirst()))
 | 
				
			||||||
                throw new BadArgumentTypeException(functionName, cons.getCar(), trailingArgumentType);
 | 
					                throw new BadArgumentTypeException(functionName, cons.getFirst(), trailingArgumentType);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean isExpectedTrailingArgumentType(SExpression trailingArgument) {
 | 
					    private boolean isExpectedTrailingArgumentType(SExpression trailingArgument) {
 | 
				
			||||||
 | 
				
			|||||||
@ -24,8 +24,8 @@ public class UserDefinedFunction extends LispFunction {
 | 
				
			|||||||
        this.executionContext = ExecutionContext.getInstance();
 | 
					        this.executionContext = ExecutionContext.getInstance();
 | 
				
			||||||
        this.functionScope = executionContext.getScope();
 | 
					        this.functionScope = executionContext.getScope();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getCdr())
 | 
					        for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getRest())
 | 
				
			||||||
            this.formalParameters.add(lambdaList.getCar().toString());
 | 
					            this.formalParameters.add(lambdaList.getFirst().toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.argumentValidator = new ArgumentValidator(this.name);
 | 
					        this.argumentValidator = new ArgumentValidator(this.name);
 | 
				
			||||||
        this.argumentValidator.setExactNumberOfArguments(this.formalParameters.size());
 | 
					        this.argumentValidator.setExactNumberOfArguments(this.formalParameters.size());
 | 
				
			||||||
@ -40,8 +40,8 @@ public class UserDefinedFunction extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        SExpression lastEvaluation = Nil.getInstance();
 | 
					        SExpression lastEvaluation = Nil.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (Cons expression = body; expression.consp(); expression = (Cons) expression.getCdr())
 | 
					        for (Cons expression = body; expression.consp(); expression = (Cons) expression.getRest())
 | 
				
			||||||
            lastEvaluation = eval(expression.getCar());
 | 
					            lastEvaluation = eval(expression.getFirst());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        executionContext.setScope(callingScope);
 | 
					        executionContext.setScope(callingScope);
 | 
				
			||||||
        releaseParameterValues();
 | 
					        releaseParameterValues();
 | 
				
			||||||
@ -53,9 +53,9 @@ public class UserDefinedFunction extends LispFunction {
 | 
				
			|||||||
        functionScope = new SymbolTable(functionScope);
 | 
					        functionScope = new SymbolTable(functionScope);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (String parameter : formalParameters) {
 | 
					        for (String parameter : formalParameters) {
 | 
				
			||||||
            SExpression currentArg = argumentList.getCar();
 | 
					            SExpression currentArg = argumentList.getFirst();
 | 
				
			||||||
            functionScope.put(parameter, currentArg);
 | 
					            functionScope.put(parameter, currentArg);
 | 
				
			||||||
            argumentList = (Cons) argumentList.getCdr();
 | 
					            argumentList = (Cons) argumentList.getRest();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -20,9 +20,9 @@ public class APPLY extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons cdr = (Cons) argumentList.getCdr();
 | 
					        Cons cdr = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression functionName = argumentList.getCar();
 | 
					        SExpression functionName = argumentList.getFirst();
 | 
				
			||||||
        SExpression functionArguments = cdr.getCar();
 | 
					        SExpression functionArguments = cdr.getFirst();
 | 
				
			||||||
        LispFunction function = EVAL.lookupFunctionOrLambda(functionName);
 | 
					        LispFunction function = EVAL.lookupFunctionOrLambda(functionName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return function.call((Cons) functionArguments);
 | 
					        return function.call((Cons) functionArguments);
 | 
				
			||||||
 | 
				
			|||||||
@ -57,7 +57,7 @@ public class EVAL extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression argument = argumentList.getCar();
 | 
					        SExpression argument = argumentList.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (argument.listp()) {
 | 
					        if (argument.listp()) {
 | 
				
			||||||
            if (argument.consp())
 | 
					            if (argument.consp())
 | 
				
			||||||
@ -79,8 +79,8 @@ public class EVAL extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression evaluateList(Cons list) {
 | 
					    private SExpression evaluateList(Cons list) {
 | 
				
			||||||
        SExpression functionName = list.getCar();
 | 
					        SExpression functionName = list.getFirst();
 | 
				
			||||||
        SExpression arguments = list.getCdr();
 | 
					        SExpression arguments = list.getRest();
 | 
				
			||||||
        LispFunction function = lookupFunctionOrLambda(functionName);
 | 
					        LispFunction function = lookupFunctionOrLambda(functionName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ArgumentValidator functionListValidator = new ArgumentValidator(functionName.toString());
 | 
					        ArgumentValidator functionListValidator = new ArgumentValidator(functionName.toString());
 | 
				
			||||||
@ -98,8 +98,8 @@ public class EVAL extends LispFunction {
 | 
				
			|||||||
        if (arguments.nullp())
 | 
					        if (arguments.nullp())
 | 
				
			||||||
            return Nil.getInstance();
 | 
					            return Nil.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression car = eval(arguments.getCar());
 | 
					        SExpression car = eval(arguments.getFirst());
 | 
				
			||||||
        SExpression cdr = arguments.getCdr();
 | 
					        SExpression cdr = arguments.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new Cons(car, evaluateArgList((Cons) cdr));
 | 
					        return new Cons(car, evaluateArgList((Cons) cdr));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
package function.builtin;
 | 
					package function.builtin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static function.builtin.APPLY.apply;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import function.*;
 | 
					import function.*;
 | 
				
			||||||
import function.builtin.cons.LIST;
 | 
					import function.builtin.cons.LIST;
 | 
				
			||||||
import sexpression.*;
 | 
					import sexpression.*;
 | 
				
			||||||
@ -15,9 +17,9 @@ public class FUNCALL extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        Cons applyArgs = new Cons(argumentList.getCar(), LIST.makeList(argumentList.getCdr()));
 | 
					        Cons applyArgs = new Cons(argumentList.getFirst(), LIST.makeList(argumentList.getRest()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return APPLY.apply(applyArgs);
 | 
					        return apply(applyArgs);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ public class LOAD extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        LispString quotedName = (LispString) argumentList.getCar();
 | 
					        LispString quotedName = (LispString) argumentList.getFirst();
 | 
				
			||||||
        String fileName = removeSurroundingQuotes(quotedName.toString());
 | 
					        String fileName = removeSurroundingQuotes(quotedName.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return processFile(fileName);
 | 
					        return processFile(fileName);
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,7 @@ public class PRINT extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        SExpression argument = argumentList.getCar();
 | 
					        SExpression argument = argumentList.getFirst();
 | 
				
			||||||
        environment.getOutput().println(argument);
 | 
					        environment.getOutput().println(argument);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argument;
 | 
					        return argument;
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ public class SYMBOL_FUNCTION extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression symbol = argumentList.getCar();
 | 
					        SExpression symbol = argumentList.getFirst();
 | 
				
			||||||
        LispFunction function = FunctionTable.lookupFunction(symbol.toString());
 | 
					        LispFunction function = FunctionTable.lookupFunction(symbol.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (function != null) {
 | 
					        if (function != null) {
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,9 @@ public class CAR extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        Cons argument = (Cons) argumentList.getCar();
 | 
					        Cons argument = (Cons) argumentList.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argument.getCar();
 | 
					        return argument.getFirst();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,9 @@ public class CDR extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        Cons argument = (Cons) argumentList.getCar();
 | 
					        Cons argument = (Cons) argumentList.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argument.getCdr();
 | 
					        return argument.getRest();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,9 @@ public class CONS extends LispFunction {
 | 
				
			|||||||
    public Cons call(Cons argumentList) {
 | 
					    public Cons call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons cdr = (Cons) argumentList.getCdr();
 | 
					        Cons cdr = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        SExpression secondArgument = cdr.getCar();
 | 
					        SExpression secondArgument = cdr.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new Cons(firstArgument, secondArgument);
 | 
					        return new Cons(firstArgument, secondArgument);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -33,8 +33,8 @@ public class LENGTH extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private LispNumber callTailRecursive(BigInteger accumulatedLength, Cons argumentList) {
 | 
					    private LispNumber callTailRecursive(BigInteger accumulatedLength, Cons argumentList) {
 | 
				
			||||||
        Cons list = (Cons) argumentList.getCar();
 | 
					        Cons list = (Cons) argumentList.getFirst();
 | 
				
			||||||
        Cons restOfList = LIST.makeList(list.getCdr());
 | 
					        Cons restOfList = LIST.makeList(list.getRest());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (list.nullp())
 | 
					        if (list.nullp())
 | 
				
			||||||
            return new LispNumber(accumulatedLength);
 | 
					            return new LispNumber(accumulatedLength);
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,8 @@ public class LIST extends LispFunction {
 | 
				
			|||||||
        if (argumentList.nullp())
 | 
					        if (argumentList.nullp())
 | 
				
			||||||
            return Nil.getInstance();
 | 
					            return Nil.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        Cons remainingArguments = (Cons) argumentList.getCdr();
 | 
					        Cons remainingArguments = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new Cons(firstArgument, callRecursive(remainingArguments));
 | 
					        return new Cons(firstArgument, callRecursive(remainingArguments));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -16,17 +16,17 @@ class MathFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public LispNumber callTailRecursive(Cons argumentList) {
 | 
					    public LispNumber callTailRecursive(Cons argumentList) {
 | 
				
			||||||
        Cons remainingArguments = (Cons) argumentList.getCdr();
 | 
					        Cons remainingArguments = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        LispNumber number1 = (LispNumber) firstArgument;
 | 
					        LispNumber number1 = (LispNumber) firstArgument;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (remainingArguments.nullp())
 | 
					        if (remainingArguments.nullp())
 | 
				
			||||||
            return singleValueOperation.apply(number1);
 | 
					            return singleValueOperation.apply(number1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression secondArgument = remainingArguments.getCar();
 | 
					        SExpression secondArgument = remainingArguments.getFirst();
 | 
				
			||||||
        LispNumber number2 = (LispNumber) secondArgument;
 | 
					        LispNumber number2 = (LispNumber) secondArgument;
 | 
				
			||||||
        LispNumber operationResult = multipleValueOperation.apply(number1, number2);
 | 
					        LispNumber operationResult = multipleValueOperation.apply(number1, number2);
 | 
				
			||||||
        SExpression remainingNumbers = remainingArguments.getCdr();
 | 
					        SExpression remainingNumbers = remainingArguments.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (remainingNumbers.nullp())
 | 
					        if (remainingNumbers.nullp())
 | 
				
			||||||
            return operationResult;
 | 
					            return operationResult;
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ public class ATOM extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        SExpression argument = argumentList.getCar();
 | 
					        SExpression argument = argumentList.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argument.atomp() ? Symbol.T : Nil.getInstance();
 | 
					        return argument.atomp() ? Symbol.T : Nil.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,9 @@ public class EQ extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons cdr = (Cons) argumentList.getCdr();
 | 
					        Cons cdr = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        SExpression secondArgument = cdr.getCar();
 | 
					        SExpression secondArgument = cdr.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return eq(firstArgument, secondArgument);
 | 
					        return eq(firstArgument, secondArgument);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -20,19 +20,19 @@ public class EQUAL extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression callRecursive(Cons argumentList) {
 | 
					    private SExpression callRecursive(Cons argumentList) {
 | 
				
			||||||
        Cons cdr = (Cons) argumentList.getCdr();
 | 
					        Cons cdr = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        SExpression secondArgument = cdr.getCar();
 | 
					        SExpression secondArgument = cdr.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!isListPair(firstArgument, secondArgument))
 | 
					        if (!isListPair(firstArgument, secondArgument))
 | 
				
			||||||
            return equal(firstArgument, secondArgument);
 | 
					            return equal(firstArgument, secondArgument);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons listOne = (Cons) firstArgument;
 | 
					        Cons listOne = (Cons) firstArgument;
 | 
				
			||||||
        Cons listTwo = (Cons) secondArgument;
 | 
					        Cons listTwo = (Cons) secondArgument;
 | 
				
			||||||
        SExpression listOneCar = listOne.getCar();
 | 
					        SExpression listOneCar = listOne.getFirst();
 | 
				
			||||||
        SExpression listTwoCar = listTwo.getCar();
 | 
					        SExpression listTwoCar = listTwo.getFirst();
 | 
				
			||||||
        SExpression listOneCdr = listOne.getCdr();
 | 
					        SExpression listOneCdr = listOne.getRest();
 | 
				
			||||||
        SExpression listTwoCdr = listTwo.getCdr();
 | 
					        SExpression listTwoCdr = listTwo.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression carEqual = callRecursive(makeArgumentList(listOneCar, listTwoCar));
 | 
					        SExpression carEqual = callRecursive(makeArgumentList(listOneCar, listTwoCar));
 | 
				
			||||||
        SExpression cdrEqual = callRecursive(makeArgumentList(listOneCdr, listTwoCdr));
 | 
					        SExpression cdrEqual = callRecursive(makeArgumentList(listOneCdr, listTwoCdr));
 | 
				
			||||||
 | 
				
			|||||||
@ -20,14 +20,14 @@ public class EQUALSP extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression callTailRecursive(Cons argumentList) {
 | 
					    private SExpression callTailRecursive(Cons argumentList) {
 | 
				
			||||||
        Cons remainingArguments = (Cons) argumentList.getCdr();
 | 
					        Cons remainingArguments = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (remainingArguments.nullp())
 | 
					        if (remainingArguments.nullp())
 | 
				
			||||||
            return Symbol.T;
 | 
					            return Symbol.T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        LispNumber number1 = (LispNumber) firstArgument;
 | 
					        LispNumber number1 = (LispNumber) firstArgument;
 | 
				
			||||||
        SExpression secondArgument = remainingArguments.getCar();
 | 
					        SExpression secondArgument = remainingArguments.getFirst();
 | 
				
			||||||
        LispNumber number2 = (LispNumber) secondArgument;
 | 
					        LispNumber number2 = (LispNumber) secondArgument;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!isEqual(number1, number2))
 | 
					        if (!isEqual(number1, number2))
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ public class GREATERP extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression callTailRecursive(Cons argumentList) {
 | 
					    private SExpression callTailRecursive(Cons argumentList) {
 | 
				
			||||||
        Cons remainingArguments = (Cons) argumentList.getCdr();
 | 
					        Cons remainingArguments = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (remainingArguments.nullp())
 | 
					        if (remainingArguments.nullp())
 | 
				
			||||||
            return Symbol.T;
 | 
					            return Symbol.T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        SExpression secondArgument = remainingArguments.getCar();
 | 
					        SExpression secondArgument = remainingArguments.getFirst();
 | 
				
			||||||
        LispNumber number1 = (LispNumber) firstArgument;
 | 
					        LispNumber number1 = (LispNumber) firstArgument;
 | 
				
			||||||
        LispNumber number2 = (LispNumber) secondArgument;
 | 
					        LispNumber number2 = (LispNumber) secondArgument;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -20,13 +20,13 @@ public class LESSP extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression callTailRecursive(Cons argumentList) {
 | 
					    private SExpression callTailRecursive(Cons argumentList) {
 | 
				
			||||||
        Cons remainingArguments = (Cons) argumentList.getCdr();
 | 
					        Cons remainingArguments = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (remainingArguments.nullp())
 | 
					        if (remainingArguments.nullp())
 | 
				
			||||||
            return Symbol.T;
 | 
					            return Symbol.T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression firstArgument = argumentList.getCar();
 | 
					        SExpression firstArgument = argumentList.getFirst();
 | 
				
			||||||
        SExpression secondArgument = remainingArguments.getCar();
 | 
					        SExpression secondArgument = remainingArguments.getFirst();
 | 
				
			||||||
        LispNumber number1 = (LispNumber) firstArgument;
 | 
					        LispNumber number1 = (LispNumber) firstArgument;
 | 
				
			||||||
        LispNumber number2 = (LispNumber) secondArgument;
 | 
					        LispNumber number2 = (LispNumber) secondArgument;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ public class LISTP extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argumentList.getCar().listp() ? Symbol.T : Nil.getInstance();
 | 
					        return argumentList.getFirst().listp() ? Symbol.T : Nil.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ public class NULL extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argumentList.getCar().nullp() ? Symbol.T : Nil.getInstance();
 | 
					        return argumentList.getFirst().nullp() ? Symbol.T : Nil.getInstance();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,8 +20,8 @@ public class AND extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression callTailRecursive(Cons argumentList, SExpression lastValue) {
 | 
					    private SExpression callTailRecursive(Cons argumentList, SExpression lastValue) {
 | 
				
			||||||
        SExpression currentValue = eval(argumentList.getCar());
 | 
					        SExpression currentValue = eval(argumentList.getFirst());
 | 
				
			||||||
        Cons remainingValues = (Cons) argumentList.getCdr();
 | 
					        Cons remainingValues = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (argumentList.nullp())
 | 
					        if (argumentList.nullp())
 | 
				
			||||||
            return lastValue;
 | 
					            return lastValue;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,9 +25,9 @@ public class COND extends LispFunction {
 | 
				
			|||||||
        if (argumentList.nullp())
 | 
					        if (argumentList.nullp())
 | 
				
			||||||
            return Nil.getInstance();
 | 
					            return Nil.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons clause = (Cons) argumentList.getCar();
 | 
					        Cons clause = (Cons) argumentList.getFirst();
 | 
				
			||||||
        Cons remainingClauses = (Cons) argumentList.getCdr();
 | 
					        Cons remainingClauses = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression test = eval(clause.getCar());
 | 
					        SExpression test = eval(clause.getFirst());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (isTestSuccessful(test))
 | 
					        if (isTestSuccessful(test))
 | 
				
			||||||
            return evaluateResult(clause, test);
 | 
					            return evaluateResult(clause, test);
 | 
				
			||||||
@ -42,18 +42,18 @@ public class COND extends LispFunction {
 | 
				
			|||||||
    private SExpression evaluateResult(Cons clause, SExpression test) {
 | 
					    private SExpression evaluateResult(Cons clause, SExpression test) {
 | 
				
			||||||
        SExpression lastResultValue = test;
 | 
					        SExpression lastResultValue = test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (SExpression result = clause.getCdr(); result.consp(); result = advanceCons(result))
 | 
					        for (SExpression result = clause.getRest(); result.consp(); result = advanceCons(result))
 | 
				
			||||||
            lastResultValue = eval(getCar(result));
 | 
					            lastResultValue = eval(getCar(result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return lastResultValue;
 | 
					        return lastResultValue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression advanceCons(SExpression knownCons) {
 | 
					    private SExpression advanceCons(SExpression knownCons) {
 | 
				
			||||||
        return ((Cons) knownCons).getCdr();
 | 
					        return ((Cons) knownCons).getRest();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression getCar(SExpression knownCons) {
 | 
					    private SExpression getCar(SExpression knownCons) {
 | 
				
			||||||
        return ((Cons) knownCons).getCar();
 | 
					        return ((Cons) knownCons).getFirst();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean evaluateArguments() {
 | 
					    public boolean evaluateArguments() {
 | 
				
			||||||
 | 
				
			|||||||
@ -33,15 +33,15 @@ public class DEFUN extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons remainingArguments = (Cons) argumentList.getCdr();
 | 
					        Cons remainingArguments = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression functionName = argumentList.getCar();
 | 
					        SExpression functionName = argumentList.getFirst();
 | 
				
			||||||
        SExpression secondArgument = remainingArguments.getCar();
 | 
					        SExpression secondArgument = remainingArguments.getFirst();
 | 
				
			||||||
        lambdaListIsListValidator.validate(LIST.makeList(secondArgument));
 | 
					        lambdaListIsListValidator.validate(LIST.makeList(secondArgument));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons lambdaList = (Cons) secondArgument;
 | 
					        Cons lambdaList = (Cons) secondArgument;
 | 
				
			||||||
        lambdaListValidator.validate(lambdaList);
 | 
					        lambdaListValidator.validate(lambdaList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons functionBody = (Cons) remainingArguments.getCdr();
 | 
					        Cons functionBody = (Cons) remainingArguments.getRest();
 | 
				
			||||||
        UserDefinedFunction function = new UserDefinedFunction(functionName.toString(), lambdaList, functionBody);
 | 
					        UserDefinedFunction function = new UserDefinedFunction(functionName.toString(), lambdaList, functionBody);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (FunctionTable.isAlreadyDefined(functionName.toString()))
 | 
					        if (FunctionTable.isAlreadyDefined(functionName.toString()))
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ public class IF extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression test = eval(argumentList.getCar());
 | 
					        SExpression test = eval(argumentList.getFirst());
 | 
				
			||||||
        SExpression thenForm = getThenForm(argumentList);
 | 
					        SExpression thenForm = getThenForm(argumentList);
 | 
				
			||||||
        SExpression elseForm = getElseForm(argumentList);
 | 
					        SExpression elseForm = getElseForm(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,17 +32,17 @@ public class IF extends LispFunction {
 | 
				
			|||||||
    private SExpression getThenForm(Cons argumentList) {
 | 
					    private SExpression getThenForm(Cons argumentList) {
 | 
				
			||||||
        Cons expressions = getRestOfList(argumentList);
 | 
					        Cons expressions = getRestOfList(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return expressions.getCar();
 | 
					        return expressions.getFirst();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Cons getRestOfList(Cons argumentList) {
 | 
					    private Cons getRestOfList(Cons argumentList) {
 | 
				
			||||||
        return (Cons) argumentList.getCdr();
 | 
					        return (Cons) argumentList.getRest();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression getElseForm(Cons argumentList) {
 | 
					    private SExpression getElseForm(Cons argumentList) {
 | 
				
			||||||
        Cons expressions = getRestOfList(argumentList);
 | 
					        Cons expressions = getRestOfList(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return getRestOfList(expressions).getCar();
 | 
					        return getRestOfList(expressions).getFirst();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean evaluateArguments() {
 | 
					    public boolean evaluateArguments() {
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ public class LAMBDA extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public static boolean isLambdaExpression(SExpression sexpr) {
 | 
					    public static boolean isLambdaExpression(SExpression sexpr) {
 | 
				
			||||||
        if (sexpr.consp()) {
 | 
					        if (sexpr.consp()) {
 | 
				
			||||||
            SExpression first = ((Cons) sexpr).getCar();
 | 
					            SExpression first = ((Cons) sexpr).getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return "LAMBDA".equals(first.toString());
 | 
					            return "LAMBDA".equals(first.toString());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -17,7 +17,7 @@ public class LAMBDA extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static UserDefinedFunction createFunction(Cons lambdaExpression) {
 | 
					    public static UserDefinedFunction createFunction(Cons lambdaExpression) {
 | 
				
			||||||
        SExpression cdr = lambdaExpression.getCdr();
 | 
					        SExpression cdr = lambdaExpression.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|");
 | 
					        ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|");
 | 
				
			||||||
        lambdaValidator.setEveryArgumentExpectedType(Cons.class);
 | 
					        lambdaValidator.setEveryArgumentExpectedType(Cons.class);
 | 
				
			||||||
@ -43,9 +43,9 @@ public class LAMBDA extends LispFunction {
 | 
				
			|||||||
    public LambdaExpression call(Cons argumentList) {
 | 
					    public LambdaExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SExpression car = argumentList.getCar();
 | 
					        SExpression car = argumentList.getFirst();
 | 
				
			||||||
        Cons lambdaList = (Cons) car;
 | 
					        Cons lambdaList = (Cons) car;
 | 
				
			||||||
        Cons body = (Cons) argumentList.getCdr();
 | 
					        Cons body = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        lambdaListValidator.validate(lambdaList);
 | 
					        lambdaListValidator.validate(lambdaList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -30,8 +30,8 @@ public class LET extends LispFunction {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
        Cons variableDefinitions = (Cons) argumentList.getCar();
 | 
					        Cons variableDefinitions = (Cons) argumentList.getFirst();
 | 
				
			||||||
        Cons body = (Cons) argumentList.getCdr();
 | 
					        Cons body = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return evaluateInScope(variableDefinitions, body);
 | 
					        return evaluateInScope(variableDefinitions, body);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -55,16 +55,16 @@ public class LET extends LispFunction {
 | 
				
			|||||||
    private void addVariablesToScope(SymbolTable scope, Cons variableDefinitions) {
 | 
					    private void addVariablesToScope(SymbolTable scope, Cons variableDefinitions) {
 | 
				
			||||||
        variableDefinitionListValidator.validate(variableDefinitions);
 | 
					        variableDefinitionListValidator.validate(variableDefinitions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (; variableDefinitions.consp(); variableDefinitions = (Cons) variableDefinitions.getCdr())
 | 
					        for (; variableDefinitions.consp(); variableDefinitions = (Cons) variableDefinitions.getRest())
 | 
				
			||||||
            addPairToScope((Cons) variableDefinitions.getCar(), scope);
 | 
					            addPairToScope((Cons) variableDefinitions.getFirst(), scope);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void addPairToScope(Cons symbolValuePair, SymbolTable scope) {
 | 
					    private void addPairToScope(Cons symbolValuePair, SymbolTable scope) {
 | 
				
			||||||
        pairValidator.validate(symbolValuePair);
 | 
					        pairValidator.validate(symbolValuePair);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons restOfPair = (Cons) symbolValuePair.getCdr();
 | 
					        Cons restOfPair = (Cons) symbolValuePair.getRest();
 | 
				
			||||||
        SExpression symbol = symbolValuePair.getCar();
 | 
					        SExpression symbol = symbolValuePair.getFirst();
 | 
				
			||||||
        SExpression value = restOfPair.getCar();
 | 
					        SExpression value = restOfPair.getFirst();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        scope.put(symbol.toString(), eval(value));
 | 
					        scope.put(symbol.toString(), eval(value));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -72,8 +72,8 @@ public class LET extends LispFunction {
 | 
				
			|||||||
    private SExpression evaluateBody(Cons body) {
 | 
					    private SExpression evaluateBody(Cons body) {
 | 
				
			||||||
        SExpression lastEvaluation = Nil.getInstance();
 | 
					        SExpression lastEvaluation = Nil.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (; body.consp(); body = (Cons) body.getCdr())
 | 
					        for (; body.consp(); body = (Cons) body.getRest())
 | 
				
			||||||
            lastEvaluation = eval(body.getCar());
 | 
					            lastEvaluation = eval(body.getFirst());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return lastEvaluation;
 | 
					        return lastEvaluation;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -20,8 +20,8 @@ public class OR extends LispFunction {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression callTailRecursive(Cons argumentList) {
 | 
					    private SExpression callTailRecursive(Cons argumentList) {
 | 
				
			||||||
        SExpression currentValue = eval(argumentList.getCar());
 | 
					        SExpression currentValue = eval(argumentList.getFirst());
 | 
				
			||||||
        Cons remainingValues = (Cons) argumentList.getCdr();
 | 
					        Cons remainingValues = (Cons) argumentList.getRest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (remainingValues.nullp() || !currentValue.nullp())
 | 
					        if (remainingValues.nullp() || !currentValue.nullp())
 | 
				
			||||||
            return currentValue;
 | 
					            return currentValue;
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ public class QUOTE extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return argumentList.getCar();
 | 
					        return argumentList.getFirst();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean evaluateArguments() {
 | 
					    public boolean evaluateArguments() {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,9 +21,9 @@ public class SETF extends LispFunction {
 | 
				
			|||||||
    public SExpression call(Cons argumentList) {
 | 
					    public SExpression call(Cons argumentList) {
 | 
				
			||||||
        argumentValidator.validate(argumentList);
 | 
					        argumentValidator.validate(argumentList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cons cdr = (Cons) argumentList.getCdr();
 | 
					        Cons cdr = (Cons) argumentList.getRest();
 | 
				
			||||||
        SExpression symbol = argumentList.getCar();
 | 
					        SExpression symbol = argumentList.getFirst();
 | 
				
			||||||
        SExpression value = eval(cdr.getCar());
 | 
					        SExpression value = eval(cdr.getFirst());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SymbolTable table = findScopeOfSymbol(symbol);
 | 
					        SymbolTable table = findScopeOfSymbol(symbol);
 | 
				
			||||||
        table.put(symbol.toString(), value);
 | 
					        table.put(symbol.toString(), value);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,28 +3,28 @@ package sexpression;
 | 
				
			|||||||
@DisplayName("list")
 | 
					@DisplayName("list")
 | 
				
			||||||
public class Cons extends SExpression {
 | 
					public class Cons extends SExpression {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private SExpression car;
 | 
					    private SExpression first;
 | 
				
			||||||
    private SExpression cdr;
 | 
					    private SExpression rest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Cons(SExpression car, SExpression cdr) {
 | 
					    public Cons(SExpression first, SExpression rest) {
 | 
				
			||||||
        this.car = car;
 | 
					        this.first = first;
 | 
				
			||||||
        this.cdr = cdr;
 | 
					        this.rest = rest;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SExpression getCar() {
 | 
					    public SExpression getFirst() {
 | 
				
			||||||
        return car;
 | 
					        return first;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SExpression getCdr() {
 | 
					    public SExpression getRest() {
 | 
				
			||||||
        return cdr;
 | 
					        return rest;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void setCar(SExpression newCar) {
 | 
					    public void setFirst(SExpression first) {
 | 
				
			||||||
        car = newCar;
 | 
					        this.first = first;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void setCdr(SExpression newCdr) {
 | 
					    public void setRest(SExpression rest) {
 | 
				
			||||||
        cdr = newCdr;
 | 
					        this.rest = rest;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean consp() {
 | 
					    public boolean consp() {
 | 
				
			||||||
@ -35,20 +35,13 @@ public class Cons extends SExpression {
 | 
				
			|||||||
        return ("(" + toStringAux());
 | 
					        return ("(" + toStringAux());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Returns a string representation of the car of a CONS cell followed by
 | 
					 | 
				
			||||||
    // its cdr. If the cdr of this CONS cell is not a CONS cell itself, this
 | 
					 | 
				
			||||||
    // method places a ')' at the end of its return value. Also, if the cdr of
 | 
					 | 
				
			||||||
    // this CONS cell is NIL, it will not be included in the return value of
 | 
					 | 
				
			||||||
    // this method. When used in conjunction with the 'toString' method of this
 | 
					 | 
				
			||||||
    // class, this method provides a means for creating the correct string
 | 
					 | 
				
			||||||
    // representation of a list.
 | 
					 | 
				
			||||||
    private String toStringAux() {
 | 
					    private String toStringAux() {
 | 
				
			||||||
        if (cdr.nullp())
 | 
					        if (rest.nullp())
 | 
				
			||||||
            return (car.toString() + ")");
 | 
					            return (first.toString() + ")");
 | 
				
			||||||
        else if (cdr.consp())
 | 
					        else if (rest.consp())
 | 
				
			||||||
            return (car.toString() + " " + ((Cons) cdr).toStringAux());
 | 
					            return (first.toString() + " " + ((Cons) rest).toStringAux());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (car.toString() + " . " + cdr.toString() + ")");
 | 
					        return (first.toString() + " . " + rest.toString() + ")");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,8 +12,8 @@ public class Nil extends Cons {
 | 
				
			|||||||
    private Nil() {
 | 
					    private Nil() {
 | 
				
			||||||
        super(null, null);
 | 
					        super(null, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super.setCar(this);
 | 
					        super.setFirst(this);
 | 
				
			||||||
        super.setCdr(this);
 | 
					        super.setRest(this);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public boolean nullp() {
 | 
					    public boolean nullp() {
 | 
				
			||||||
@ -35,12 +35,12 @@ public class Nil extends Cons {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The car of NIL can not be changed.
 | 
					     * The car of NIL can not be changed.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void setCar(SExpression newCar) {}
 | 
					    public void setFirst(SExpression newCar) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The cdr of NIL can not be changed.
 | 
					     * The cdr of NIL can not be changed.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void setCdr(SExpression newCdr) {}
 | 
					    public void setRest(SExpression newCdr) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String toString() {
 | 
					    public String toString() {
 | 
				
			||||||
        return "NIL";
 | 
					        return "NIL";
 | 
				
			||||||
 | 
				
			|||||||
@ -106,28 +106,28 @@ public class SExpressionTester {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testCarOfNilIsNil() {
 | 
					    public void testCarOfNilIsNil() {
 | 
				
			||||||
        assertEquals(Nil.getInstance(), Nil.getInstance().getCar());
 | 
					        assertEquals(Nil.getInstance(), Nil.getInstance().getFirst());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testCdrOfNilIsNil() {
 | 
					    public void testCdrOfNilIsNil() {
 | 
				
			||||||
        assertEquals(Nil.getInstance(), Nil.getInstance().getCdr());
 | 
					        assertEquals(Nil.getInstance(), Nil.getInstance().getRest());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void afterSettingCarOfNil_ShouldStillBeNil() {
 | 
					    public void afterSettingCarOfNil_ShouldStillBeNil() {
 | 
				
			||||||
        Cons nil = Nil.getInstance();
 | 
					        Cons nil = Nil.getInstance();
 | 
				
			||||||
        nil.setCar(new LispNumber("2"));
 | 
					        nil.setFirst(new LispNumber("2"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(Nil.getInstance(), nil.getCar());
 | 
					        assertEquals(Nil.getInstance(), nil.getFirst());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void afterSettingCdrOfNil_ShouldStillBeNil() {
 | 
					    public void afterSettingCdrOfNil_ShouldStillBeNil() {
 | 
				
			||||||
        Cons nil = Nil.getInstance();
 | 
					        Cons nil = Nil.getInstance();
 | 
				
			||||||
        nil.setCdr(new LispNumber("2"));
 | 
					        nil.setRest(new LispNumber("2"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertEquals(Nil.getInstance(), nil.getCdr());
 | 
					        assertEquals(Nil.getInstance(), nil.getRest());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user