diff --git a/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki b/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki new file mode 100644 index 0000000..fdfe34a --- /dev/null +++ b/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodClosure.wiki @@ -0,0 +1,24 @@ +--- +Test +--- +| script | lisp interpreter fixture | +| # | Object with multiple methods | +| show | evaluate |!- + +(defun counter-class-multi () + (let ((counter 0)) + (lambda (msg) + (case msg + ((:inc) + (setq counter (+ counter 1))) + ((:dec) + (setq counter (- counter 1))))))) + + -!| +| show | evaluate | (setq my-counter (counter-class-multi)) | +| check | evaluate | (funcall my-counter :inc) | 1 | +| check | evaluate | (funcall my-counter :inc) | 2 | +| check | evaluate | (funcall my-counter :inc) | 3 | +| check | evaluate | (funcall my-counter :dec) | 2 | +| check | evaluate | (funcall my-counter :dec) | 1 | +| check | evaluate | (funcall my-counter :dec) | 0 | diff --git a/fitnesse/FitNesseRoot/RecentChanges.wiki b/fitnesse/FitNesseRoot/RecentChanges.wiki index a85c5af..be31fa4 100644 --- a/fitnesse/FitNesseRoot/RecentChanges.wiki +++ b/fitnesse/FitNesseRoot/RecentChanges.wiki @@ -1,3 +1,4 @@ +|LispInterpreter.MultipleMethodClosure||11:52:11 Tue, Feb 28, 2017| |LispInterpreter.LexicalClosures||12:10:13 Mon, Feb 27, 2017| |LispInterpreter.TestClosure||11:24:27 Mon, Feb 27, 2017| |LispInterpreter.TestOne||09:26:08 Fri, Feb 24, 2017| diff --git a/src/function/builtin/predicate/EQ.java b/src/function/builtin/predicate/EQ.java index 0fd581f..e305dd9 100644 --- a/src/function/builtin/predicate/EQ.java +++ b/src/function/builtin/predicate/EQ.java @@ -35,7 +35,11 @@ public class EQ extends LispFunction { } private SExpression atomEq(SExpression firstArgument, SExpression secondArgument) { - return (firstArgument.toString().equals(secondArgument.toString())) ? Symbol.T : Nil.getInstance(); + return isEq(firstArgument, secondArgument) ? Symbol.T : Nil.getInstance(); + } + + private boolean isEq(SExpression firstArgument, SExpression secondArgument) { + return firstArgument.toString().equals(secondArgument.toString()); } private SExpression listEq(SExpression firstArgument, SExpression secondArgument) { diff --git a/src/function/builtin/predicate/EQUAL.java b/src/function/builtin/predicate/EQUAL.java index eccbd38..1ab136f 100644 --- a/src/function/builtin/predicate/EQUAL.java +++ b/src/function/builtin/predicate/EQUAL.java @@ -25,9 +25,21 @@ public class EQUAL extends LispFunction { SExpression firstArgument = argumentList.getFirst(); SExpression secondArgument = rest.getFirst(); - if (!isListPair(firstArgument, secondArgument)) - return equal(firstArgument, secondArgument); + return equal(firstArgument, secondArgument); + } + private SExpression equal(SExpression firstArgument, SExpression secondArgument) { + if (isListPair(firstArgument, secondArgument)) + return listEqual(firstArgument, secondArgument); + + return atomEqual(firstArgument, secondArgument); + } + + private boolean isListPair(SExpression firstArgument, SExpression secondArgument) { + return firstArgument.isCons() && secondArgument.isCons(); + } + + private SExpression listEqual(SExpression firstArgument, SExpression secondArgument) { Cons listOne = (Cons) firstArgument; Cons listTwo = (Cons) secondArgument; SExpression listOneFirst = listOne.getFirst(); @@ -41,20 +53,8 @@ public class EQUAL extends LispFunction { return logicalConjunction(firstEqual, restEqual); } - private boolean isListPair(SExpression firstArgument, SExpression secondArgument) { - return firstArgument.isCons() && secondArgument.isCons(); - } - - private SExpression equal(SExpression firstArgument, SExpression secondArgument) { - return isEqual(firstArgument, secondArgument) ? Symbol.T : Nil.getInstance(); - } - - private boolean isEqual(SExpression firstArgument, SExpression secondArgument) { - return firstArgument.toString().equals(secondArgument.toString()); - } - - private Cons makeArgumentList(SExpression listOneFirst, SExpression listTwoFirst) { - return new Cons(listOneFirst, LIST.makeList(listTwoFirst)); + private Cons makeArgumentList(SExpression one, SExpression two) { + return new Cons(one, LIST.makeList(two)); } private SExpression logicalConjunction(SExpression firstEqual, SExpression restEqual) { @@ -65,4 +65,12 @@ public class EQUAL extends LispFunction { return (firstEqual == Symbol.T) && (restEqual == Symbol.T); } + private SExpression atomEqual(SExpression firstArgument, SExpression secondArgument) { + return isEqual(firstArgument, secondArgument) ? Symbol.T : Nil.getInstance(); + } + + private boolean isEqual(SExpression firstArgument, SExpression secondArgument) { + return firstArgument.toString().equals(secondArgument.toString()); + } + } diff --git a/src/function/builtin/predicate/EQUALSP.java b/src/function/builtin/predicate/NUMERIC_EQUAL.java similarity index 94% rename from src/function/builtin/predicate/EQUALSP.java rename to src/function/builtin/predicate/NUMERIC_EQUAL.java index 90c1084..452b18b 100644 --- a/src/function/builtin/predicate/EQUALSP.java +++ b/src/function/builtin/predicate/NUMERIC_EQUAL.java @@ -4,11 +4,11 @@ import function.*; import sexpression.*; @FunctionNames({ "=" }) -public class EQUALSP extends LispFunction { +public class NUMERIC_EQUAL extends LispFunction { private ArgumentValidator argumentValidator; - public EQUALSP() { + public NUMERIC_EQUAL() { this.argumentValidator = new ArgumentValidator("="); this.argumentValidator.setMinimumNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class); diff --git a/src/function/builtin/predicate/GREATERP.java b/src/function/builtin/predicate/NUMERIC_GREATER.java similarity index 93% rename from src/function/builtin/predicate/GREATERP.java rename to src/function/builtin/predicate/NUMERIC_GREATER.java index d144861..4d2bd37 100644 --- a/src/function/builtin/predicate/GREATERP.java +++ b/src/function/builtin/predicate/NUMERIC_GREATER.java @@ -4,11 +4,11 @@ import function.*; import sexpression.*; @FunctionNames({ ">" }) -public class GREATERP extends LispFunction { +public class NUMERIC_GREATER extends LispFunction { private ArgumentValidator argumentValidator; - public GREATERP() { + public NUMERIC_GREATER() { this.argumentValidator = new ArgumentValidator(">"); this.argumentValidator.setMinimumNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class); diff --git a/src/function/builtin/predicate/LESSP.java b/src/function/builtin/predicate/NUMERIC_LESS.java similarity index 94% rename from src/function/builtin/predicate/LESSP.java rename to src/function/builtin/predicate/NUMERIC_LESS.java index 19090d1..ec7f2b8 100644 --- a/src/function/builtin/predicate/LESSP.java +++ b/src/function/builtin/predicate/NUMERIC_LESS.java @@ -4,11 +4,11 @@ import function.*; import sexpression.*; @FunctionNames({ "<" }) -public class LESSP extends LispFunction { +public class NUMERIC_LESS extends LispFunction { private ArgumentValidator argumentValidator; - public LESSP() { + public NUMERIC_LESS() { this.argumentValidator = new ArgumentValidator("<"); this.argumentValidator.setMinimumNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class); diff --git a/src/table/FunctionTable.java b/src/table/FunctionTable.java index 0319e1b..d880a35 100644 --- a/src/table/FunctionTable.java +++ b/src/table/FunctionTable.java @@ -46,16 +46,16 @@ public class FunctionTable { allBuiltIns.add(DIVIDE.class); allBuiltIns.add(EQ.class); allBuiltIns.add(EQUAL.class); - allBuiltIns.add(EQUALSP.class); + allBuiltIns.add(NUMERIC_EQUAL.class); allBuiltIns.add(EVAL.class); allBuiltIns.add(EXIT.class); allBuiltIns.add(FIRST.class); allBuiltIns.add(FUNCALL.class); - allBuiltIns.add(GREATERP.class); + allBuiltIns.add(NUMERIC_GREATER.class); allBuiltIns.add(IF.class); allBuiltIns.add(LAMBDA.class); allBuiltIns.add(LENGTH.class); - allBuiltIns.add(LESSP.class); + allBuiltIns.add(NUMERIC_LESS.class); allBuiltIns.add(LET.class); allBuiltIns.add(LIST.class); allBuiltIns.add(LISTP.class); diff --git a/test/function/builtin/predicate/EQTester.java b/test/function/builtin/predicate/EQTester.java index d8f9440..d35a49f 100644 --- a/test/function/builtin/predicate/EQTester.java +++ b/test/function/builtin/predicate/EQTester.java @@ -10,28 +10,63 @@ import function.ArgumentValidator.*; public class EQTester { @Test - public void testEqWithEqualAtoms() { + public void eqWithEqualAtoms() { String input = "(eq 1 1)"; assertT(evaluateString(input)); } @Test - public void testEqWithUnequalAtoms() { + public void eqWithUnequalAtoms() { String input = "(eq 1 2)"; assertNil(evaluateString(input)); } @Test - public void testEqWithAtomAndList() { + public void eqWithTwoEqualNumbers() { + String input = "(eq -4 -4)"; + + assertT(evaluateString(input)); + } + + @Test + public void eqWithTwoUnequalNumbers() { + String input = "(eq +5 +7)"; + + assertNil(evaluateString(input)); + } + + @Test + public void eqWithTwoEqualStrings() { + String input = "(eq \"potato\" \"potato\")"; + + assertT(evaluateString(input)); + } + + @Test + public void eqWithTwoUnequalStrings() { + String input = "(eq \"tomato\" \"potato\")"; + + assertNil(evaluateString(input)); + } + + @Test + public void eqWithTwoDifferentCasedStrings() { + String input = "(eq \"Potato\" \"potato\")"; + + assertNil(evaluateString(input)); + } + + @Test + public void eqWithAtomAndList() { String input = "(eq 1 '(2))"; assertNil(evaluateString(input)); } @Test - public void testEqWithSameList() { + public void eqWithSameList() { String initializeL1 = "(setf l1 '(1 2 3))"; String initializeL2 = "(setf l2 l1)"; String input = "(eq l1 l2)"; @@ -43,26 +78,26 @@ public class EQTester { } @Test - public void testEqWithEqualLists() { + public void eqWithEqualLists() { String input = "(eq '(1 2) '(1 2))"; assertNil(evaluateString(input)); } @Test - public void testEqWithUnequalLists() { + public void eqWithUnequalLists() { String input = "(eq '(1 2) '(3 4))"; assertNil(evaluateString(input)); } @Test(expected = TooManyArgumentsException.class) - public void testEqWithTooManyArguments() { + public void eqWithTooManyArguments() { evaluateString("(eq 'one 'two 'three)"); } @Test(expected = TooFewArgumentsException.class) - public void testEqWithTooFewArguments() { + public void eqWithTooFewArguments() { evaluateString("(eq 'one)"); } diff --git a/test/function/builtin/predicate/EQUALTester.java b/test/function/builtin/predicate/EQUALTester.java index e25e2ac..ddd9c58 100644 --- a/test/function/builtin/predicate/EQUALTester.java +++ b/test/function/builtin/predicate/EQUALTester.java @@ -10,61 +10,96 @@ import function.ArgumentValidator.*; public class EQUALTester { @Test - public void testEqualWithTwoEqualAtoms() { + public void equalWithTwoEqualAtoms() { String input = "(equal 'a 'a)"; assertT(evaluateString(input)); } @Test - public void testEqualWithTwoUnequalAtoms() { + public void equalWithTwoUnequalAtoms() { String input = "(equal 'a 'b)"; assertNil(evaluateString(input)); } @Test - public void testEqualWithAtomAndList() { + public void equalWithTwoEqualNumbers() { + String input = "(equal -4 -4)"; + + assertT(evaluateString(input)); + } + + @Test + public void equalWithTwoUnequalNumbers() { + String input = "(equal +5 +7)"; + + assertNil(evaluateString(input)); + } + + @Test + public void equalWithTwoEqualStrings() { + String input = "(equal \"potato\" \"potato\")"; + + assertT(evaluateString(input)); + } + + @Test + public void equalWithTwoUnequalStrings() { + String input = "(equal \"tomato\" \"potato\")"; + + assertNil(evaluateString(input)); + } + + @Test + public void equalWithTwoDifferentCasedStrings() { + String input = "(equal \"Potato\" \"potato\")"; + + assertNil(evaluateString(input)); + } + + @Test + public void equalWithAtomAndList() { String input = "(equal \"string\" '(m i k e))"; assertNil(evaluateString(input)); } @Test - public void testEqualWithListAndAtom() { + public void equalWithListAndAtom() { String input = "(equal '(m i k e) \"string\")"; assertNil(evaluateString(input)); } @Test - public void testEqualWithTwoEqualLists() { + public void equalWithTwoEqualLists() { String input = "(equal '(1 2 3) '(1 2 3))"; assertT(evaluateString(input)); } @Test - public void testEqualWithTwoUnequalLists() { + public void equalWithTwoUnequalLists() { String input = "(equal '(1 2 3) '(1 3 3))"; assertNil(evaluateString(input)); } @Test - public void testEqualWithTwoEqualNestedLists() { + public void equalWithTwoEqualNestedLists() { String input = "(equal '(1 ((2) 3)) '(1 ((2) 3)))"; assertT(evaluateString(input)); } @Test(expected = TooManyArgumentsException.class) - public void testEqualWithTooManyArguments() { + public void equalWithTooManyArguments() { evaluateString("(equal 1 2 3)"); } @Test(expected = TooFewArgumentsException.class) - public void testEqualWithTooFewArguments() { + public void equalWithTooFewArguments() { evaluateString("(equal 1)"); } diff --git a/test/function/builtin/predicate/LISTPTester.java b/test/function/builtin/predicate/LISTPTester.java index c8e755a..0f760ce 100644 --- a/test/function/builtin/predicate/LISTPTester.java +++ b/test/function/builtin/predicate/LISTPTester.java @@ -10,22 +10,22 @@ import function.ArgumentValidator.*; public class LISTPTester { @Test - public void testListpWithList_ReturnsT() { + public void listpWithList() { assertT(evaluateString("(listp '(1))")); } @Test - public void testListWithNonList_ReturnsNil() { + public void listpWithNonList() { assertNil(evaluateString("(listp 1)")); } @Test(expected = TooFewArgumentsException.class) - public void testListpWithTooFewArguments() { + public void listpWithTooFewArguments() { evaluateString("(listp)"); } @Test(expected = TooManyArgumentsException.class) - public void testListpWithTooManyArguments() { + public void listpWithTooManyArguments() { evaluateString("(listp '() '())"); } diff --git a/test/function/builtin/predicate/EQUALSPTester.java b/test/function/builtin/predicate/NUMERIC_EQUALTester.java similarity index 69% rename from test/function/builtin/predicate/EQUALSPTester.java rename to test/function/builtin/predicate/NUMERIC_EQUALTester.java index 2294282..8aa4f36 100644 --- a/test/function/builtin/predicate/EQUALSPTester.java +++ b/test/function/builtin/predicate/NUMERIC_EQUALTester.java @@ -7,50 +7,50 @@ import org.junit.Test; import function.ArgumentValidator.*; -public class EQUALSPTester { +public class NUMERIC_EQUALTester { @Test - public void testEqualspWithOneNumber() { + public void numericEqualWithOneNumber() { String input = "(= 1)"; assertT(evaluateString(input)); } @Test - public void testEqualspWithEqualNumbers() { + public void numericEqualWithEqualNumbers() { String input = "(= 1 1)"; assertT(evaluateString(input)); } @Test - public void testEqualspWithNonEqualNumbers() { + public void numericEqualWithNonEqualNumbers() { String input = "(= 1 2)"; assertNil(evaluateString(input)); } @Test - public void testEqualspWithManyEqualNumbers() { + public void numericEqualWithManyEqualNumbers() { String input = "(= 4 4 4 4 4 4 4 4 4 4)"; assertT(evaluateString(input)); } @Test - public void testEqualspWithManyNonEqualNumbers() { + public void numericEqualWithManyNonEqualNumbers() { String input = "(= 4 4 4 4 5 4 4 4 4 4)"; assertNil(evaluateString(input)); } @Test(expected = BadArgumentTypeException.class) - public void testEqualspWithNonNumbers() { + public void numericEqualWithNonNumbers() { evaluateString("(= 'x 'x)"); } @Test(expected = TooFewArgumentsException.class) - public void testEqualspWithTooFewArguments() { + public void numericEqualWithTooFewArguments() { evaluateString("(=)"); } diff --git a/test/function/builtin/predicate/GREATERPTester.java b/test/function/builtin/predicate/NUMERIC_GREATERTester.java similarity index 67% rename from test/function/builtin/predicate/GREATERPTester.java rename to test/function/builtin/predicate/NUMERIC_GREATERTester.java index 6890b5c..43162a7 100644 --- a/test/function/builtin/predicate/GREATERPTester.java +++ b/test/function/builtin/predicate/NUMERIC_GREATERTester.java @@ -7,50 +7,50 @@ import org.junit.Test; import function.ArgumentValidator.*; -public class GREATERPTester { +public class NUMERIC_GREATERTester { @Test - public void testGreaterpWithOneNumber_ReturnsT() { + public void greaterThanWithOneNumber_ReturnsT() { String input = "(> 1)"; assertT(evaluateString(input)); } @Test - public void testGreaterpWithTwoNumbers_ReturnsNil() { + public void greaterThanWithTwoNumbers_ReturnsNil() { String input = "(> 1 2)"; assertNil(evaluateString(input)); } @Test - public void testGreaterpWithTwoNumbers_ReturnsT() { + public void greaterThanWithTwoNumbers_ReturnsT() { String input = "(> 3 2)"; assertT(evaluateString(input)); } @Test - public void testGreaterpWithManyNumbers_ReturnsNil() { + public void greaterThanWithManyNumbers_ReturnsNil() { String input = "(> 4 3 2 5 1)"; assertNil(evaluateString(input)); } @Test - public void testGreaterpWithManyNumbers_ReturnsT() { + public void greaterThanWithManyNumbers() { String input = "(> 4 3 2 1 0)"; assertT(evaluateString(input)); } @Test(expected = BadArgumentTypeException.class) - public void testGreaterpWithNonNumbers() { + public void greaterThanWithNonNumbers() { evaluateString("(> 'x 'x)"); } @Test(expected = TooFewArgumentsException.class) - public void testGreaterpWithTooFewArguments() { + public void greaterThanWithTooFewArguments() { evaluateString("(>)"); } diff --git a/test/function/builtin/predicate/LESSPTester.java b/test/function/builtin/predicate/NUMERIC_LESSTester.java similarity index 68% rename from test/function/builtin/predicate/LESSPTester.java rename to test/function/builtin/predicate/NUMERIC_LESSTester.java index 924df1e..74c186a 100644 --- a/test/function/builtin/predicate/LESSPTester.java +++ b/test/function/builtin/predicate/NUMERIC_LESSTester.java @@ -7,50 +7,50 @@ import org.junit.Test; import function.ArgumentValidator.*; -public class LESSPTester { +public class NUMERIC_LESSTester { @Test - public void testLesspWithOneNumber_ReturnsT() { + public void lessThanWithOneNumber_ReturnsT() { String input = "(< 1)"; assertT(evaluateString(input)); } @Test - public void testLesspWithTwoNumbers_ReturnsNil() { + public void lessThanWithTwoNumbers_ReturnsNil() { String input = "(< 2 1)"; assertNil(evaluateString(input)); } @Test - public void testLesspWithTwoNumbers_ReturnsT() { + public void lessThanWithTwoNumbers_ReturnsT() { String input = "(< 2 3)"; assertT(evaluateString(input)); } @Test - public void testLesspWithManyNumbers_ReturnsNil() { + public void lessThanWithManyNumbers_ReturnsNil() { String input = "(< 4 3 2 5 1)"; assertNil(evaluateString(input)); } @Test - public void testLesspWithManyNumbers_ReturnsT() { + public void lessThanWithManyNumbers_ReturnsT() { String input = "(< 0 1 2 3 4)"; assertT(evaluateString(input)); } @Test(expected = BadArgumentTypeException.class) - public void testLesspWithNonNumbers() { + public void lessThanWithNonNumbers() { evaluateString("(< '(1) '(2))"); } @Test(expected = TooFewArgumentsException.class) - public void testLesspWithTooFewArguments() { + public void lessThanWithTooFewArguments() { evaluateString("(<)"); }