From 4b0c4b44a74a9bb6d869049ef33194b92e34445d Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Sun, 25 Dec 2016 13:56:24 -0500 Subject: [PATCH] Started conversion to BigInteger for numbers --- src/function/builtin/DIVIDE.java | 6 +++-- src/function/builtin/EQUALSP.java | 2 +- src/function/builtin/GREATERP.java | 2 +- src/function/builtin/LENGTH.java | 25 ++++++++++---------- src/function/builtin/LESSP.java | 2 +- src/function/builtin/MINUS.java | 6 +++-- src/function/builtin/MULTIPLY.java | 6 +++-- src/function/builtin/PLUS.java | 6 +++-- src/sexpression/LispNumber.java | 11 +++++---- test/function/UserDefinedFunctionTester.java | 4 ++-- test/sexpression/SExpressionTester.java | 16 +++++++------ 11 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/function/builtin/DIVIDE.java b/src/function/builtin/DIVIDE.java index aaf8b57..c8bd044 100644 --- a/src/function/builtin/DIVIDE.java +++ b/src/function/builtin/DIVIDE.java @@ -1,5 +1,7 @@ package function.builtin; +import java.math.BigInteger; + import function.LispFunction; import sexpression.*; @@ -26,7 +28,7 @@ public class DIVIDE extends LispFunction { if (argRest.nullp()) { // there is only one argument, so return the multiplicative // inverse of the number - return new LispNumber(1 / num1.getValue()); + return new LispNumber(BigInteger.ONE.divide(num1.getValue())); } SExpression argSecond = argRest.getCar(); @@ -34,7 +36,7 @@ public class DIVIDE extends LispFunction { // make sure that the next argument is a number as well if (argSecond.numberp()) { LispNumber num2 = (LispNumber) argSecond; - LispNumber quotient = new LispNumber(num1.getValue() / num2.getValue()); + LispNumber quotient = new LispNumber(num1.getValue().divide(num2.getValue())); SExpression argCddr = argRest.getCdr(); if (argCddr.consp()) { diff --git a/src/function/builtin/EQUALSP.java b/src/function/builtin/EQUALSP.java index 6bdb456..deff065 100644 --- a/src/function/builtin/EQUALSP.java +++ b/src/function/builtin/EQUALSP.java @@ -33,7 +33,7 @@ public class EQUALSP extends LispFunction { if (secondArg.numberp()) { LispNumber num2 = (LispNumber) secondArg; - if (num1.getValue() == num2.getValue()) { + if (num1.getValue().equals(num2.getValue())) { return call(argRest); } diff --git a/src/function/builtin/GREATERP.java b/src/function/builtin/GREATERP.java index 955f403..fed1bbf 100644 --- a/src/function/builtin/GREATERP.java +++ b/src/function/builtin/GREATERP.java @@ -33,7 +33,7 @@ public class GREATERP extends LispFunction { if (secondArg.numberp()) { LispNumber num2 = (LispNumber) secondArg; - if (num1.getValue() > num2.getValue()) { + if (num1.getValue().compareTo(num2.getValue()) > 0) { return call(argRest); } diff --git a/src/function/builtin/LENGTH.java b/src/function/builtin/LENGTH.java index 353e312..b4b2d64 100644 --- a/src/function/builtin/LENGTH.java +++ b/src/function/builtin/LENGTH.java @@ -1,5 +1,7 @@ package function.builtin; +import java.math.BigInteger; + import function.LispFunction; import sexpression.*; @@ -12,15 +14,15 @@ public class LENGTH extends LispFunction { * Returns the length of the given list. * * @param list - * the list to determine the length of - * @return - * the length of list + * the list to determine the length of + * @return the length of list */ public static int getLength(Cons list) { LENGTH lengthFunction = new LENGTH(); LispNumber length = lengthFunction.call(LIST.makeList(list)); - return length.getValue(); + return length.getValue().intValue(); // TODO - return BigInteger when all built-ins use + // ArgumentValidator } public LispNumber call(Cons argList) { @@ -28,19 +30,17 @@ public class LENGTH extends LispFunction { if (argList.nullp()) { Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList); - throw new RuntimeException("too few arguments given to LENGTH: " + - originalSExpr); + throw new RuntimeException("too few arguments given to LENGTH: " + originalSExpr); } SExpression argCar = argList.getCar(); SExpression argCdr = argList.getCdr(); // make sure we have received only one argument - if (! argCdr.nullp()) { + if (!argCdr.nullp()) { Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList); - throw new RuntimeException("too many arguments given to LENGTH: " + - originalSExpr); + throw new RuntimeException("too many arguments given to LENGTH: " + originalSExpr); } // make sure that the argument is a list @@ -48,17 +48,16 @@ public class LENGTH extends LispFunction { Cons arg = (Cons) argCar; if (arg.nullp()) { - return new LispNumber(0); + return new LispNumber(BigInteger.ZERO); } Cons cdr = LIST.makeList(arg.getCdr()); LispNumber cdrLength = call(cdr); - return new LispNumber(1 + cdrLength.getValue()); + return new LispNumber(BigInteger.ONE.add(cdrLength.getValue())); } - throw new RuntimeException("LENGTH: a proper list must not end with " + - argCar); + throw new RuntimeException("LENGTH: a proper list must not end with " + argCar); } } diff --git a/src/function/builtin/LESSP.java b/src/function/builtin/LESSP.java index 8746c31..9275327 100644 --- a/src/function/builtin/LESSP.java +++ b/src/function/builtin/LESSP.java @@ -33,7 +33,7 @@ public class LESSP extends LispFunction { if (secondArg.numberp()) { LispNumber num2 = (LispNumber) secondArg; - if (num1.getValue() < num2.getValue()) { + if (num1.getValue().compareTo(num2.getValue()) < 0) { return call(argRest); } diff --git a/src/function/builtin/MINUS.java b/src/function/builtin/MINUS.java index cbe15dc..d9b4165 100644 --- a/src/function/builtin/MINUS.java +++ b/src/function/builtin/MINUS.java @@ -1,5 +1,7 @@ package function.builtin; +import java.math.BigInteger; + import function.LispFunction; import sexpression.*; @@ -26,7 +28,7 @@ public class MINUS extends LispFunction { if (argRest.nullp()) { // there is only one argument, so return the additive // inverse of the number - return new LispNumber(-num1.getValue()); + return new LispNumber(BigInteger.ZERO.subtract(num1.getValue())); } SExpression argSecond = argRest.getCar(); @@ -34,7 +36,7 @@ public class MINUS extends LispFunction { // make sure that the next argument is a number as well if (argSecond.numberp()) { LispNumber num2 = (LispNumber) argSecond; - LispNumber difference = new LispNumber(num1.getValue() - num2.getValue()); + LispNumber difference = new LispNumber(num1.getValue().subtract(num2.getValue())); SExpression argCddr = argRest.getCdr(); if (argCddr.consp()) { diff --git a/src/function/builtin/MULTIPLY.java b/src/function/builtin/MULTIPLY.java index c20be32..d5cfcd3 100644 --- a/src/function/builtin/MULTIPLY.java +++ b/src/function/builtin/MULTIPLY.java @@ -1,5 +1,7 @@ package function.builtin; +import java.math.BigInteger; + import function.LispFunction; import sexpression.*; @@ -10,7 +12,7 @@ public class MULTIPLY extends LispFunction { public LispNumber call(Cons argList) { if (argList.nullp()) { - return new LispNumber(1); + return new LispNumber(BigInteger.ONE); } SExpression argFirst = argList.getCar(); @@ -20,7 +22,7 @@ public class MULTIPLY extends LispFunction { LispNumber num1 = (LispNumber) argFirst; LispNumber num2 = call(argRest); - return new LispNumber(num1.getValue() * num2.getValue()); + return new LispNumber(num1.getValue().multiply(num2.getValue())); } throw new RuntimeException("*: " + argFirst + " is not a number"); diff --git a/src/function/builtin/PLUS.java b/src/function/builtin/PLUS.java index 4d784bb..ce93494 100644 --- a/src/function/builtin/PLUS.java +++ b/src/function/builtin/PLUS.java @@ -1,5 +1,7 @@ package function.builtin; +import java.math.BigInteger; + import function.LispFunction; import sexpression.*; @@ -7,7 +9,7 @@ public class PLUS extends LispFunction { public LispNumber call(Cons argList) { if (argList.nullp()) { - return new LispNumber(0); + return new LispNumber(BigInteger.ZERO); } if (!argList.getCdr().listp()) @@ -20,7 +22,7 @@ public class PLUS extends LispFunction { LispNumber num1 = (LispNumber) argFirst; LispNumber num2 = call(argRest); - return new LispNumber(num1.getValue() + num2.getValue()); + return new LispNumber(num1.getValue().add(num2.getValue())); } throw new RuntimeException("+: " + argFirst + " is not a number"); diff --git a/src/sexpression/LispNumber.java b/src/sexpression/LispNumber.java index 7b122f4..36d0a6a 100644 --- a/src/sexpression/LispNumber.java +++ b/src/sexpression/LispNumber.java @@ -1,5 +1,6 @@ package sexpression; +import java.math.BigInteger; import java.text.MessageFormat; import error.LispException; @@ -7,20 +8,20 @@ import error.LispException; @DisplayName("number") public class LispNumber extends Atom { - private int value; + private BigInteger value; public LispNumber(String text) { super(text.replaceFirst("^0+(?!$)", "")); try { - this.value = Integer.parseInt(text); + this.value = new BigInteger(text); } catch (NumberFormatException e) { throw new InvalidNumberException(text); } } - public LispNumber(int value) { - super(Integer.toString(value)); + public LispNumber(BigInteger value) { + super(value.toString()); this.value = value; } @@ -29,7 +30,7 @@ public class LispNumber extends Atom { return true; } - public int getValue() { + public BigInteger getValue() { return value; } diff --git a/test/function/UserDefinedFunctionTester.java b/test/function/UserDefinedFunctionTester.java index 4b75e43..7546b74 100644 --- a/test/function/UserDefinedFunctionTester.java +++ b/test/function/UserDefinedFunctionTester.java @@ -42,7 +42,7 @@ public class UserDefinedFunctionTester { @Test public void oneArgumentFunction_ReturnsCorrectValue() { UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument(); - SExpression argument = new LispNumber(23); + SExpression argument = new LispNumber("23"); Cons argumentList = new Cons(argument, Nil.getUniqueInstance()); assertSExpressionsMatch(argument, function.call(argumentList)); @@ -51,7 +51,7 @@ public class UserDefinedFunctionTester { @Test(expected = TooManyArgumentsException.class) public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() { UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument(); - SExpression argument = new LispNumber(23); + SExpression argument = new LispNumber("23"); Cons argumentList = new Cons(argument, new Cons(argument, Nil.getUniqueInstance())); function.call(argumentList); diff --git a/test/sexpression/SExpressionTester.java b/test/sexpression/SExpressionTester.java index c3535b4..014fa75 100644 --- a/test/sexpression/SExpressionTester.java +++ b/test/sexpression/SExpressionTester.java @@ -2,6 +2,8 @@ package sexpression; import static org.junit.Assert.*; +import java.math.BigInteger; + import org.junit.*; import error.ErrorManager; @@ -35,7 +37,7 @@ public class SExpressionTester { public void testNumberValueToString() { String expected = "12"; - assertSExpressionMatchesString(expected, new LispNumber(12)); + assertSExpressionMatchesString(expected, new LispNumber("12")); } @Test @@ -55,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.getUniqueInstance()); assertSExpressionMatchesString(expected, cons); } @@ -63,7 +65,7 @@ public class SExpressionTester { @Test public void testComplexConsToString() { String expected = "(1 A \"string\")"; - Cons list = new Cons(new LispNumber(1), + Cons list = new Cons(new LispNumber("1"), new Cons(new Symbol("a"), new Cons(new LispString("\"string\""), Nil.getUniqueInstance()))); @@ -118,7 +120,7 @@ public class SExpressionTester { @Test public void afterSettingCarOfNil_ShouldStillBeNil() { Cons nil = Nil.getUniqueInstance(); - nil.setCar(new LispNumber(2)); + nil.setCar(new LispNumber("2")); assertEquals(nil.getCar(), Nil.getUniqueInstance()); } @@ -126,15 +128,15 @@ public class SExpressionTester { @Test public void afterSettingCdrOfNil_ShouldStillBeNil() { Cons nil = Nil.getUniqueInstance(); - nil.setCdr(new LispNumber(2)); + nil.setCdr(new LispNumber("2")); assertEquals(nil.getCdr(), Nil.getUniqueInstance()); } @Test public void testNumberValue() { - int value = 12; - LispNumber number = new LispNumber(String.valueOf(value)); + BigInteger value = new BigInteger("12"); + LispNumber number = new LispNumber(value.toString()); assertEquals(number.getValue(), value); }