Started changing car/cdr to first/rest, modified acceptance test fixture

This commit is contained in:
Mike Cifelli 2017-02-24 11:07:06 -05:00
parent 496f30cded
commit 0855789fde
38 changed files with 159 additions and 158 deletions

View File

@ -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();
} }
} }

View 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 |

View File

@ -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
-!|

View File

@ -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|

View File

@ -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) {

View File

@ -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();
} }
} }

View File

@ -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);

View File

@ -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));
} }

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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();
} }
} }

View File

@ -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();
} }
} }

View File

@ -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);
} }

View File

@ -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);

View File

@ -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));
} }

View File

@ -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;

View File

@ -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();
} }

View File

@ -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);
} }

View File

@ -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));

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -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();
} }
} }

View File

@ -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();
} }
} }

View File

@ -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;

View File

@ -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() {

View File

@ -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()))

View File

@ -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() {

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -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() {

View File

@ -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);

View File

@ -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() + ")");
} }
} }

View File

@ -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";

View File

@ -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