diff --git a/src/function/builtin/ATOM.java b/src/function/builtin/ATOM.java
index 1cb8775..4be2e9f 100644
--- a/src/function/builtin/ATOM.java
+++ b/src/function/builtin/ATOM.java
@@ -16,7 +16,7 @@ public class ATOM extends LispFunction {
argumentValidator.validate(argumentList);
SExpression argument = argumentList.getCar();
- return argument.atomp() ? Symbol.T : Nil.getUniqueInstance();
+ return argument.atomp() ? Symbol.T : Nil.getInstance();
}
}
diff --git a/src/function/builtin/COND.java b/src/function/builtin/COND.java
index 3171081..05b1fe4 100644
--- a/src/function/builtin/COND.java
+++ b/src/function/builtin/COND.java
@@ -21,7 +21,7 @@ public class COND extends LispFunction {
private SExpression callTailRecursive(Cons argumentList) {
if (argumentList.nullp())
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
Cons clause = (Cons) argumentList.getCar();
Cons remainingClauses = (Cons) argumentList.getCdr();
@@ -34,7 +34,7 @@ public class COND extends LispFunction {
}
private boolean isTestSuccessful(SExpression test) {
- return test != Nil.getUniqueInstance();
+ return test != Nil.getInstance();
}
private SExpression evaluateResult(Cons clause, SExpression test) {
diff --git a/src/function/builtin/DIVIDE.java b/src/function/builtin/DIVIDE.java
index c8bd044..f9efa8c 100644
--- a/src/function/builtin/DIVIDE.java
+++ b/src/function/builtin/DIVIDE.java
@@ -2,54 +2,50 @@ package function.builtin;
import java.math.BigInteger;
-import function.LispFunction;
+import function.*;
import sexpression.*;
-/**
- * DIVIDE
represents the '/' function in Lisp.
- */
public class DIVIDE extends LispFunction {
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("/"), argList);
+ private ArgumentValidator argumentValidator;
- throw new RuntimeException("too few arguments given to /: " + originalSExpr);
- }
+ public DIVIDE() {
+ this.argumentValidator = new ArgumentValidator("/");
+ this.argumentValidator.setMinimumNumberOfArguments(1);
+ this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class);
+ }
- SExpression argFirst = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
+ public SExpression call(Cons argumentList) {
+ argumentValidator.validate(argumentList);
- // make sure that the first argument is a number
- if (argFirst.numberp()) {
- LispNumber num1 = (LispNumber) argFirst;
+ return callTailRecursive(argumentList);
+ }
- if (argRest.nullp()) {
- // there is only one argument, so return the multiplicative
- // inverse of the number
- return new LispNumber(BigInteger.ONE.divide(num1.getValue()));
- }
+ private SExpression callTailRecursive(Cons argumentList) {
+ Cons remainingArguments = (Cons) argumentList.getCdr();
+ SExpression firstArgument = argumentList.getCar();
+ LispNumber number1 = (LispNumber) firstArgument;
- SExpression argSecond = argRest.getCar();
+ if (remainingArguments.nullp())
+ return getReciprocal(number1);
- // make sure that the next argument is a number as well
- if (argSecond.numberp()) {
- LispNumber num2 = (LispNumber) argSecond;
- LispNumber quotient = new LispNumber(num1.getValue().divide(num2.getValue()));
- SExpression argCddr = argRest.getCdr();
+ SExpression secondArgument = remainingArguments.getCar();
+ LispNumber number2 = (LispNumber) secondArgument;
+ LispNumber quotient = divide(number1, number2);
+ SExpression remainingNumbers = remainingArguments.getCdr();
- if (argCddr.consp()) {
- return call(new Cons(quotient, argCddr));
- }
+ if (remainingNumbers.nullp())
+ return quotient;
- return quotient;
- }
+ return callTailRecursive(new Cons(quotient, remainingNumbers));
+ }
- throw new RuntimeException("/: " + argSecond + " is not a number");
- }
+ private LispNumber getReciprocal(LispNumber number1) {
+ return new LispNumber(BigInteger.ONE.divide(number1.getValue()));
+ }
- throw new RuntimeException("/: " + argFirst + " is not a number");
+ private LispNumber divide(LispNumber number1, LispNumber number2) {
+ return new LispNumber(number1.getValue().divide(number2.getValue()));
}
}
diff --git a/src/function/builtin/EQ.java b/src/function/builtin/EQ.java
index 9d98d3d..6857537 100644
--- a/src/function/builtin/EQ.java
+++ b/src/function/builtin/EQ.java
@@ -1,38 +1,44 @@
package function.builtin;
-import function.LispFunction;
+import function.*;
import sexpression.*;
-/**
- * EQ
represents the EQ function in Lisp.
- */
public class EQ extends LispFunction {
- // The number of arguments that EQ takes.
- private static final int NUM_ARGS = 2;
+ private ArgumentValidator argumentValidator;
- public SExpression call(Cons argList) {
- // retrieve the number of arguments passed to EQ
- int argListLength = LENGTH.getLength(argList);
+ public EQ() {
+ this.argumentValidator = new ArgumentValidator("EQ");
+ this.argumentValidator.setExactNumberOfArguments(2);
+ }
- // make sure we have received the proper number of arguments
- if (argListLength != NUM_ARGS) {
- Cons originalSExpr = new Cons(new Symbol("EQ"), argList);
- String errMsg = "too " + ((argListLength > NUM_ARGS) ? "many" : "few") + " arguments given to EQ: "
- + originalSExpr;
+ public SExpression call(Cons argumentList) {
+ argumentValidator.validate(argumentList);
- throw new RuntimeException(errMsg);
- }
+ Cons cdr = (Cons) argumentList.getCdr();
+ SExpression firstArgument = argumentList.getCar();
+ SExpression secondArgument = cdr.getCar();
- SExpression argOne = argList.getCar(); // first argument
- Cons cdr = (Cons) argList.getCdr();
- SExpression argTwo = cdr.getCar(); // second argumnet
+ return eq(firstArgument, secondArgument);
+ }
- if (argOne.atomp() && argTwo.atomp()) {
- return ((argOne.toString().equals(argTwo.toString())) ? Symbol.T : Nil.getUniqueInstance());
- }
+ private SExpression eq(SExpression firstArgument, SExpression secondArgument) {
+ if (isAtomPair(firstArgument, secondArgument))
+ return atomEq(firstArgument, secondArgument);
- return ((argOne == argTwo) ? Symbol.T : Nil.getUniqueInstance());
+ return listEq(firstArgument, secondArgument);
+ }
+
+ private boolean isAtomPair(SExpression firstArgument, SExpression secondArgument) {
+ return firstArgument.atomp() && secondArgument.atomp();
+ }
+
+ private SExpression atomEq(SExpression firstArgument, SExpression secondArgument) {
+ return (firstArgument.toString().equals(secondArgument.toString())) ? Symbol.T : Nil.getInstance();
+ }
+
+ private SExpression listEq(SExpression firstArgument, SExpression secondArgument) {
+ return (firstArgument == secondArgument) ? Symbol.T : Nil.getInstance();
}
}
diff --git a/src/function/builtin/EQUAL.java b/src/function/builtin/EQUAL.java
index 2a9ec1b..72ad6a4 100644
--- a/src/function/builtin/EQUAL.java
+++ b/src/function/builtin/EQUAL.java
@@ -39,10 +39,10 @@ public class EQUAL extends LispFunction {
SExpression carEqual = call(new Cons(listOneCar, LIST.makeList(listTwoCar)));
SExpression cdrEqual = call(new Cons(listOneCdr, LIST.makeList(listTwoCdr)));
- return (((carEqual == Symbol.T) && (cdrEqual == Symbol.T)) ? Symbol.T : Nil.getUniqueInstance());
+ return (((carEqual == Symbol.T) && (cdrEqual == Symbol.T)) ? Symbol.T : Nil.getInstance());
}
- return ((argOne.toString().equals(argTwo.toString())) ? Symbol.T : Nil.getUniqueInstance());
+ return ((argOne.toString().equals(argTwo.toString())) ? Symbol.T : Nil.getInstance());
}
}
diff --git a/src/function/builtin/EQUALSP.java b/src/function/builtin/EQUALSP.java
index deff065..5882e87 100644
--- a/src/function/builtin/EQUALSP.java
+++ b/src/function/builtin/EQUALSP.java
@@ -1,49 +1,43 @@
package function.builtin;
-import function.LispFunction;
+import function.*;
import sexpression.*;
-/**
- * EQUALSP
represents the '=' function in Lisp.
- */
public class EQUALSP extends LispFunction {
- public SExpression call(Cons argList) {
- // make sure we have received at least one argument
- if (argList.nullp()) {
- Cons originalSExpr = new Cons(new Symbol("="), argList);
+ private ArgumentValidator argumentValidator;
- throw new RuntimeException("too few arguments given to =: " + originalSExpr);
- }
+ public EQUALSP() {
+ this.argumentValidator = new ArgumentValidator("=");
+ this.argumentValidator.setMinimumNumberOfArguments(1);
+ this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class);
+ }
- SExpression firstArg = argList.getCar();
- Cons argRest = (Cons) argList.getCdr();
+ public SExpression call(Cons argumentList) {
+ argumentValidator.validate(argumentList);
- // make sure that the first argument is a number
- if (firstArg.numberp()) {
- LispNumber num1 = (LispNumber) firstArg;
+ return callTailRecursive(argumentList);
+ }
- if (argRest.nullp()) {
- return Symbol.T;
- }
+ private SExpression callTailRecursive(Cons argumentList) {
+ Cons remainingArguments = (Cons) argumentList.getCdr();
- SExpression secondArg = argRest.getCar();
+ if (remainingArguments.nullp())
+ return Symbol.T;
- // make sure that the second argument is a number as well
- if (secondArg.numberp()) {
- LispNumber num2 = (LispNumber) secondArg;
+ SExpression firstArgument = argumentList.getCar();
+ LispNumber number1 = (LispNumber) firstArgument;
+ SExpression secondArgument = remainingArguments.getCar();
+ LispNumber number2 = (LispNumber) secondArgument;
- if (num1.getValue().equals(num2.getValue())) {
- return call(argRest);
- }
+ if (!isEqual(number1, number2))
+ return Nil.getInstance();
- return Nil.getUniqueInstance();
- }
+ return callTailRecursive(remainingArguments);
+ }
- throw new RuntimeException("=: " + secondArg + " is not a number");
- }
-
- throw new RuntimeException("=: " + firstArg + " is not a number");
+ private boolean isEqual(LispNumber number1, LispNumber number2) {
+ return number1.getValue().equals(number2.getValue());
}
}
diff --git a/src/function/builtin/EVAL.java b/src/function/builtin/EVAL.java
index d965588..19feb34 100644
--- a/src/function/builtin/EVAL.java
+++ b/src/function/builtin/EVAL.java
@@ -73,7 +73,7 @@ public class EVAL extends LispFunction {
public static SExpression lookupSymbol(String symbolName) {
if (symbolName.equals("NIL")) {
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
} else if (symbolName.equals("T")) {
return Symbol.T;
} else if (symbolName.startsWith(":")) {
@@ -173,7 +173,7 @@ public class EVAL extends LispFunction {
private Cons evaluateArgList(Cons arguments) {
if (arguments.nullp()) {
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
SExpression car = eval(arguments.getCar());
@@ -185,7 +185,7 @@ public class EVAL extends LispFunction {
// remove any parameters found after a dot (put here in case the check
// for a dotted parameter list is not done prior to this call)
- return new Cons(car, Nil.getUniqueInstance());
+ return new Cons(car, Nil.getInstance());
}
}
diff --git a/src/function/builtin/GREATERP.java b/src/function/builtin/GREATERP.java
index fed1bbf..a4ed18a 100644
--- a/src/function/builtin/GREATERP.java
+++ b/src/function/builtin/GREATERP.java
@@ -37,7 +37,7 @@ public class GREATERP extends LispFunction {
return call(argRest);
}
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
throw new RuntimeException(">: " + secondArg + " is not a number");
diff --git a/src/function/builtin/LESSP.java b/src/function/builtin/LESSP.java
index 9275327..82c3ade 100644
--- a/src/function/builtin/LESSP.java
+++ b/src/function/builtin/LESSP.java
@@ -37,7 +37,7 @@ public class LESSP extends LispFunction {
return call(argRest);
}
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
throw new RuntimeException("<: " + secondArg + " is not a number");
diff --git a/src/function/builtin/LET.java b/src/function/builtin/LET.java
index 80698cb..2d16de3 100644
--- a/src/function/builtin/LET.java
+++ b/src/function/builtin/LET.java
@@ -25,7 +25,7 @@ public class LET extends LispFunction {
addVariablesToTable(environment, car);
SETF.setEnvironment(environment);
- SExpression retval = Nil.getUniqueInstance();
+ SExpression retval = Nil.getInstance();
// evaluate all S-expression in the body
while (cdr.consp()) {
diff --git a/src/function/builtin/LIST.java b/src/function/builtin/LIST.java
index 0bcf90e..0dc83cc 100644
--- a/src/function/builtin/LIST.java
+++ b/src/function/builtin/LIST.java
@@ -17,13 +17,13 @@ public class LIST extends LispFunction {
* a list with sexpr
as the car and NIL as the cdr.
*/
public static Cons makeList(SExpression sexpr) {
- return new Cons(sexpr, Nil.getUniqueInstance());
+ return new Cons(sexpr, Nil.getInstance());
}
public Cons call(Cons argList) {
if (argList.nullp()) {
// return NIL if there were no arguments passed to LIST
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
SExpression argCar = argList.getCar();
diff --git a/src/function/builtin/LISTP.java b/src/function/builtin/LISTP.java
index 1db2101..4519ba1 100644
--- a/src/function/builtin/LISTP.java
+++ b/src/function/builtin/LISTP.java
@@ -26,7 +26,7 @@ public class LISTP extends LispFunction {
SExpression arg = argList.getCar();
- return (arg.listp() ? Symbol.T : Nil.getUniqueInstance());
+ return (arg.listp() ? Symbol.T : Nil.getInstance());
}
}
diff --git a/src/function/builtin/LOAD.java b/src/function/builtin/LOAD.java
index b02ebb7..c03ee1a 100644
--- a/src/function/builtin/LOAD.java
+++ b/src/function/builtin/LOAD.java
@@ -58,7 +58,7 @@ public class LOAD extends LispFunction {
} catch (FileNotFoundException e) {
System.out.println("LOAD: could not open " + fileName);
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
// attempt to evaluate all the S-expressions contained in the file
@@ -70,7 +70,7 @@ public class LOAD extends LispFunction {
} catch (RuntimeException e) {
System.out.println("LOAD: " + e.getMessage());
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
}
diff --git a/src/function/builtin/NULL.java b/src/function/builtin/NULL.java
index 19607e7..50dc455 100644
--- a/src/function/builtin/NULL.java
+++ b/src/function/builtin/NULL.java
@@ -26,7 +26,7 @@ public class NULL extends LispFunction {
SExpression arg = argList.getCar();
- return (arg.nullp() ? Symbol.T : Nil.getUniqueInstance());
+ return (arg.nullp() ? Symbol.T : Nil.getInstance());
}
}
diff --git a/src/sexpression/Nil.java b/src/sexpression/Nil.java
index 49d9388..6b1977a 100644
--- a/src/sexpression/Nil.java
+++ b/src/sexpression/Nil.java
@@ -5,7 +5,7 @@ public class Nil extends Cons {
private static Nil uniqueInstance = new Nil();
- public static Nil getUniqueInstance() {
+ public static Nil getInstance() {
return uniqueInstance;
}
@@ -33,14 +33,12 @@ public class Nil extends Cons {
}
/**
- * Set the car of this CONS cell to the specified value. This method does nothing (the car of
- * NIL can not be changed).
+ * The car of NIL can not be changed.
*/
public void setCar(SExpression newCar) {}
/**
- * Set the cdr of this CONS cell to the specified value. This method does nothing (the cdr of
- * NIL can not be changed).
+ * The cdr of NIL can not be changed.
*/
public void setCdr(SExpression newCdr) {}
diff --git a/src/token/QuoteMark.java b/src/token/QuoteMark.java
index 64ee3f4..660bd5d 100644
--- a/src/token/QuoteMark.java
+++ b/src/token/QuoteMark.java
@@ -16,7 +16,7 @@ public class QuoteMark extends Token {
Token nextToken = getNextToken.get();
SExpression argument = nextToken.parseSExpression(getNextToken);
- return new Cons(Symbol.createQuote(), new Cons(argument, Nil.getUniqueInstance()));
+ return new Cons(Symbol.createQuote(), new Cons(argument, Nil.getInstance()));
}
}
diff --git a/src/token/RightParenthesis.java b/src/token/RightParenthesis.java
index f94db7e..26ac921 100644
--- a/src/token/RightParenthesis.java
+++ b/src/token/RightParenthesis.java
@@ -19,7 +19,7 @@ public class RightParenthesis extends Token {
@Override
public SExpression parseSExpressionTail(Supplier getNextToken) {
- return Nil.getUniqueInstance();
+ return Nil.getInstance();
}
public static class StartsWithRightParenthesisException extends LineColumnException {
diff --git a/test/function/ArgumentValidatorTester.java b/test/function/ArgumentValidatorTester.java
index c102956..97ae1d3 100644
--- a/test/function/ArgumentValidatorTester.java
+++ b/test/function/ArgumentValidatorTester.java
@@ -13,10 +13,10 @@ public class ArgumentValidatorTester {
private ArgumentValidator validator;
private Cons makeArgumentListOfSize(int size) {
- Cons argumentList = Nil.getUniqueInstance();
+ Cons argumentList = Nil.getInstance();
for (int i = 0; i < size; i++)
- argumentList = new Cons(Nil.getUniqueInstance(), argumentList);
+ argumentList = new Cons(Nil.getInstance(), argumentList);
return argumentList;
}
@@ -73,14 +73,14 @@ public class ArgumentValidatorTester {
@Test
public void tooManyArgumentsException_HasCorrectSeverity() {
- TooManyArgumentsException e = new TooManyArgumentsException("TEST", Nil.getUniqueInstance());
+ TooManyArgumentsException e = new TooManyArgumentsException("TEST", Nil.getInstance());
assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL);
}
@Test
public void tooManyArgumentsException_HasMessageText() {
- TooManyArgumentsException e = new TooManyArgumentsException("TEST", Nil.getUniqueInstance());
+ TooManyArgumentsException e = new TooManyArgumentsException("TEST", Nil.getInstance());
assertNotNull(e.getMessage());
assertTrue(e.getMessage().length() > 0);
@@ -88,14 +88,14 @@ public class ArgumentValidatorTester {
@Test
public void tooFewArgumentsException_HasCorrectSeverity() {
- TooFewArgumentsException e = new TooFewArgumentsException("TEST", Nil.getUniqueInstance());
+ TooFewArgumentsException e = new TooFewArgumentsException("TEST", Nil.getInstance());
assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL);
}
@Test
public void tooFewArgumentsException_HasMessageText() {
- TooFewArgumentsException e = new TooFewArgumentsException("TEST", Nil.getUniqueInstance());
+ TooFewArgumentsException e = new TooFewArgumentsException("TEST", Nil.getInstance());
assertNotNull(e.getMessage());
assertTrue(e.getMessage().length() > 0);
@@ -103,14 +103,14 @@ public class ArgumentValidatorTester {
@Test
public void BadArgumentTypeException_HasCorrectSeverity() {
- BadArgumentTypeException e = new BadArgumentTypeException("TEST", Nil.getUniqueInstance(), SExpression.class);
+ BadArgumentTypeException e = new BadArgumentTypeException("TEST", Nil.getInstance(), SExpression.class);
assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL);
}
@Test
public void BadArgumentTypeException_HasMessageText() {
- BadArgumentTypeException e = new BadArgumentTypeException("TEST", Nil.getUniqueInstance(), SExpression.class);
+ BadArgumentTypeException e = new BadArgumentTypeException("TEST", Nil.getInstance(), SExpression.class);
assertNotNull(e.getMessage());
assertTrue(e.getMessage().length() > 0);
@@ -130,7 +130,7 @@ public class ArgumentValidatorTester {
@Test
public void correctFirstAndRestArgumentTypes_DoesNotThrowException() {
- Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance()));
+ Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getInstance(), Nil.getInstance()));
validator.setFirstArgumentExpectedType(Symbol.class);
validator.setTrailingArgumentExpectedType(Cons.class);
@@ -139,7 +139,7 @@ public class ArgumentValidatorTester {
@Test(expected = BadArgumentTypeException.class)
public void badFirstArgumentType_ThrowsException() {
- Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance()));
+ Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getInstance(), Nil.getInstance()));
validator.setFirstArgumentExpectedType(Cons.class);
validator.setTrailingArgumentExpectedType(Cons.class);
@@ -148,7 +148,7 @@ public class ArgumentValidatorTester {
@Test(expected = BadArgumentTypeException.class)
public void badTrailingArgumentType_ThrowsException() {
- Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance()));
+ Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getInstance(), Nil.getInstance()));
validator.setFirstArgumentExpectedType(Symbol.class);
validator.setTrailingArgumentExpectedType(Symbol.class);
@@ -157,7 +157,7 @@ public class ArgumentValidatorTester {
@Test
public void expectedTypeWithNoDisplayName_DoesNotCauseNPE() {
- Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance()));
+ Cons argumentList = new Cons(Symbol.T, new Cons(Nil.getInstance(), Nil.getInstance()));
SExpression withoutDisplayName = new SExpression() {};
validator.setEveryArgumentExpectedType(withoutDisplayName.getClass());
@@ -186,14 +186,14 @@ public class ArgumentValidatorTester {
@Test
public void DottedArgumentListException_HasCorrectSeverity() {
- DottedArgumentListException e = new DottedArgumentListException("TEST", Nil.getUniqueInstance());
+ DottedArgumentListException e = new DottedArgumentListException("TEST", Nil.getInstance());
assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL);
}
@Test
public void dottedArgumentListException_HasMessageText() {
- DottedArgumentListException e = new DottedArgumentListException("TEST", Nil.getUniqueInstance());
+ DottedArgumentListException e = new DottedArgumentListException("TEST", Nil.getInstance());
assertNotNull(e.getMessage());
assertTrue(e.getMessage().length() > 0);
@@ -202,19 +202,19 @@ public class ArgumentValidatorTester {
@Test(expected = BadArgumentTypeException.class)
public void doNotAcceptNil_ThrowsExceptionOnNilArgument() {
validator.doNotAcceptNil();
- validator.validate(new Cons(Symbol.T, new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance())));
+ validator.validate(new Cons(Symbol.T, new Cons(Nil.getInstance(), Nil.getInstance())));
}
@Test
public void doNotAcceptNil_AllowsEmptyArgumentList() {
validator.doNotAcceptNil();
- validator.validate(Nil.getUniqueInstance());
+ validator.validate(Nil.getInstance());
}
@Test
public void doNotAcceptNil_AllowsProperList() {
validator.doNotAcceptNil();
- validator.validate(new Cons(Symbol.T, new Cons(Symbol.T, Nil.getUniqueInstance())));
+ validator.validate(new Cons(Symbol.T, new Cons(Symbol.T, Nil.getInstance())));
}
}
diff --git a/test/function/UserDefinedFunctionTester.java b/test/function/UserDefinedFunctionTester.java
index 7546b74..7ba85ea 100644
--- a/test/function/UserDefinedFunctionTester.java
+++ b/test/function/UserDefinedFunctionTester.java
@@ -13,28 +13,28 @@ public class UserDefinedFunctionTester {
private static final String FUNCTION_NAME = "TEST";
private UserDefinedFunction createNoArgumentFunctionThatReturnsNil() {
- return new UserDefinedFunction(FUNCTION_NAME, Nil.getUniqueInstance(),
- new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance()));
+ return new UserDefinedFunction(FUNCTION_NAME, Nil.getInstance(),
+ new Cons(Nil.getInstance(), Nil.getInstance()));
}
private UserDefinedFunction createOneArgumentFunctionThatReturnsArgument() {
- return new UserDefinedFunction(FUNCTION_NAME, new Cons(new Symbol("X"), Nil.getUniqueInstance()),
- new Cons(new Symbol("X"), Nil.getUniqueInstance()));
+ return new UserDefinedFunction(FUNCTION_NAME, new Cons(new Symbol("X"), Nil.getInstance()),
+ new Cons(new Symbol("X"), Nil.getInstance()));
}
@Test
public void testNilFunctionCall() {
UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil();
- assertEquals(Nil.getUniqueInstance(), function.call(Nil.getUniqueInstance()));
+ assertEquals(Nil.getInstance(), function.call(Nil.getInstance()));
}
@Test
public void testNilFunctionToString() {
UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil();
Cons expected = new Cons(new Symbol(FUNCTION_NAME),
- new Cons(Nil.getUniqueInstance(),
- new Cons(Nil.getUniqueInstance(), Nil.getUniqueInstance())));
+ new Cons(Nil.getInstance(),
+ new Cons(Nil.getInstance(), Nil.getInstance())));
assertSExpressionsMatch(expected, function.getLambdaExpression());
}
@@ -43,7 +43,7 @@ public class UserDefinedFunctionTester {
public void oneArgumentFunction_ReturnsCorrectValue() {
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
SExpression argument = new LispNumber("23");
- Cons argumentList = new Cons(argument, Nil.getUniqueInstance());
+ Cons argumentList = new Cons(argument, Nil.getInstance());
assertSExpressionsMatch(argument, function.call(argumentList));
}
@@ -52,7 +52,7 @@ public class UserDefinedFunctionTester {
public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() {
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
SExpression argument = new LispNumber("23");
- Cons argumentList = new Cons(argument, new Cons(argument, Nil.getUniqueInstance()));
+ Cons argumentList = new Cons(argument, new Cons(argument, Nil.getInstance()));
function.call(argumentList);
}
@@ -61,7 +61,7 @@ public class UserDefinedFunctionTester {
public void oneArgumentFunction_ThrowsExceptionWithTooFewArguments() {
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
- function.call(Nil.getUniqueInstance());
+ function.call(Nil.getInstance());
}
}
diff --git a/test/function/builtin/DIVIDETester.java b/test/function/builtin/DIVIDETester.java
new file mode 100644
index 0000000..634d573
--- /dev/null
+++ b/test/function/builtin/DIVIDETester.java
@@ -0,0 +1,63 @@
+package function.builtin;
+
+import static testutil.TestUtilities.*;
+
+import org.junit.Test;
+
+import function.ArgumentValidator.*;
+
+public class DIVIDETester {
+
+ @Test
+ public void testDivideWithOne() {
+ String input = "(/ 1)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("1"));
+ }
+
+ @Test
+ public void testDivideWithTwo() {
+ String input = "(/ 2)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("0"));
+ }
+
+ @Test
+ public void testDivideTwoNumbers() {
+ String input = "(/ 24 3)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("8"));
+ }
+
+ @Test
+ public void testDivideSeveralNumbers() {
+ String input = "(/ 256 2 2 8)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("8"));
+ }
+
+ @Test
+ public void testDivideTwoNumbersWithRemainder() {
+ String input = "(/ 9 2)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("4"));
+ }
+
+ @Test
+ public void testDivideSeveralNumbersWithRemainder() {
+ String input = "(/ 19 2 5)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("1"));
+ }
+
+ @Test(expected = BadArgumentTypeException.class)
+ public void testDivideWithNonNumber() {
+ evaluateString("(/ 'x)");
+ }
+
+ @Test(expected = TooFewArgumentsException.class)
+ public void testDivideWithTooFewArguments() {
+ evaluateString("(/)");
+ }
+
+}
diff --git a/test/function/builtin/EQTester.java b/test/function/builtin/EQTester.java
new file mode 100644
index 0000000..6af3b00
--- /dev/null
+++ b/test/function/builtin/EQTester.java
@@ -0,0 +1,67 @@
+package function.builtin;
+
+import static testutil.TestUtilities.*;
+
+import org.junit.Test;
+
+import function.ArgumentValidator.*;
+
+public class EQTester {
+
+ @Test
+ public void testEqWithEqualAtoms() {
+ String input = "(eq 1 1)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("t"));
+ }
+
+ @Test
+ public void testEqWithUnequalAtoms() {
+ String input = "(eq 1 2)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("nil"));
+ }
+ @Test
+ public void testEqWithAtomAndList() {
+ String input = "(eq 1 '(2))";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("nil"));
+ }
+
+ @Test
+ public void testEqWithSameList() {
+ String initializeL1 = "(setf l1 '(1 2 3))";
+ String initializeL2 = "(setf l2 l1)";
+ String input = "(eq l1 l2)";
+
+ evaluateString(initializeL1);
+ evaluateString(initializeL2);
+
+ assertSExpressionsMatch(evaluateString(input), parseString("t"));
+ }
+
+ @Test
+ public void testEqWithEqualLists() {
+ String input = "(eq '(1 2) '(1 2))";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("nil"));
+ }
+
+ @Test
+ public void testEqWithUnequalLists() {
+ String input = "(eq '(1 2) '(3 4))";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("nil"));
+ }
+
+ @Test(expected = TooManyArgumentsException.class)
+ public void testEqWithTooManyArguments() {
+ evaluateString("(eq 'one 'two 'three)");
+ }
+
+ @Test(expected = TooFewArgumentsException.class)
+ public void testEqWithTooFewArguments() {
+ evaluateString("(eq 'one)");
+ }
+
+}
diff --git a/test/function/builtin/EQUALSPTester.java b/test/function/builtin/EQUALSPTester.java
new file mode 100644
index 0000000..cd19a3a
--- /dev/null
+++ b/test/function/builtin/EQUALSPTester.java
@@ -0,0 +1,56 @@
+package function.builtin;
+
+import static testutil.TestUtilities.*;
+
+import org.junit.Test;
+
+import function.ArgumentValidator.*;
+
+public class EQUALSPTester {
+
+ @Test
+ public void testEqualspWithOneNumber() {
+ String input = "(= 1)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("t"));
+ }
+
+ @Test
+ public void testEqualspWithEqualNumbers() {
+ String input = "(= 1 1)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("t"));
+ }
+
+ @Test
+ public void testEqualspWithNonEqualNumbers() {
+ String input = "(= 1 2)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("nil"));
+ }
+
+ @Test
+ public void testEqualspWithManyEqualNumbers() {
+ String input = "(= 4 4 4 4 4 4 4 4 4 4)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("t"));
+ }
+
+ @Test
+ public void testEqualspWithManyNonEqualNumbers() {
+ String input = "(= 4 4 4 4 5 4 4 4 4 4)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("nil"));
+ }
+
+ @Test(expected = BadArgumentTypeException.class)
+ public void testEqualspWithNonNumbers() {
+ evaluateString("(= 'x 'x)");
+ }
+
+ @Test(expected = TooFewArgumentsException.class)
+ public void testEqualspWithTooFewArguments() {
+ evaluateString("(=)");
+ }
+
+}
diff --git a/test/function/builtin/EQUALTester.java b/test/function/builtin/EQUALTester.java
new file mode 100644
index 0000000..13e21ce
--- /dev/null
+++ b/test/function/builtin/EQUALTester.java
@@ -0,0 +1,47 @@
+package function.builtin;
+
+import static testutil.TestUtilities.*;
+
+import org.junit.Test;
+
+import function.ArgumentValidator.*;
+
+public class EQUALTester {
+
+ @Test
+ public void testCarWithNil() {
+ String input = "(car nil)";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("()"));
+ }
+
+ @Test
+ public void testCarWithList() {
+ String input = "(car '(1 2 3))";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("1"));
+ }
+
+ @Test
+ public void testNestedCarWithList() {
+ String input = "(car (car '((1 2) 3)))";
+
+ assertSExpressionsMatch(evaluateString(input), parseString("1"));
+ }
+
+ @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)");
+ }
+
+}
diff --git a/test/sexpression/SExpressionTester.java b/test/sexpression/SExpressionTester.java
index 014fa75..4e9a332 100644
--- a/test/sexpression/SExpressionTester.java
+++ b/test/sexpression/SExpressionTester.java
@@ -23,7 +23,7 @@ public class SExpressionTester {
public void testNilToString() {
String input = "NIL";
- assertSExpressionMatchesString(input, Nil.getUniqueInstance());
+ assertSExpressionMatchesString(input, Nil.getInstance());
}
@Test
@@ -57,7 +57,7 @@ public class SExpressionTester {
@Test
public void testSimpleConsToString() {
String expected = "(1)";
- Cons cons = new Cons(new LispNumber("1"), Nil.getUniqueInstance());
+ Cons cons = new Cons(new LispNumber("1"), Nil.getInstance());
assertSExpressionMatchesString(expected, cons);
}
@@ -67,7 +67,7 @@ public class SExpressionTester {
String expected = "(1 A \"string\")";
Cons list = new Cons(new LispNumber("1"),
new Cons(new Symbol("a"),
- new Cons(new LispString("\"string\""), Nil.getUniqueInstance())));
+ new Cons(new LispString("\"string\""), Nil.getInstance())));
assertSExpressionMatchesString(expected, list);
}
@@ -83,7 +83,7 @@ public class SExpressionTester {
@Test
public void testLambdaExpressionToString() {
String expected = "(LAMBDA)";
- LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), Nil.getUniqueInstance()), null);
+ LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), Nil.getInstance()), null);
assertSExpressionMatchesString(expected, lambda);
}
@@ -91,7 +91,7 @@ public class SExpressionTester {
@Test
public void testLambdaExpressionGetLambdaExpression() {
String expected = "(LAMBDA)";
- LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), Nil.getUniqueInstance()), null);
+ LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), Nil.getInstance()), null);
assertSExpressionMatchesString(expected, lambda.getLambdaExpression());
}
@@ -99,9 +99,9 @@ public class SExpressionTester {
@Test
public void testLambdaExpressionGetFunction() {
String expected = "(LAMBDA)";
- UserDefinedFunction function = new UserDefinedFunction(expected, Nil.getUniqueInstance(),
- Nil.getUniqueInstance());
- LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), Nil.getUniqueInstance()),
+ UserDefinedFunction function = new UserDefinedFunction(expected, Nil.getInstance(),
+ Nil.getInstance());
+ LambdaExpression lambda = new LambdaExpression(new Cons(new Symbol("lambda"), Nil.getInstance()),
function);
assertEquals(function, lambda.getFunction());
@@ -109,28 +109,28 @@ public class SExpressionTester {
@Test
public void testCarOfNilIsNil() {
- assertEquals(Nil.getUniqueInstance().getCar(), Nil.getUniqueInstance());
+ assertEquals(Nil.getInstance().getCar(), Nil.getInstance());
}
@Test
public void testCdrOfNilIsNil() {
- assertEquals(Nil.getUniqueInstance().getCdr(), Nil.getUniqueInstance());
+ assertEquals(Nil.getInstance().getCdr(), Nil.getInstance());
}
@Test
public void afterSettingCarOfNil_ShouldStillBeNil() {
- Cons nil = Nil.getUniqueInstance();
+ Cons nil = Nil.getInstance();
nil.setCar(new LispNumber("2"));
- assertEquals(nil.getCar(), Nil.getUniqueInstance());
+ assertEquals(nil.getCar(), Nil.getInstance());
}
@Test
public void afterSettingCdrOfNil_ShouldStillBeNil() {
- Cons nil = Nil.getUniqueInstance();
+ Cons nil = Nil.getInstance();
nil.setCdr(new LispNumber("2"));
- assertEquals(nil.getCdr(), Nil.getUniqueInstance());
+ assertEquals(nil.getCdr(), Nil.getInstance());
}
@Test
diff --git a/test/table/SymbolTableTester.java b/test/table/SymbolTableTester.java
index 6791364..015c62f 100644
--- a/test/table/SymbolTableTester.java
+++ b/test/table/SymbolTableTester.java
@@ -35,8 +35,8 @@ public class SymbolTableTester {
@Test
public void redefineSymbolValue() {
symbolTable.put("symbol", Symbol.T);
- symbolTable.put("symbol", Nil.getUniqueInstance());
- assertEquals(symbolTable.get("symbol"), Nil.getUniqueInstance());
+ symbolTable.put("symbol", Nil.getInstance());
+ assertEquals(symbolTable.get("symbol"), Nil.getInstance());
}
@Test
diff --git a/test/testutil/SExpressionTypeAssertions.java b/test/testutil/SExpressionTypeAssertions.java
index 6d8acf8..9b8126c 100644
--- a/test/testutil/SExpressionTypeAssertions.java
+++ b/test/testutil/SExpressionTypeAssertions.java
@@ -18,7 +18,7 @@ public final class SExpressionTypeAssertions {
}
public static void assertNil(SExpression sExpression) {
- assertEquals(sExpression, Nil.getUniqueInstance());
+ assertEquals(sExpression, Nil.getInstance());
assertTrue(sExpression.atomp());
assertFalse(sExpression.consp());