Started conversion to BigInteger for numbers
This commit is contained in:
parent
68510ec1a8
commit
4b0c4b44a7
|
@ -1,5 +1,7 @@
|
||||||
package function.builtin;
|
package function.builtin;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.*;
|
import sexpression.*;
|
||||||
|
|
||||||
|
@ -26,7 +28,7 @@ public class DIVIDE extends LispFunction {
|
||||||
if (argRest.nullp()) {
|
if (argRest.nullp()) {
|
||||||
// there is only one argument, so return the multiplicative
|
// there is only one argument, so return the multiplicative
|
||||||
// inverse of the number
|
// inverse of the number
|
||||||
return new LispNumber(1 / num1.getValue());
|
return new LispNumber(BigInteger.ONE.divide(num1.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argSecond = argRest.getCar();
|
SExpression argSecond = argRest.getCar();
|
||||||
|
@ -34,7 +36,7 @@ public class DIVIDE extends LispFunction {
|
||||||
// make sure that the next argument is a number as well
|
// make sure that the next argument is a number as well
|
||||||
if (argSecond.numberp()) {
|
if (argSecond.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) argSecond;
|
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();
|
SExpression argCddr = argRest.getCdr();
|
||||||
|
|
||||||
if (argCddr.consp()) {
|
if (argCddr.consp()) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class EQUALSP extends LispFunction {
|
||||||
if (secondArg.numberp()) {
|
if (secondArg.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) secondArg;
|
LispNumber num2 = (LispNumber) secondArg;
|
||||||
|
|
||||||
if (num1.getValue() == num2.getValue()) {
|
if (num1.getValue().equals(num2.getValue())) {
|
||||||
return call(argRest);
|
return call(argRest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class GREATERP extends LispFunction {
|
||||||
if (secondArg.numberp()) {
|
if (secondArg.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) secondArg;
|
LispNumber num2 = (LispNumber) secondArg;
|
||||||
|
|
||||||
if (num1.getValue() > num2.getValue()) {
|
if (num1.getValue().compareTo(num2.getValue()) > 0) {
|
||||||
return call(argRest);
|
return call(argRest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package function.builtin;
|
package function.builtin;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.*;
|
import sexpression.*;
|
||||||
|
|
||||||
|
@ -12,15 +14,15 @@ public class LENGTH extends LispFunction {
|
||||||
* Returns the length of the given list.
|
* Returns the length of the given list.
|
||||||
*
|
*
|
||||||
* @param list
|
* @param list
|
||||||
* the list to determine the length of
|
* the list to determine the length of
|
||||||
* @return
|
* @return the length of <code>list</code>
|
||||||
* the length of <code>list</code>
|
|
||||||
*/
|
*/
|
||||||
public static int getLength(Cons list) {
|
public static int getLength(Cons list) {
|
||||||
LENGTH lengthFunction = new LENGTH();
|
LENGTH lengthFunction = new LENGTH();
|
||||||
LispNumber length = lengthFunction.call(LIST.makeList(list));
|
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) {
|
public LispNumber call(Cons argList) {
|
||||||
|
@ -28,19 +30,17 @@ public class LENGTH extends LispFunction {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
|
Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too few arguments given to LENGTH: " +
|
throw new RuntimeException("too few arguments given to LENGTH: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argCar = argList.getCar();
|
SExpression argCar = argList.getCar();
|
||||||
SExpression argCdr = argList.getCdr();
|
SExpression argCdr = argList.getCdr();
|
||||||
|
|
||||||
// make sure we have received only one argument
|
// make sure we have received only one argument
|
||||||
if (! argCdr.nullp()) {
|
if (!argCdr.nullp()) {
|
||||||
Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
|
Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
|
||||||
|
|
||||||
throw new RuntimeException("too many arguments given to LENGTH: " +
|
throw new RuntimeException("too many arguments given to LENGTH: " + originalSExpr);
|
||||||
originalSExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that the argument is a list
|
// make sure that the argument is a list
|
||||||
|
@ -48,17 +48,16 @@ public class LENGTH extends LispFunction {
|
||||||
Cons arg = (Cons) argCar;
|
Cons arg = (Cons) argCar;
|
||||||
|
|
||||||
if (arg.nullp()) {
|
if (arg.nullp()) {
|
||||||
return new LispNumber(0);
|
return new LispNumber(BigInteger.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cons cdr = LIST.makeList(arg.getCdr());
|
Cons cdr = LIST.makeList(arg.getCdr());
|
||||||
LispNumber cdrLength = call(cdr);
|
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 " +
|
throw new RuntimeException("LENGTH: a proper list must not end with " + argCar);
|
||||||
argCar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class LESSP extends LispFunction {
|
||||||
if (secondArg.numberp()) {
|
if (secondArg.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) secondArg;
|
LispNumber num2 = (LispNumber) secondArg;
|
||||||
|
|
||||||
if (num1.getValue() < num2.getValue()) {
|
if (num1.getValue().compareTo(num2.getValue()) < 0) {
|
||||||
return call(argRest);
|
return call(argRest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package function.builtin;
|
package function.builtin;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.*;
|
import sexpression.*;
|
||||||
|
|
||||||
|
@ -26,7 +28,7 @@ public class MINUS extends LispFunction {
|
||||||
if (argRest.nullp()) {
|
if (argRest.nullp()) {
|
||||||
// there is only one argument, so return the additive
|
// there is only one argument, so return the additive
|
||||||
// inverse of the number
|
// inverse of the number
|
||||||
return new LispNumber(-num1.getValue());
|
return new LispNumber(BigInteger.ZERO.subtract(num1.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argSecond = argRest.getCar();
|
SExpression argSecond = argRest.getCar();
|
||||||
|
@ -34,7 +36,7 @@ public class MINUS extends LispFunction {
|
||||||
// make sure that the next argument is a number as well
|
// make sure that the next argument is a number as well
|
||||||
if (argSecond.numberp()) {
|
if (argSecond.numberp()) {
|
||||||
LispNumber num2 = (LispNumber) argSecond;
|
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();
|
SExpression argCddr = argRest.getCdr();
|
||||||
|
|
||||||
if (argCddr.consp()) {
|
if (argCddr.consp()) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package function.builtin;
|
package function.builtin;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.*;
|
import sexpression.*;
|
||||||
|
|
||||||
|
@ -10,7 +12,7 @@ public class MULTIPLY extends LispFunction {
|
||||||
|
|
||||||
public LispNumber call(Cons argList) {
|
public LispNumber call(Cons argList) {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
return new LispNumber(1);
|
return new LispNumber(BigInteger.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SExpression argFirst = argList.getCar();
|
SExpression argFirst = argList.getCar();
|
||||||
|
@ -20,7 +22,7 @@ public class MULTIPLY extends LispFunction {
|
||||||
LispNumber num1 = (LispNumber) argFirst;
|
LispNumber num1 = (LispNumber) argFirst;
|
||||||
LispNumber num2 = call(argRest);
|
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");
|
throw new RuntimeException("*: " + argFirst + " is not a number");
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package function.builtin;
|
package function.builtin;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.*;
|
import sexpression.*;
|
||||||
|
|
||||||
|
@ -7,7 +9,7 @@ public class PLUS extends LispFunction {
|
||||||
|
|
||||||
public LispNumber call(Cons argList) {
|
public LispNumber call(Cons argList) {
|
||||||
if (argList.nullp()) {
|
if (argList.nullp()) {
|
||||||
return new LispNumber(0);
|
return new LispNumber(BigInteger.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!argList.getCdr().listp())
|
if (!argList.getCdr().listp())
|
||||||
|
@ -20,7 +22,7 @@ public class PLUS extends LispFunction {
|
||||||
LispNumber num1 = (LispNumber) argFirst;
|
LispNumber num1 = (LispNumber) argFirst;
|
||||||
LispNumber num2 = call(argRest);
|
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");
|
throw new RuntimeException("+: " + argFirst + " is not a number");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package sexpression;
|
package sexpression;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import error.LispException;
|
import error.LispException;
|
||||||
|
@ -7,20 +8,20 @@ import error.LispException;
|
||||||
@DisplayName("number")
|
@DisplayName("number")
|
||||||
public class LispNumber extends Atom {
|
public class LispNumber extends Atom {
|
||||||
|
|
||||||
private int value;
|
private BigInteger value;
|
||||||
|
|
||||||
public LispNumber(String text) {
|
public LispNumber(String text) {
|
||||||
super(text.replaceFirst("^0+(?!$)", ""));
|
super(text.replaceFirst("^0+(?!$)", ""));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.value = Integer.parseInt(text);
|
this.value = new BigInteger(text);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new InvalidNumberException(text);
|
throw new InvalidNumberException(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LispNumber(int value) {
|
public LispNumber(BigInteger value) {
|
||||||
super(Integer.toString(value));
|
super(value.toString());
|
||||||
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +30,7 @@ public class LispNumber extends Atom {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getValue() {
|
public BigInteger getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class UserDefinedFunctionTester {
|
||||||
@Test
|
@Test
|
||||||
public void oneArgumentFunction_ReturnsCorrectValue() {
|
public void oneArgumentFunction_ReturnsCorrectValue() {
|
||||||
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
||||||
SExpression argument = new LispNumber(23);
|
SExpression argument = new LispNumber("23");
|
||||||
Cons argumentList = new Cons(argument, Nil.getUniqueInstance());
|
Cons argumentList = new Cons(argument, Nil.getUniqueInstance());
|
||||||
|
|
||||||
assertSExpressionsMatch(argument, function.call(argumentList));
|
assertSExpressionsMatch(argument, function.call(argumentList));
|
||||||
|
@ -51,7 +51,7 @@ public class UserDefinedFunctionTester {
|
||||||
@Test(expected = TooManyArgumentsException.class)
|
@Test(expected = TooManyArgumentsException.class)
|
||||||
public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() {
|
public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() {
|
||||||
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
||||||
SExpression argument = new LispNumber(23);
|
SExpression argument = new LispNumber("23");
|
||||||
Cons argumentList = new Cons(argument, new Cons(argument, Nil.getUniqueInstance()));
|
Cons argumentList = new Cons(argument, new Cons(argument, Nil.getUniqueInstance()));
|
||||||
|
|
||||||
function.call(argumentList);
|
function.call(argumentList);
|
||||||
|
|
|
@ -2,6 +2,8 @@ package sexpression;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import error.ErrorManager;
|
import error.ErrorManager;
|
||||||
|
@ -35,7 +37,7 @@ public class SExpressionTester {
|
||||||
public void testNumberValueToString() {
|
public void testNumberValueToString() {
|
||||||
String expected = "12";
|
String expected = "12";
|
||||||
|
|
||||||
assertSExpressionMatchesString(expected, new LispNumber(12));
|
assertSExpressionMatchesString(expected, new LispNumber("12"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -55,7 +57,7 @@ public class SExpressionTester {
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleConsToString() {
|
public void testSimpleConsToString() {
|
||||||
String expected = "(1)";
|
String expected = "(1)";
|
||||||
Cons cons = new Cons(new LispNumber(1), Nil.getUniqueInstance());
|
Cons cons = new Cons(new LispNumber("1"), Nil.getUniqueInstance());
|
||||||
|
|
||||||
assertSExpressionMatchesString(expected, cons);
|
assertSExpressionMatchesString(expected, cons);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +65,7 @@ public class SExpressionTester {
|
||||||
@Test
|
@Test
|
||||||
public void testComplexConsToString() {
|
public void testComplexConsToString() {
|
||||||
String expected = "(1 A \"string\")";
|
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 Symbol("a"),
|
||||||
new Cons(new LispString("\"string\""), Nil.getUniqueInstance())));
|
new Cons(new LispString("\"string\""), Nil.getUniqueInstance())));
|
||||||
|
|
||||||
|
@ -118,7 +120,7 @@ public class SExpressionTester {
|
||||||
@Test
|
@Test
|
||||||
public void afterSettingCarOfNil_ShouldStillBeNil() {
|
public void afterSettingCarOfNil_ShouldStillBeNil() {
|
||||||
Cons nil = Nil.getUniqueInstance();
|
Cons nil = Nil.getUniqueInstance();
|
||||||
nil.setCar(new LispNumber(2));
|
nil.setCar(new LispNumber("2"));
|
||||||
|
|
||||||
assertEquals(nil.getCar(), Nil.getUniqueInstance());
|
assertEquals(nil.getCar(), Nil.getUniqueInstance());
|
||||||
}
|
}
|
||||||
|
@ -126,15 +128,15 @@ public class SExpressionTester {
|
||||||
@Test
|
@Test
|
||||||
public void afterSettingCdrOfNil_ShouldStillBeNil() {
|
public void afterSettingCdrOfNil_ShouldStillBeNil() {
|
||||||
Cons nil = Nil.getUniqueInstance();
|
Cons nil = Nil.getUniqueInstance();
|
||||||
nil.setCdr(new LispNumber(2));
|
nil.setCdr(new LispNumber("2"));
|
||||||
|
|
||||||
assertEquals(nil.getCdr(), Nil.getUniqueInstance());
|
assertEquals(nil.getCdr(), Nil.getUniqueInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNumberValue() {
|
public void testNumberValue() {
|
||||||
int value = 12;
|
BigInteger value = new BigInteger("12");
|
||||||
LispNumber number = new LispNumber(String.valueOf(value));
|
LispNumber number = new LispNumber(value.toString());
|
||||||
|
|
||||||
assertEquals(number.getValue(), value);
|
assertEquals(number.getValue(), value);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue