diff --git a/src/function/builtin/GREATERP.java b/src/function/builtin/GREATERP.java index 974107f..850626d 100644 --- a/src/function/builtin/GREATERP.java +++ b/src/function/builtin/GREATERP.java @@ -8,8 +8,8 @@ public class GREATERP extends LispFunction { private ArgumentValidator argumentValidator; public GREATERP() { - this.argumentValidator = new ArgumentValidator("GREATERP"); - this.argumentValidator.setMinimumNumberOfArguments(2); + this.argumentValidator = new ArgumentValidator(">"); + this.argumentValidator.setMinimumNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class); } diff --git a/src/function/builtin/LESSP.java b/src/function/builtin/LESSP.java index 82c3ade..5024649 100644 --- a/src/function/builtin/LESSP.java +++ b/src/function/builtin/LESSP.java @@ -1,49 +1,43 @@ package function.builtin; -import function.LispFunction; +import function.*; import sexpression.*; -/** - * LESSP represents the '<' function in Lisp. - */ public class LESSP 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 LESSP() { + 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(); + SExpression secondArgument = remainingArguments.getCar(); + LispNumber number1 = (LispNumber) firstArgument; + LispNumber number2 = (LispNumber) secondArgument; - if (num1.getValue().compareTo(num2.getValue()) < 0) { - return call(argRest); - } + if (!isFirstLesser(number1, number2)) + return Nil.getInstance(); - return Nil.getInstance(); - } + return callTailRecursive(remainingArguments); + } - throw new RuntimeException("<: " + secondArg + " is not a number"); - } - - throw new RuntimeException("<: " + firstArg + " is not a number"); + private boolean isFirstLesser(LispNumber number1, LispNumber number2) { + return number1.getValue().compareTo(number2.getValue()) < 0; } } diff --git a/test/function/builtin/GREATERPTester.java b/test/function/builtin/GREATERPTester.java index 9de0446..9e2d8d3 100644 --- a/test/function/builtin/GREATERPTester.java +++ b/test/function/builtin/GREATERPTester.java @@ -8,6 +8,13 @@ import function.ArgumentValidator.*; public class GREATERPTester { + @Test + public void testGreaterpWithOneNumber_ReturnsT() { + String input = "(> 1)"; + + assertSExpressionsMatch(evaluateString(input), parseString("t")); + } + @Test public void testGreaterpWithTwoNumbers_ReturnsNil() { String input = "(> 1 2)"; @@ -43,7 +50,7 @@ public class GREATERPTester { @Test(expected = TooFewArgumentsException.class) public void testGreaterpWithTooFewArguments() { - evaluateString("(> 1)"); + evaluateString("(>)"); } } diff --git a/test/function/builtin/LESSPTester.java b/test/function/builtin/LESSPTester.java new file mode 100644 index 0000000..21f4201 --- /dev/null +++ b/test/function/builtin/LESSPTester.java @@ -0,0 +1,56 @@ +package function.builtin; + +import static testutil.TestUtilities.*; + +import org.junit.Test; + +import function.ArgumentValidator.*; + +public class LESSPTester { + + @Test + public void testLesspWithOneNumber_ReturnsT() { + String input = "(< 1)"; + + assertSExpressionsMatch(evaluateString(input), parseString("t")); + } + + @Test + public void testLesspWithTwoNumbers_ReturnsNil() { + String input = "(< 2 1)"; + + assertSExpressionsMatch(evaluateString(input), parseString("nil")); + } + + @Test + public void testLesspWithTwoNumbers_ReturnsT() { + String input = "(< 2 3)"; + + assertSExpressionsMatch(evaluateString(input), parseString("t")); + } + + @Test + public void testLesspWithManyNumbers_ReturnsNil() { + String input = "(< 4 3 2 5 1)"; + + assertSExpressionsMatch(evaluateString(input), parseString("nil")); + } + + @Test + public void testLesspWithManyNumbers_ReturnsT() { + String input = "(< 0 1 2 3 4)"; + + assertSExpressionsMatch(evaluateString(input), parseString("t")); + } + + @Test(expected = BadArgumentTypeException.class) + public void testLesspWithNonNumbers() { + evaluateString("(< '(1) '(2))"); + } + + @Test(expected = TooFewArgumentsException.class) + public void testLesspWithTooFewArguments() { + evaluateString("(<)"); + } + +}