Resolves #11 - The CASE special function has been added
Refactored some unit tests
This commit is contained in:
parent
544df91c27
commit
05f75b627b
|
@ -6,6 +6,10 @@ import sexpression.*;
|
||||||
@FunctionNames({ "EQUAL" })
|
@FunctionNames({ "EQUAL" })
|
||||||
public class EQUAL extends LispFunction {
|
public class EQUAL extends LispFunction {
|
||||||
|
|
||||||
|
public static boolean isEqual(SExpression firstArgument, SExpression secondArgument) {
|
||||||
|
return firstArgument.toString().equals(secondArgument.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private ArgumentValidator argumentValidator;
|
private ArgumentValidator argumentValidator;
|
||||||
|
|
||||||
public EQUAL() {
|
public EQUAL() {
|
||||||
|
@ -27,8 +31,4 @@ public class EQUAL extends LispFunction {
|
||||||
return isEqual(firstArgument, secondArgument) ? Symbol.T : Nil.getInstance();
|
return isEqual(firstArgument, secondArgument) ? Symbol.T : Nil.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEqual(SExpression firstArgument, SExpression secondArgument) {
|
|
||||||
return firstArgument.toString().equals(secondArgument.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package function.builtin.special;
|
||||||
|
|
||||||
|
import static function.builtin.EVAL.eval;
|
||||||
|
import static function.builtin.predicate.EQUAL.isEqual;
|
||||||
|
|
||||||
|
import function.*;
|
||||||
|
import sexpression.*;
|
||||||
|
|
||||||
|
@FunctionNames({ "CASE" })
|
||||||
|
public class CASE extends LispSpecialFunction {
|
||||||
|
|
||||||
|
private ArgumentValidator argumentValidator;
|
||||||
|
|
||||||
|
public CASE() {
|
||||||
|
this.argumentValidator = new ArgumentValidator("CASE");
|
||||||
|
this.argumentValidator.setMinimumNumberOfArguments(1);
|
||||||
|
this.argumentValidator.setTrailingArgumentExpectedType(Cons.class);
|
||||||
|
this.argumentValidator.doNotAcceptNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SExpression call(Cons argumentList) {
|
||||||
|
argumentValidator.validate(argumentList);
|
||||||
|
SExpression key = eval(argumentList.getFirst());
|
||||||
|
|
||||||
|
return callTailRecursive(key, (Cons) argumentList.getRest());
|
||||||
|
}
|
||||||
|
|
||||||
|
private SExpression callTailRecursive(SExpression key, Cons argumentList) {
|
||||||
|
if (argumentList.isNull())
|
||||||
|
return Nil.getInstance();
|
||||||
|
|
||||||
|
Cons clause = (Cons) argumentList.getFirst();
|
||||||
|
Cons remainingClauses = (Cons) argumentList.getRest();
|
||||||
|
SExpression keyList = clause.getFirst();
|
||||||
|
|
||||||
|
if (isMatch(key, keyList))
|
||||||
|
return evaluateResult(clause);
|
||||||
|
|
||||||
|
return callTailRecursive(key, remainingClauses);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMatch(SExpression key, SExpression keyList) {
|
||||||
|
if (keyList.isNull())
|
||||||
|
return false;
|
||||||
|
else if (keyList.isCons())
|
||||||
|
return containsMatch(key, keyList);
|
||||||
|
|
||||||
|
return isEqual(key, keyList) || isKeyListT(keyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsMatch(SExpression key, SExpression keyList) {
|
||||||
|
for (; keyList.isCons(); keyList = advanceCons(keyList))
|
||||||
|
if (isEqual(key, getFirst(keyList)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isKeyListT(SExpression keyList) {
|
||||||
|
return isEqual(Symbol.T, keyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SExpression advanceCons(SExpression knownCons) {
|
||||||
|
return ((Cons) knownCons).getRest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SExpression getFirst(SExpression knownCons) {
|
||||||
|
return ((Cons) knownCons).getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SExpression evaluateResult(Cons clause) {
|
||||||
|
SExpression lastResultValue = Nil.getInstance();
|
||||||
|
|
||||||
|
for (SExpression result = clause.getRest(); result.isCons(); result = advanceCons(result))
|
||||||
|
lastResultValue = eval(getFirst(result));
|
||||||
|
|
||||||
|
return lastResultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ public class FunctionTable {
|
||||||
allBuiltIns.add(AND.class);
|
allBuiltIns.add(AND.class);
|
||||||
allBuiltIns.add(APPLY.class);
|
allBuiltIns.add(APPLY.class);
|
||||||
allBuiltIns.add(ATOM.class);
|
allBuiltIns.add(ATOM.class);
|
||||||
|
allBuiltIns.add(CASE.class);
|
||||||
allBuiltIns.add(COND.class);
|
allBuiltIns.add(COND.class);
|
||||||
allBuiltIns.add(CONS.class);
|
allBuiltIns.add(CONS.class);
|
||||||
allBuiltIns.add(DEFINE_MACRO.class);
|
allBuiltIns.add(DEFINE_MACRO.class);
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
package function.builtin.special;
|
||||||
|
|
||||||
|
import static testutil.TestUtilities.*;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import function.ArgumentValidator.*;
|
||||||
|
import table.ExecutionContext;
|
||||||
|
|
||||||
|
public class CASETester {
|
||||||
|
|
||||||
|
private ExecutionContext executionContext;
|
||||||
|
|
||||||
|
public CASETester() {
|
||||||
|
this.executionContext = ExecutionContext.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
executionContext.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
executionContext.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithOnlySwitchExpression() {
|
||||||
|
String input = "(case t)";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithEmptyConsequent() {
|
||||||
|
String input = "(case :a ((:a)))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithOneClause_Match() {
|
||||||
|
String input = "(case :a ((:a) 'banana))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("banana"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithOneClause_NoMatch() {
|
||||||
|
String input = "(case :a ((:b) 'banana))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithSeveralClauses_Match() {
|
||||||
|
String input = "(case :a ((:b) 'orange) ((:a) 'banana))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("banana"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithSeveralClauses_NoMatch() {
|
||||||
|
String input = "(case :a ((:b) 'orange) ((:c) 'banana))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithSymbolicKeyList_Match() {
|
||||||
|
String input = "(case :a (:a 'orange))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("orange"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithSymbolicKeyList_NoMatch() {
|
||||||
|
String input = "(case :a (:b 'orange))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithEmptyKeyList() {
|
||||||
|
String input = "(case nil (() 'orange))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithNil() {
|
||||||
|
String input = "(case nil ((nil) 'orange))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("orange"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithDefaultClause() {
|
||||||
|
String input = "(case nil (() 'banana) (t 'orange))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("orange"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithOutOfOrderDefaultClause() {
|
||||||
|
String input = "(case :a (t 'orange) (:a 'banana))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("orange"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithKeyListContainingT() {
|
||||||
|
String input = "(case t ((t) 'banana))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("banana"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseWithMultipleMatches_ReturnsFirst() {
|
||||||
|
String input = "(case 2 ((0) 'banana) ((1) 'apple) ((2) 'avocado) ((2) 'greenbean))";
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("avocado"), evaluateString(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseOnlyEvaluatesFirstMatchingClause() {
|
||||||
|
String input = "(case 2 ((0) (setf zero 0)) ((1) (setf one 1)) ((2) (setf two '2)) ((2) (setf two 'two)))";
|
||||||
|
|
||||||
|
evaluateString("(setf zero nil)");
|
||||||
|
evaluateString("(setf one nil)");
|
||||||
|
evaluateString(input);
|
||||||
|
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString("zero"));
|
||||||
|
assertSExpressionsMatch(parseString("nil"), evaluateString("one"));
|
||||||
|
assertSExpressionsMatch(parseString("2"), evaluateString("two"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
|
public void caseWithTooFewArguments() {
|
||||||
|
evaluateString("(case)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
|
public void caseWithNonListClause() {
|
||||||
|
evaluateString("(case :a t)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,80 +9,80 @@ import function.ArgumentValidator.*;
|
||||||
public class CONDTester {
|
public class CONDTester {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithNoArguments() {
|
public void condWithNoArguments() {
|
||||||
String input = "(cond)";
|
String input = "(cond)";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithTrue() {
|
public void condWithTrue() {
|
||||||
String input = "(cond (T))";
|
String input = "(cond (T))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("T"), evaluateString(input));
|
assertSExpressionsMatch(parseString("T"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithNumber() {
|
public void condWithNumber() {
|
||||||
String input = "(cond ((+ 1 2)))";
|
String input = "(cond ((+ 1 2)))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithSingleExpression() {
|
public void condWithSingleExpression() {
|
||||||
String input = "(cond (T \"true\"))";
|
String input = "(cond (T \"true\"))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("\"true\""), evaluateString(input));
|
assertSExpressionsMatch(parseString("\"true\""), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithMultipleExpressions() {
|
public void condWithMultipleExpressions() {
|
||||||
String input = "(cond ((= 1 2) 2) ((= 1 2) 2) ((= 1 1) 3))";
|
String input = "(cond ((= 1 2) 2) ((= 1 2) 2) ((= 1 1) 3))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
assertSExpressionsMatch(parseString("3"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithMultipleConditionsMatching_ReturnFirstOne() {
|
public void condWithMultipleConditionsMatching_ReturnFirstOne() {
|
||||||
String input = "(cond ((= 1 1) 2) ((= 1 1) 3))";
|
String input = "(cond ((= 1 1) 2) ((= 1 1) 3))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithMultipleConditionsMatching_OnlyEvaluatesFirstOne() {
|
public void condWithMultipleConditionsMatching_OnlyEvaluatesFirstOne() {
|
||||||
String input = "(cond ((= 1 1) 2) ((= 1 1) x))";
|
String input = "(cond ((= 1 1) 2) ((= 1 1) x))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
assertSExpressionsMatch(parseString("2"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithMultipleResultValues_OnlyReturnsLast() {
|
public void condWithMultipleResultValues_OnlyReturnsLast() {
|
||||||
String input = "(cond ((= 1 1) 2 3 4))";
|
String input = "(cond ((= 1 1) 2 3 4))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("4"), evaluateString(input));
|
assertSExpressionsMatch(parseString("4"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCondWithNoConditionMatching_ReturnsNil() {
|
public void condWithNoConditionMatching_ReturnsNil() {
|
||||||
String input = "(cond ((= 1 2) T) ((= 1 3) T))";
|
String input = "(cond ((= 1 2) T) ((= 1 3) T))";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
assertSExpressionsMatch(parseString("nil"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testCondWithNilArgument_ThrowsException() {
|
public void condWithNilArgument_ThrowsException() {
|
||||||
evaluateString("(cond ())");
|
evaluateString("(cond ())");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testCondWithNonListArgument_ThrowsException() {
|
public void condWithNonListArgument_ThrowsException() {
|
||||||
evaluateString("(cond o)");
|
evaluateString("(cond o)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void testCondWithDottedArgumentList_ThrowsException() {
|
public void condWithDottedArgumentList_ThrowsException() {
|
||||||
evaluateString("(apply 'cond (cons '(nil T) 'b))");
|
evaluateString("(apply 'cond (cons '(nil T) 'b))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class DEFINE_MACROTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacro() {
|
public void defineMacro() {
|
||||||
String input = "(define-macro f () t)";
|
String input = "(define-macro f () t)";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("f"), evaluateString(input));
|
assertSExpressionsMatch(parseString("f"), evaluateString(input));
|
||||||
|
@ -50,7 +50,7 @@ public class DEFINE_MACROTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacroWithEmptyBody() {
|
public void defineMacroWithEmptyBody() {
|
||||||
String input = "(define-macro f ())";
|
String input = "(define-macro f ())";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("f"), evaluateString(input));
|
assertSExpressionsMatch(parseString("f"), evaluateString(input));
|
||||||
|
@ -58,26 +58,26 @@ public class DEFINE_MACROTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacroDoesNotEvaluatesArguments() {
|
public void defineMacroDoesNotEvaluatesArguments() {
|
||||||
evaluateString("(define-macro f (x) (car x))");
|
evaluateString("(define-macro f (x) (car x))");
|
||||||
assertSExpressionsMatch(parseString("quote"), evaluateString("(f '(1 2 3))"));
|
assertSExpressionsMatch(parseString("quote"), evaluateString("(f '(1 2 3))"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacroAdd() {
|
public void defineMacroAdd() {
|
||||||
evaluateString("(define-macro f (x) (+ (eval x) 23))");
|
evaluateString("(define-macro f (x) (+ (eval x) 23))");
|
||||||
assertSExpressionsMatch(parseString("27"), evaluateString("(f (+ 2 2))"));
|
assertSExpressionsMatch(parseString("27"), evaluateString("(f (+ 2 2))"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacroSetVariable() {
|
public void defineMacroSetVariable() {
|
||||||
evaluateString("(define-macro f (x) (set x 23))");
|
evaluateString("(define-macro f (x) (set x 23))");
|
||||||
evaluateString("(f y)");
|
evaluateString("(f y)");
|
||||||
assertSExpressionsMatch(parseString("23"), evaluateString("y"));
|
assertSExpressionsMatch(parseString("23"), evaluateString("y"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacroVariableCapture() {
|
public void defineMacroVariableCapture() {
|
||||||
evaluateString("(setf x 0)");
|
evaluateString("(setf x 0)");
|
||||||
evaluateString("(define-macro f (x) (set x 23))");
|
evaluateString("(define-macro f (x) (set x 23))");
|
||||||
evaluateString("(f x)");
|
evaluateString("(f x)");
|
||||||
|
@ -85,7 +85,7 @@ public class DEFINE_MACROTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefineMacroAvoidVariableCaptureConvention() {
|
public void defineMacroAvoidVariableCaptureConvention() {
|
||||||
evaluateString("(setf x 0)");
|
evaluateString("(setf x 0)");
|
||||||
evaluateString("(define-macro f (-x-) (set -x- 23))");
|
evaluateString("(define-macro f (-x-) (set -x- 23))");
|
||||||
evaluateString("(f x)");
|
evaluateString("(f x)");
|
||||||
|
@ -111,22 +111,22 @@ public class DEFINE_MACROTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void testDefineMacroWithDottedLambdaList() {
|
public void defineMacroWithDottedLambdaList() {
|
||||||
evaluateString("(funcall 'define-macro 'x (cons 'a 'b) ())");
|
evaluateString("(funcall 'define-macro 'x (cons 'a 'b) ())");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testDefineMacroWithNonSymbolName() {
|
public void defineMacroWithNonSymbolName() {
|
||||||
evaluateString("(define-macro 1 () ())");
|
evaluateString("(define-macro 1 () ())");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testDefineMacroWithBadLambdaList() {
|
public void defineMacroWithBadLambdaList() {
|
||||||
evaluateString("(define-macro x a ())");
|
evaluateString("(define-macro x a ())");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooFewArgumentsException.class)
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
public void testDefineMacroWithTooFewArguments() {
|
public void defineMacroWithTooFewArguments() {
|
||||||
evaluateString("(define-macro x)");
|
evaluateString("(define-macro x)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,47 +110,47 @@ public class LETTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testLetWithNonList() {
|
public void letWithNonList() {
|
||||||
evaluateString("(let a)");
|
evaluateString("(let a)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testLetWithNoPairs() {
|
public void letWithNoPairs() {
|
||||||
evaluateString("(let (a))");
|
evaluateString("(let (a))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooFewArgumentsException.class)
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
public void testLetWithTooFewItemsInPair() {
|
public void letWithTooFewItemsInPair() {
|
||||||
evaluateString("(let ((a)))");
|
evaluateString("(let ((a)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooManyArgumentsException.class)
|
@Test(expected = TooManyArgumentsException.class)
|
||||||
public void testLetWithTooManyItemsInPair() {
|
public void letWithTooManyItemsInPair() {
|
||||||
evaluateString("(let ((a b c)))");
|
evaluateString("(let ((a b c)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testLetWithNonSymbolInPair() {
|
public void letWithNonSymbolInPair() {
|
||||||
evaluateString("(let ((1 b)))");
|
evaluateString("(let ((1 b)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooFewArgumentsException.class)
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
public void testLetWithTooFewArguments() {
|
public void letWithTooFewArguments() {
|
||||||
evaluateString("(let)");
|
evaluateString("(let)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void testLetWithDottedArgumentList() {
|
public void letWithDottedArgumentList() {
|
||||||
evaluateString("(apply 'let (cons 'a 'b))");
|
evaluateString("(apply 'let (cons 'a 'b))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void testLetWithDottedPairList() {
|
public void letWithDottedPairList() {
|
||||||
evaluateString("(apply 'let (cons (cons 'a 'b) nil))");
|
evaluateString("(apply 'let (cons (cons 'a 'b) nil))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void testLetWithDottedPair() {
|
public void letWithDottedPair() {
|
||||||
evaluateString("(apply 'let (cons (cons (cons 'a 'b) nil) nil))");
|
evaluateString("(apply 'let (cons (cons (cons 'a 'b) nil) nil))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,26 +9,26 @@ import function.ArgumentValidator.*;
|
||||||
public class QUOTETester {
|
public class QUOTETester {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQuoteSymbol() {
|
public void quoteSymbol() {
|
||||||
String input = "'a";
|
String input = "'a";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("a"), evaluateString(input));
|
assertSExpressionsMatch(parseString("a"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQuoteList() {
|
public void quoteList() {
|
||||||
String input = "'(l i s t)";
|
String input = "'(l i s t)";
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("(l i s t)"), evaluateString(input));
|
assertSExpressionsMatch(parseString("(l i s t)"), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooFewArgumentsException.class)
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
public void testQuoteWithTooFewArguments() {
|
public void quoteWithTooFewArguments() {
|
||||||
evaluateString("(quote)");
|
evaluateString("(quote)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooManyArgumentsException.class)
|
@Test(expected = TooManyArgumentsException.class)
|
||||||
public void testQuoteWithTooManyArguments() {
|
public void quoteWithTooManyArguments() {
|
||||||
evaluateString("(quote a b)");
|
evaluateString("(quote a b)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,17 @@ public class SETFTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetf() {
|
public void setf() {
|
||||||
evaluateString("(setf a 23)");
|
evaluateString("(setf a 23)");
|
||||||
assertSExpressionsMatch(new LispNumber("23"), evaluateString("a"));
|
assertSExpressionsMatch(new LispNumber("23"), evaluateString("a"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setq() {
|
||||||
|
evaluateString("(setq a 23)");
|
||||||
|
assertSExpressionsMatch(new LispNumber("23"), evaluateString("a"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lookupDefinedSymbol() {
|
public void lookupDefinedSymbol() {
|
||||||
evaluateString("(setf a 23)");
|
evaluateString("(setf a 23)");
|
||||||
|
@ -56,6 +62,17 @@ public class SETFTester {
|
||||||
assertSExpressionsMatch(new LispNumber("94"), evaluateString("a"));
|
assertSExpressionsMatch(new LispNumber("94"), evaluateString("a"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setfLocalVariable() {
|
||||||
|
SymbolTable global = executionContext.getScope();
|
||||||
|
SymbolTable local = new SymbolTable(global);
|
||||||
|
local.put("A", new LispNumber("99"));
|
||||||
|
executionContext.setScope(local);
|
||||||
|
|
||||||
|
evaluateString("(setf a 94)");
|
||||||
|
assertSExpressionsMatch(new LispNumber("94"), evaluateString("a"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = UndefinedSymbolException.class)
|
@Test(expected = UndefinedSymbolException.class)
|
||||||
public void setfLocalVariableDefined_DoesNotSetGlobal() {
|
public void setfLocalVariableDefined_DoesNotSetGlobal() {
|
||||||
SymbolTable global = executionContext.getScope();
|
SymbolTable global = executionContext.getScope();
|
||||||
|
@ -80,17 +97,17 @@ public class SETFTester {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void testSetfWithNonSymbol() {
|
public void setfWithNonSymbol() {
|
||||||
evaluateString("(setf 1 2)");
|
evaluateString("(setf 1 2)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooFewArgumentsException.class)
|
@Test(expected = TooFewArgumentsException.class)
|
||||||
public void testSetfWithTooFewArguments() {
|
public void setfWithTooFewArguments() {
|
||||||
evaluateString("(setf x)");
|
evaluateString("(setf x)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TooManyArgumentsException.class)
|
@Test(expected = TooManyArgumentsException.class)
|
||||||
public void testSetfWithTooManyArguments() {
|
public void setfWithTooManyArguments() {
|
||||||
evaluateString("(setf a b c)");
|
evaluateString("(setf a b c)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue