Finished changing car/cdr to first/rest in the code

This commit is contained in:
Mike Cifelli 2017-02-24 16:00:05 -05:00
parent 0855789fde
commit c83db3721c
18 changed files with 131 additions and 116 deletions

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.getRest(); Cons rest = (Cons) argumentList.getRest();
SExpression functionName = argumentList.getFirst(); SExpression functionName = argumentList.getFirst();
SExpression functionArguments = cdr.getFirst(); SExpression functionArguments = rest.getFirst();
LispFunction function = EVAL.lookupFunctionOrLambda(functionName); LispFunction function = EVAL.lookupFunctionOrLambda(functionName);
return function.call((Cons) functionArguments); return function.call((Cons) functionArguments);

View File

@ -98,10 +98,10 @@ public class EVAL extends LispFunction {
if (arguments.nullp()) if (arguments.nullp())
return Nil.getInstance(); return Nil.getInstance();
SExpression car = eval(arguments.getFirst()); SExpression first = eval(arguments.getFirst());
SExpression cdr = arguments.getRest(); SExpression rest = arguments.getRest();
return new Cons(car, evaluateArgList((Cons) cdr)); return new Cons(first, evaluateArgList((Cons) rest));
} }
public static class UndefinedFunctionException extends LispException { public static class UndefinedFunctionException extends LispException {

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.getRest(); Cons rest = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst(); SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = cdr.getFirst(); SExpression secondArgument = rest.getFirst();
return new Cons(firstArgument, secondArgument); return new Cons(firstArgument, secondArgument);
} }

View File

@ -3,12 +3,12 @@ package function.builtin.cons;
import function.*; import function.*;
import sexpression.*; import sexpression.*;
public class CAR extends LispFunction { public class FIRST extends LispFunction {
private ArgumentValidator argumentValidator; private ArgumentValidator argumentValidator;
public CAR() { public FIRST() {
this.argumentValidator = new ArgumentValidator("CAR"); this.argumentValidator = new ArgumentValidator("FIRST");
this.argumentValidator.setExactNumberOfArguments(1); this.argumentValidator.setExactNumberOfArguments(1);
this.argumentValidator.setEveryArgumentExpectedType(Cons.class); this.argumentValidator.setEveryArgumentExpectedType(Cons.class);
} }

View File

@ -3,12 +3,12 @@ package function.builtin.cons;
import function.*; import function.*;
import sexpression.*; import sexpression.*;
public class CDR extends LispFunction { public class REST extends LispFunction {
private ArgumentValidator argumentValidator; private ArgumentValidator argumentValidator;
public CDR() { public REST() {
this.argumentValidator = new ArgumentValidator("CDR"); this.argumentValidator = new ArgumentValidator("REST");
this.argumentValidator.setExactNumberOfArguments(1); this.argumentValidator.setExactNumberOfArguments(1);
this.argumentValidator.setEveryArgumentExpectedType(Cons.class); this.argumentValidator.setEveryArgumentExpectedType(Cons.class);
} }

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.getRest(); Cons rest = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst(); SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = cdr.getFirst(); SExpression secondArgument = rest.getFirst();
return eq(firstArgument, secondArgument); return eq(firstArgument, secondArgument);
} }

View File

@ -20,24 +20,24 @@ public class EQUAL extends LispFunction {
} }
private SExpression callRecursive(Cons argumentList) { private SExpression callRecursive(Cons argumentList) {
Cons cdr = (Cons) argumentList.getRest(); Cons rest = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst(); SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = cdr.getFirst(); SExpression secondArgument = rest.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.getFirst(); SExpression listOneFirst = listOne.getFirst();
SExpression listTwoCar = listTwo.getFirst(); SExpression listTwoFirst = listTwo.getFirst();
SExpression listOneCdr = listOne.getRest(); SExpression listOneRest = listOne.getRest();
SExpression listTwoCdr = listTwo.getRest(); SExpression listTwoRest = listTwo.getRest();
SExpression carEqual = callRecursive(makeArgumentList(listOneCar, listTwoCar)); SExpression firstEqual = callRecursive(makeArgumentList(listOneFirst, listTwoFirst));
SExpression cdrEqual = callRecursive(makeArgumentList(listOneCdr, listTwoCdr)); SExpression restEqual = callRecursive(makeArgumentList(listOneRest, listTwoRest));
return logicalConjunction(carEqual, cdrEqual); return logicalConjunction(firstEqual, restEqual);
} }
private boolean isListPair(SExpression firstArgument, SExpression secondArgument) { private boolean isListPair(SExpression firstArgument, SExpression secondArgument) {
@ -52,16 +52,16 @@ public class EQUAL extends LispFunction {
return firstArgument.toString().equals(secondArgument.toString()); return firstArgument.toString().equals(secondArgument.toString());
} }
private Cons makeArgumentList(SExpression listOneCar, SExpression listTwoCar) { private Cons makeArgumentList(SExpression listOneFirst, SExpression listTwoFirst) {
return new Cons(listOneCar, LIST.makeList(listTwoCar)); return new Cons(listOneFirst, LIST.makeList(listTwoFirst));
} }
private SExpression logicalConjunction(SExpression carEqual, SExpression cdrEqual) { private SExpression logicalConjunction(SExpression firstEqual, SExpression restEqual) {
return bothAreTrue(carEqual, cdrEqual) ? Symbol.T : Nil.getInstance(); return bothAreTrue(firstEqual, restEqual) ? Symbol.T : Nil.getInstance();
} }
private boolean bothAreTrue(SExpression carEqual, SExpression cdrEqual) { private boolean bothAreTrue(SExpression firstEqual, SExpression restEqual) {
return (carEqual == Symbol.T) && (cdrEqual == Symbol.T); return (firstEqual == Symbol.T) && (restEqual == Symbol.T);
} }
} }

