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();
}
public void input(String input) throws IOException {
public String evaluate(String input) throws IOException {
environment.setInput(new ByteArrayInputStream(input.getBytes()));
interpreter.interpret();
}
public String output() {
String output = outputStream.toString();
discardOutput();
return output;
}
public void discardOutput() {
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.TestOne||14:27:42 Wed, Feb 22, 2017|
|LispInterpreter||14:24:41 Wed, Feb 22, 2017|
|FrontPage||14:15:03 Wed, Feb 22, 2017|

View File

@ -1,10 +1,11 @@
package function;
import static function.builtin.cons.LENGTH.getLength;
import java.math.BigInteger;
import java.text.MessageFormat;
import error.LispException;
import function.builtin.cons.LENGTH;
import sexpression.*;
public class ArgumentValidator {
@ -62,9 +63,9 @@ public class ArgumentValidator {
}
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;
if (!next.nullp())
@ -79,13 +80,27 @@ public class ArgumentValidator {
}
private boolean containsTooFewArguments(Cons argumentList) {
return (minimumNumberOfArguments != null)
&& (LENGTH.getLength(argumentList).compareTo(minimumNumberOfArguments) < 0);
return isMinimum() && isLengthLessThanMinimum(argumentList);
}
private boolean isMinimum() {
return minimumNumberOfArguments != null;
}
private boolean isLengthLessThanMinimum(Cons argumentList) {
return getLength(argumentList).compareTo(minimumNumberOfArguments) < 0;
}
private boolean containsTooManyArguments(Cons argumentList) {
return (maximumNumberOfArguments != null)
&& (LENGTH.getLength(argumentList).compareTo(maximumNumberOfArguments) > 0);
return isMaximum() && isLengthGreaterThanMaximum(argumentList);
}
private boolean isMaximum() {
return maximumNumberOfArguments != null;
}
private boolean isLengthGreaterThanMaximum(Cons argumentList) {
return getLength(argumentList).compareTo(maximumNumberOfArguments) > 0;
}
private void validateArgumentTypes(Cons argumentList) {
@ -95,11 +110,11 @@ public class ArgumentValidator {
private void validateFirstArgument(Cons argumentList) {
if (!isFirstArgumentValid(argumentList))
throw new BadArgumentTypeException(functionName, argumentList.getCar(), firstArgumentType);
throw new BadArgumentTypeException(functionName, argumentList.getFirst(), firstArgumentType);
}
private boolean isFirstArgumentValid(Cons argumentList) {
return argumentList.nullp() || isExpectedFirstArgumentType(argumentList.getCar());
return argumentList.nullp() || isExpectedFirstArgumentType(argumentList.getFirst());
}
private boolean isExpectedFirstArgumentType(SExpression firstArgument) {
@ -111,9 +126,9 @@ public class ArgumentValidator {
}
private void validateTrailingArguments(Cons argumentList) {
for (Cons cons = (Cons) argumentList.getCdr(); !cons.nullp(); cons = (Cons) cons.getCdr())
if (!isExpectedTrailingArgumentType(cons.getCar()))
throw new BadArgumentTypeException(functionName, cons.getCar(), trailingArgumentType);
for (Cons cons = (Cons) argumentList.getRest(); !cons.nullp(); cons = (Cons) cons.getRest())
if (!isExpectedTrailingArgumentType(cons.getFirst()))
throw new BadArgumentTypeException(functionName, cons.getFirst(), trailingArgumentType);
}
private boolean isExpectedTrailingArgumentType(SExpression trailingArgument) {

View File

@ -24,8 +24,8 @@ public class UserDefinedFunction extends LispFunction {
this.executionContext = ExecutionContext.getInstance();
this.functionScope = executionContext.getScope();
for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getCdr())
this.formalParameters.add(lambdaList.getCar().toString());
for (this.formalParameters = new ArrayList<>(); lambdaList.consp(); lambdaList = (Cons) lambdaList.getRest())
this.formalParameters.add(lambdaList.getFirst().toString());
this.argumentValidator = new ArgumentValidator(this.name);
this.argumentValidator.setExactNumberOfArguments(this.formalParameters.size());
@ -40,8 +40,8 @@ public class UserDefinedFunction extends LispFunction {
SExpression lastEvaluation = Nil.getInstance();
for (Cons expression = body; expression.consp(); expression = (Cons) expression.getCdr())
lastEvaluation = eval(expression.getCar());
for (Cons expression = body; expression.consp(); expression = (Cons) expression.getRest())
lastEvaluation = eval(expression.getFirst());
executionContext.setScope(callingScope);
releaseParameterValues();
@ -53,9 +53,9 @@ public class UserDefinedFunction extends LispFunction {
functionScope = new SymbolTable(functionScope);
for (String parameter : formalParameters) {
SExpression currentArg = argumentList.getCar();
SExpression currentArg = argumentList.getFirst();
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) {
argumentValidator.validate(argumentList);
Cons cdr = (Cons) argumentList.getCdr();
SExpression functionName = argumentList.getCar();
SExpression functionArguments = cdr.getCar();
Cons cdr = (Cons) argumentList.getRest();
SExpression functionName = argumentList.getFirst();
SExpression functionArguments = cdr.getFirst();
LispFunction function = EVAL.lookupFunctionOrLambda(functionName);
return function.call((Cons) functionArguments);

View File

@ -57,7 +57,7 @@ public class EVAL extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression argument = argumentList.getCar();
SExpression argument = argumentList.getFirst();
if (argument.listp()) {
if (argument.consp())
@ -79,8 +79,8 @@ public class EVAL extends LispFunction {
}
private SExpression evaluateList(Cons list) {
SExpression functionName = list.getCar();
SExpression arguments = list.getCdr();
SExpression functionName = list.getFirst();
SExpression arguments = list.getRest();
LispFunction function = lookupFunctionOrLambda(functionName);
ArgumentValidator functionListValidator = new ArgumentValidator(functionName.toString());
@ -98,8 +98,8 @@ public class EVAL extends LispFunction {
if (arguments.nullp())
return Nil.getInstance();
SExpression car = eval(arguments.getCar());
SExpression cdr = arguments.getCdr();
SExpression car = eval(arguments.getFirst());
SExpression cdr = arguments.getRest();
return new Cons(car, evaluateArgList((Cons) cdr));
}

View File

@ -1,5 +1,7 @@
package function.builtin;
import static function.builtin.APPLY.apply;
import function.*;
import function.builtin.cons.LIST;
import sexpression.*;
@ -15,9 +17,9 @@ public class FUNCALL extends LispFunction {
public SExpression call(Cons 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) {
argumentValidator.validate(argumentList);
LispString quotedName = (LispString) argumentList.getCar();
LispString quotedName = (LispString) argumentList.getFirst();
String fileName = removeSurroundingQuotes(quotedName.toString());
return processFile(fileName);

View File

@ -17,7 +17,7 @@ public class PRINT extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression argument = argumentList.getCar();
SExpression argument = argumentList.getFirst();
environment.getOutput().println(argument);
return argument;

View File

@ -20,7 +20,7 @@ public class SYMBOL_FUNCTION extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression symbol = argumentList.getCar();
SExpression symbol = argumentList.getFirst();
LispFunction function = FunctionTable.lookupFunction(symbol.toString());
if (function != null) {

View File

@ -15,9 +15,9 @@ public class CAR extends LispFunction {
public SExpression call(Cons 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) {
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) {
argumentValidator.validate(argumentList);
Cons cdr = (Cons) argumentList.getCdr();
SExpression firstArgument = argumentList.getCar();
SExpression secondArgument = cdr.getCar();
Cons cdr = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = cdr.getFirst();
return new Cons(firstArgument, secondArgument);
}

View File

@ -33,8 +33,8 @@ public class LENGTH extends LispFunction {
}
private LispNumber callTailRecursive(BigInteger accumulatedLength, Cons argumentList) {
Cons list = (Cons) argumentList.getCar();
Cons restOfList = LIST.makeList(list.getCdr());
Cons list = (Cons) argumentList.getFirst();
Cons restOfList = LIST.makeList(list.getRest());
if (list.nullp())
return new LispNumber(accumulatedLength);

View File

@ -25,8 +25,8 @@ public class LIST extends LispFunction {
if (argumentList.nullp())
return Nil.getInstance();
SExpression firstArgument = argumentList.getCar();
Cons remainingArguments = (Cons) argumentList.getCdr();
SExpression firstArgument = argumentList.getFirst();
Cons remainingArguments = (Cons) argumentList.getRest();
return new Cons(firstArgument, callRecursive(remainingArguments));
}

View File

@ -16,17 +16,17 @@ class MathFunction {
}
public LispNumber callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getCdr();
SExpression firstArgument = argumentList.getCar();
Cons remainingArguments = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
if (remainingArguments.nullp())
return singleValueOperation.apply(number1);
SExpression secondArgument = remainingArguments.getCar();
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number2 = (LispNumber) secondArgument;
LispNumber operationResult = multipleValueOperation.apply(number1, number2);
SExpression remainingNumbers = remainingArguments.getCdr();
SExpression remainingNumbers = remainingArguments.getRest();
if (remainingNumbers.nullp())
return operationResult;

View File

@ -14,7 +14,7 @@ public class ATOM extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression argument = argumentList.getCar();
SExpression argument = argumentList.getFirst();
return argument.atomp() ? Symbol.T : Nil.getInstance();
}

View File

@ -15,9 +15,9 @@ public class EQ extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons cdr = (Cons) argumentList.getCdr();
SExpression firstArgument = argumentList.getCar();
SExpression secondArgument = cdr.getCar();
Cons cdr = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = cdr.getFirst();
return eq(firstArgument, secondArgument);
}

View File

@ -20,19 +20,19 @@ public class EQUAL extends LispFunction {
}
private SExpression callRecursive(Cons argumentList) {
Cons cdr = (Cons) argumentList.getCdr();
SExpression firstArgument = argumentList.getCar();
SExpression secondArgument = cdr.getCar();
Cons cdr = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = cdr.getFirst();
if (!isListPair(firstArgument, secondArgument))
return equal(firstArgument, secondArgument);
Cons listOne = (Cons) firstArgument;
Cons listTwo = (Cons) secondArgument;
SExpression listOneCar = listOne.getCar();
SExpression listTwoCar = listTwo.getCar();
SExpression listOneCdr = listOne.getCdr();
SExpression listTwoCdr = listTwo.getCdr();
SExpression listOneCar = listOne.getFirst();
SExpression listTwoCar = listTwo.getFirst();
SExpression listOneCdr = listOne.getRest();
SExpression listTwoCdr = listTwo.getRest();
SExpression carEqual = callRecursive(makeArgumentList(listOneCar, listTwoCar));
SExpression cdrEqual = callRecursive(makeArgumentList(listOneCdr, listTwoCdr));

View File

@ -20,14 +20,14 @@ public class EQUALSP extends LispFunction {
}
private SExpression callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getCdr();
Cons remainingArguments = (Cons) argumentList.getRest();
if (remainingArguments.nullp())
return Symbol.T;
SExpression firstArgument = argumentList.getCar();
SExpression firstArgument = argumentList.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
SExpression secondArgument = remainingArguments.getCar();
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number2 = (LispNumber) secondArgument;
if (!isEqual(number1, number2))

View File

@ -20,13 +20,13 @@ public class GREATERP extends LispFunction {
}
private SExpression callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getCdr();
Cons remainingArguments = (Cons) argumentList.getRest();
if (remainingArguments.nullp())
return Symbol.T;
SExpression firstArgument = argumentList.getCar();
SExpression secondArgument = remainingArguments.getCar();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
LispNumber number2 = (LispNumber) secondArgument;

View File

@ -20,13 +20,13 @@ public class LESSP extends LispFunction {
}
private SExpression callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getCdr();
Cons remainingArguments = (Cons) argumentList.getRest();
if (remainingArguments.nullp())
return Symbol.T;
SExpression firstArgument = argumentList.getCar();
SExpression secondArgument = remainingArguments.getCar();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
LispNumber number2 = (LispNumber) secondArgument;

View File

@ -15,7 +15,7 @@ public class LISTP extends LispFunction {
public SExpression call(Cons 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) {
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) {
SExpression currentValue = eval(argumentList.getCar());
Cons remainingValues = (Cons) argumentList.getCdr();
SExpression currentValue = eval(argumentList.getFirst());
Cons remainingValues = (Cons) argumentList.getRest();
if (argumentList.nullp())
return lastValue;

View File

@ -25,9 +25,9 @@ public class COND extends LispFunction {
if (argumentList.nullp())
return Nil.getInstance();
Cons clause = (Cons) argumentList.getCar();
Cons remainingClauses = (Cons) argumentList.getCdr();
SExpression test = eval(clause.getCar());
Cons clause = (Cons) argumentList.getFirst();
Cons remainingClauses = (Cons) argumentList.getRest();
SExpression test = eval(clause.getFirst());
if (isTestSuccessful(test))
return evaluateResult(clause, test);
@ -42,18 +42,18 @@ public class COND extends LispFunction {
private SExpression evaluateResult(Cons clause, SExpression 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));
return lastResultValue;
}
private SExpression advanceCons(SExpression knownCons) {
return ((Cons) knownCons).getCdr();
return ((Cons) knownCons).getRest();
}
private SExpression getCar(SExpression knownCons) {
return ((Cons) knownCons).getCar();
return ((Cons) knownCons).getFirst();
}
public boolean evaluateArguments() {

View File

@ -33,15 +33,15 @@ public class DEFUN extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons remainingArguments = (Cons) argumentList.getCdr();
SExpression functionName = argumentList.getCar();
SExpression secondArgument = remainingArguments.getCar();
Cons remainingArguments = (Cons) argumentList.getRest();
SExpression functionName = argumentList.getFirst();
SExpression secondArgument = remainingArguments.getFirst();
lambdaListIsListValidator.validate(LIST.makeList(secondArgument));
Cons lambdaList = (Cons) secondArgument;
lambdaListValidator.validate(lambdaList);
Cons functionBody = (Cons) remainingArguments.getCdr();
Cons functionBody = (Cons) remainingArguments.getRest();
UserDefinedFunction function = new UserDefinedFunction(functionName.toString(), lambdaList, functionBody);
if (FunctionTable.isAlreadyDefined(functionName.toString()))

View File

@ -18,7 +18,7 @@ public class IF extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression test = eval(argumentList.getCar());
SExpression test = eval(argumentList.getFirst());
SExpression thenForm = getThenForm(argumentList);
SExpression elseForm = getElseForm(argumentList);
@ -32,17 +32,17 @@ public class IF extends LispFunction {
private SExpression getThenForm(Cons argumentList) {
Cons expressions = getRestOfList(argumentList);
return expressions.getCar();
return expressions.getFirst();
}
private Cons getRestOfList(Cons argumentList) {
return (Cons) argumentList.getCdr();
return (Cons) argumentList.getRest();
}
private SExpression getElseForm(Cons argumentList) {
Cons expressions = getRestOfList(argumentList);
return getRestOfList(expressions).getCar();
return getRestOfList(expressions).getFirst();
}
public boolean evaluateArguments() {

View File

@ -8,7 +8,7 @@ public class LAMBDA extends LispFunction {
public static boolean isLambdaExpression(SExpression sexpr) {
if (sexpr.consp()) {
SExpression first = ((Cons) sexpr).getCar();
SExpression first = ((Cons) sexpr).getFirst();
return "LAMBDA".equals(first.toString());
}
@ -17,7 +17,7 @@ public class LAMBDA extends LispFunction {
}
public static UserDefinedFunction createFunction(Cons lambdaExpression) {
SExpression cdr = lambdaExpression.getCdr();
SExpression cdr = lambdaExpression.getRest();
ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|");
lambdaValidator.setEveryArgumentExpectedType(Cons.class);
@ -43,9 +43,9 @@ public class LAMBDA extends LispFunction {
public LambdaExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression car = argumentList.getCar();
SExpression car = argumentList.getFirst();
Cons lambdaList = (Cons) car;
Cons body = (Cons) argumentList.getCdr();
Cons body = (Cons) argumentList.getRest();
lambdaListValidator.validate(lambdaList);

View File

@ -30,8 +30,8 @@ public class LET extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons variableDefinitions = (Cons) argumentList.getCar();
Cons body = (Cons) argumentList.getCdr();
Cons variableDefinitions = (Cons) argumentList.getFirst();
Cons body = (Cons) argumentList.getRest();
return evaluateInScope(variableDefinitions, body);
}
@ -55,16 +55,16 @@ public class LET extends LispFunction {
private void addVariablesToScope(SymbolTable scope, Cons variableDefinitions) {
variableDefinitionListValidator.validate(variableDefinitions);
for (; variableDefinitions.consp(); variableDefinitions = (Cons) variableDefinitions.getCdr())
addPairToScope((Cons) variableDefinitions.getCar(), scope);
for (; variableDefinitions.consp(); variableDefinitions = (Cons) variableDefinitions.getRest())
addPairToScope((Cons) variableDefinitions.getFirst(), scope);
}
private void addPairToScope(Cons symbolValuePair, SymbolTable scope) {
pairValidator.validate(symbolValuePair);
Cons restOfPair = (Cons) symbolValuePair.getCdr();
SExpression symbol = symbolValuePair.getCar();
SExpression value = restOfPair.getCar();
Cons restOfPair = (Cons) symbolValuePair.getRest();
SExpression symbol = symbolValuePair.getFirst();
SExpression value = restOfPair.getFirst();
scope.put(symbol.toString(), eval(value));
}
@ -72,8 +72,8 @@ public class LET extends LispFunction {
private SExpression evaluateBody(Cons body) {
SExpression lastEvaluation = Nil.getInstance();
for (; body.consp(); body = (Cons) body.getCdr())
lastEvaluation = eval(body.getCar());
for (; body.consp(); body = (Cons) body.getRest())
lastEvaluation = eval(body.getFirst());
return lastEvaluation;
}

View File

@ -20,8 +20,8 @@ public class OR extends LispFunction {
}
private SExpression callTailRecursive(Cons argumentList) {
SExpression currentValue = eval(argumentList.getCar());
Cons remainingValues = (Cons) argumentList.getCdr();
SExpression currentValue = eval(argumentList.getFirst());
Cons remainingValues = (Cons) argumentList.getRest();
if (remainingValues.nullp() || !currentValue.nullp())
return currentValue;

View File

@ -15,7 +15,7 @@ public class QUOTE extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return argumentList.getCar();
return argumentList.getFirst();
}
public boolean evaluateArguments() {

View File

@ -21,9 +21,9 @@ public class SETF extends LispFunction {
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons cdr = (Cons) argumentList.getCdr();
SExpression symbol = argumentList.getCar();
SExpression value = eval(cdr.getCar());
Cons cdr = (Cons) argumentList.getRest();
SExpression symbol = argumentList.getFirst();
SExpression value = eval(cdr.getFirst());
SymbolTable table = findScopeOfSymbol(symbol);
table.put(symbol.toString(), value);

View File

@ -3,28 +3,28 @@ package sexpression;
@DisplayName("list")
public class Cons extends SExpression {
private SExpression car;
private SExpression cdr;
private SExpression first;
private SExpression rest;
public Cons(SExpression car, SExpression cdr) {
this.car = car;
this.cdr = cdr;
public Cons(SExpression first, SExpression rest) {
this.first = first;
this.rest = rest;
}
public SExpression getCar() {
return car;
public SExpression getFirst() {
return first;
}
public SExpression getCdr() {
return cdr;
public SExpression getRest() {
return rest;
}
public void setCar(SExpression newCar) {
car = newCar;
public void setFirst(SExpression first) {
this.first = first;
}
public void setCdr(SExpression newCdr) {
cdr = newCdr;
public void setRest(SExpression rest) {
this.rest = rest;
}
public boolean consp() {
@ -35,20 +35,13 @@ public class Cons extends SExpression {
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() {
if (cdr.nullp())
return (car.toString() + ")");
else if (cdr.consp())
return (car.toString() + " " + ((Cons) cdr).toStringAux());
if (rest.nullp())
return (first.toString() + ")");
else if (rest.consp())
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() {
super(null, null);
super.setCar(this);
super.setCdr(this);
super.setFirst(this);
super.setRest(this);
}
public boolean nullp() {
@ -35,12 +35,12 @@ public class Nil extends Cons {
/**
* 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.
*/
public void setCdr(SExpression newCdr) {}
public void setRest(SExpression newCdr) {}
public String toString() {
return "NIL";

View File

@ -106,28 +106,28 @@ public class SExpressionTester {
@Test
public void testCarOfNilIsNil() {
assertEquals(Nil.getInstance(), Nil.getInstance().getCar());
assertEquals(Nil.getInstance(), Nil.getInstance().getFirst());
}
@Test
public void testCdrOfNilIsNil() {
assertEquals(Nil.getInstance(), Nil.getInstance().getCdr());
assertEquals(Nil.getInstance(), Nil.getInstance().getRest());
}
@Test
public void afterSettingCarOfNil_ShouldStillBeNil() {
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
public void afterSettingCdrOfNil_ShouldStillBeNil() {
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