Resolves #10 - The equality predicates have been refactored

This commit is contained in:
Mike Cifelli 2017-02-28 11:54:19 -05:00
parent 50a3f3be67
commit d2dfe23083
14 changed files with 178 additions and 71 deletions

View File

@ -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 |

View File

@ -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|

View File

@ -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) {

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)");
}

View File

@ -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)");
}

View File

@ -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 '() '())");
}

View File

@ -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("(=)");
}

View File

@ -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("(>)");
}

View File

@ -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("(<)");
}