View File

@ -43,7 +43,7 @@ public class COND extends LispFunction {
SExpression lastResultValue = test; SExpression lastResultValue = test;
for (SExpression result = clause.getRest(); result.consp(); result = advanceCons(result)) for (SExpression result = clause.getRest(); result.consp(); result = advanceCons(result))
lastResultValue = eval(getCar(result)); lastResultValue = eval(getFirst(result));
return lastResultValue; return lastResultValue;
} }
@ -52,7 +52,7 @@ public class COND extends LispFunction {
return ((Cons) knownCons).getRest(); return ((Cons) knownCons).getRest();
} }
private SExpression getCar(SExpression knownCons) { private SExpression getFirst(SExpression knownCons) {
return ((Cons) knownCons).getFirst(); return ((Cons) knownCons).getFirst();
} }

View File

@ -1,7 +1,8 @@
package function.builtin.special; package function.builtin.special;
import static function.builtin.cons.LIST.makeList;
import function.*; import function.*;
import function.builtin.cons.LIST;
import sexpression.*; import sexpression.*;
public class LAMBDA extends LispFunction { public class LAMBDA extends LispFunction {
@ -17,13 +18,13 @@ public class LAMBDA extends LispFunction {
} }
public static UserDefinedFunction createFunction(Cons lambdaExpression) { public static UserDefinedFunction createFunction(Cons lambdaExpression) {
SExpression cdr = lambdaExpression.getRest(); SExpression rest = lambdaExpression.getRest();
ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|"); ArgumentValidator lambdaValidator = new ArgumentValidator("LAMBDA|create|");
lambdaValidator.setEveryArgumentExpectedType(Cons.class); lambdaValidator.setEveryArgumentExpectedType(Cons.class);
lambdaValidator.validate(LIST.makeList(cdr)); lambdaValidator.validate(makeList(rest));
LambdaExpression lambda = new LAMBDA().call((Cons) cdr); LambdaExpression lambda = new LAMBDA().call((Cons) rest);
return lambda.getFunction(); return lambda.getFunction();
} }
@ -43,8 +44,8 @@ public class LAMBDA extends LispFunction {
public LambdaExpression call(Cons argumentList) { public LambdaExpression call(Cons argumentList) {
argumentValidator.validate(argumentList); argumentValidator.validate(argumentList);
SExpression car = argumentList.getFirst(); SExpression first = argumentList.getFirst();
Cons lambdaList = (Cons) car; Cons lambdaList = (Cons) first;
Cons body = (Cons) argumentList.getRest(); Cons body = (Cons) argumentList.getRest();
lambdaListValidator.validate(lambdaList); lambdaListValidator.validate(lambdaList);

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.getRest(); Cons rest = (Cons) argumentList.getRest();
SExpression symbol = argumentList.getFirst(); SExpression symbol = argumentList.getFirst();
SExpression value = eval(cdr.getFirst()); SExpression value = eval(rest.getFirst());
SymbolTable table = findScopeOfSymbol(symbol); SymbolTable table = findScopeOfSymbol(symbol);
table.put(symbol.toString(), value); table.put(symbol.toString(), value);

View File

@ -33,14 +33,14 @@ public class Nil extends Cons {
} }
/** /**
* The car of NIL can not be changed. * The first of NIL can not be changed.
*/ */
public void setFirst(SExpression newCar) {} public void setFirst(SExpression first) {}
/** /**
* The cdr of NIL can not be changed. * The rest of NIL can not be changed.
*/ */
public void setRest(SExpression newCdr) {} public void setRest(SExpression rest) {}
public String toString() { public String toString() {
return "NIL"; return "NIL";

View File

@ -48,8 +48,8 @@ public class FunctionTable {
functionTable.put("AND", new AND()); functionTable.put("AND", new AND());
functionTable.put("APPLY", new APPLY()); functionTable.put("APPLY", new APPLY());
functionTable.put("ATOM", new ATOM()); functionTable.put("ATOM", new ATOM());
functionTable.put("CAR", new CAR()); functionTable.put("CAR", new FIRST());
functionTable.put("CDR", new CDR()); functionTable.put("CDR", new REST());
functionTable.put("COND", new COND()); functionTable.put("COND", new COND());
functionTable.put("CONS", new CONS()); functionTable.put("CONS", new CONS());
functionTable.put("DEFUN", new DEFUN()); functionTable.put("DEFUN", new DEFUN());
@ -57,7 +57,7 @@ public class FunctionTable {
functionTable.put("EQUAL", new EQUAL()); functionTable.put("EQUAL", new EQUAL());
functionTable.put("EVAL", new EVAL()); functionTable.put("EVAL", new EVAL());
functionTable.put("EXIT", new EXIT()); functionTable.put("EXIT", new EXIT());
functionTable.put("FIRST", new CAR()); functionTable.put("FIRST", new FIRST());
functionTable.put("FUNCALL", new FUNCALL()); functionTable.put("FUNCALL", new FUNCALL());
functionTable.put("GREATERP", new GREATERP()); functionTable.put("GREATERP", new GREATERP());
functionTable.put("IF", new IF()); functionTable.put("IF", new IF());
@ -71,7 +71,7 @@ public class FunctionTable {
functionTable.put("OR", new OR()); functionTable.put("OR", new OR());
functionTable.put("PRINT", new PRINT()); functionTable.put("PRINT", new PRINT());
functionTable.put("QUOTE", new QUOTE()); functionTable.put("QUOTE", new QUOTE());
functionTable.put("REST", new CDR()); functionTable.put("REST", new REST());
functionTable.put("SETF", new SETF()); functionTable.put("SETF", new SETF());
functionTable.put("SYMBOL-FUNCTION", new SYMBOL_FUNCTION()); functionTable.put("SYMBOL-FUNCTION", new SYMBOL_FUNCTION());
} }

View File

@ -31,12 +31,12 @@ public abstract class Token {
// sExprTail ::= RIGHT_PAREN | sExpr sExprTail // sExprTail ::= RIGHT_PAREN | sExpr sExprTail
public SExpression parseSExpressionTail(Supplier<Token> getNextToken) { public SExpression parseSExpressionTail(Supplier<Token> getNextToken) {
SExpression car = parseSExpression(getNextToken); SExpression first = parseSExpression(getNextToken);
Token nextToken = getNextToken.get(); Token nextToken = getNextToken.get();
SExpression cdr = nextToken.parseSExpressionTail(getNextToken); SExpression rest = nextToken.parseSExpressionTail(getNextToken);
return new Cons(car, cdr); return new Cons(first, rest);
} }
} }

View File

@ -1,47 +0,0 @@
package function.builtin.cons;
import static testutil.TestUtilities.*;
import org.junit.Test;
import function.ArgumentValidator.*;
public class CARTester {
@Test
public void testCarWithNil() {
String input = "(car nil)";
assertSExpressionsMatch(parseString("()"), evaluateString(input));
}
@Test
public void testCarWithList() {
String input = "(car '(1 2 3))";
assertSExpressionsMatch(parseString("1"), evaluateString(input));
}
@Test
public void testNestedCarWithList() {
String input = "(car (car '((1 2) 3)))";
assertSExpressionsMatch(parseString("1"), evaluateString(input));
}
@Test(expected = BadArgumentTypeException.class)
public void testCarWithNonList() {
evaluateString("(car 'x)");
}
@Test(expected = TooManyArgumentsException.class)
public void testCarWithTooManyArguments() {
evaluateString("(car '(1 2) '(1 2) \"oh\")");
}
@Test(expected = TooFewArgumentsException.class)
public void testCarWithTooFewArguments() {
evaluateString("(car)");
}
}

View File

@ -24,7 +24,7 @@ public class CONSTester {
} }
@Test @Test
public void testConsWithListAsCdr() { public void testConsWithListAsRest() {
String input = "(cons 1 '(2 3))"; String input = "(cons 1 '(2 3))";
assertSExpressionsMatch(parseString("(1 2 3)"), evaluateString(input)); assertSExpressionsMatch(parseString("(1 2 3)"), evaluateString(input));

View File

@ -0,0 +1,54 @@
package function.builtin.cons;
import static testutil.TestUtilities.*;
import org.junit.Test;
import function.ArgumentValidator.*;
public class FIRSTTester {
@Test
public void firstOfNil() {
String input = "(first nil)";
assertSExpressionsMatch(parseString("()"), evaluateString(input));
}
@Test
public void firstOfList() {
String input = "(first '(1 2 3))";
assertSExpressionsMatch(parseString("1"), evaluateString(input));
}
@Test
public void carOfList() {
String input = "(car '(1 2 3))";
assertSExpressionsMatch(parseString("1"), evaluateString(input));
}
@Test
public void nestedFirstOfList() {
String input = "(first (first '((1 2) 3)))";
assertSExpressionsMatch(parseString("1"), evaluateString(input));
}
@Test(expected = BadArgumentTypeException.class)
public void firstOfSymbol() {
evaluateString("(first 'x)");
}
@Test(expected = TooManyArgumentsException.class)
public void firstWithTooManyArguments() {
evaluateString("(first '(1 2) '(1 2) \"oh\")");
}
@Test(expected = TooFewArgumentsException.class)
public void firstWithTooFewArguments() {
evaluateString("(first)");
}
}

View File

@ -6,42 +6,49 @@ import org.junit.Test;
import function.ArgumentValidator.*; import function.ArgumentValidator.*;
public class CDRTester { public class RESTTester {
@Test @Test
public void testCdrWithNil() { public void restOfNil() {
String input = "(cdr nil)"; String input = "(rest nil)";
assertSExpressionsMatch(parseString("()"), evaluateString(input)); assertSExpressionsMatch(parseString("()"), evaluateString(input));
} }
@Test @Test
public void testCdrWithList() { public void restOfList() {
String input = "(rest '(1 2 3))";
assertSExpressionsMatch(parseString("(2 3)"), evaluateString(input));
}
@Test
public void cdrOfList() {
String input = "(cdr '(1 2 3))"; String input = "(cdr '(1 2 3))";
assertSExpressionsMatch(parseString("(2 3)"), evaluateString(input)); assertSExpressionsMatch(parseString("(2 3)"), evaluateString(input));
} }
@Test @Test
public void testNestedCdrWithList() { public void nestedRestOfList() {
String input = "(cdr (cdr '(1 2 3)))"; String input = "(rest (rest '(1 2 3)))";
assertSExpressionsMatch(parseString("(3)"), evaluateString(input)); assertSExpressionsMatch(parseString("(3)"), evaluateString(input));
} }
@Test(expected = BadArgumentTypeException.class) @Test(expected = BadArgumentTypeException.class)
public void testCdrWithNonList() { public void restOfSymbol() {
evaluateString("(cdr 'x)"); evaluateString("(rest 'x)");
} }
@Test(expected = TooManyArgumentsException.class) @Test(expected = TooManyArgumentsException.class)
public void testCdrWithTooManyArguments() { public void restWithTooManyArguments() {
evaluateString("(cdr '(1 2) '(1 2) \"oh\")"); evaluateString("(rest '(1 2) '(1 2) \"oh\")");
} }
@Test(expected = TooFewArgumentsException.class) @Test(expected = TooFewArgumentsException.class)
public void testCdrWithTooFewArguments() { public void restWithTooFewArguments() {
evaluateString("(cdr)"); evaluateString("(rest)");
} }
} }

View File

@ -72,7 +72,7 @@ public class SExpressionTester {
} }
@Test @Test
public void testConsWithNonListCdrToString() { public void testImproperListToString() {
String expected = "(A . B)"; String expected = "(A . B)";
Cons list = new Cons(new Symbol("A"), new Symbol("B")); Cons list = new Cons(new Symbol("A"), new Symbol("B"));
@ -105,17 +105,17 @@ public class SExpressionTester {
} }
@Test @Test
public void testCarOfNilIsNil() { public void testFirstOfNilIsNil() {
assertEquals(Nil.getInstance(), Nil.getInstance().getFirst()); assertEquals(Nil.getInstance(), Nil.getInstance().getFirst());
} }
@Test @Test
public void testCdrOfNilIsNil() { public void testRestOfNilIsNil() {
assertEquals(Nil.getInstance(), Nil.getInstance().getRest()); assertEquals(Nil.getInstance(), Nil.getInstance().getRest());
} }
@Test @Test
public void afterSettingCarOfNil_ShouldStillBeNil() { public void afterSettingFirstOfNil_ShouldStillBeNil() {
Cons nil = Nil.getInstance(); Cons nil = Nil.getInstance();
nil.setFirst(new LispNumber("2")); nil.setFirst(new LispNumber("2"));
@ -123,7 +123,7 @@ public class SExpressionTester {
} }
@Test @Test
public void afterSettingCdrOfNil_ShouldStillBeNil() { public void afterSettingRestOfNil_ShouldStillBeNil() {
Cons nil = Nil.getInstance(); Cons nil = Nil.getInstance();
nil.setRest(new LispNumber("2")); nil.setRest(new LispNumber("2"));