int startPos = buf.curPos();
boolean foundNum = false;
+ boolean hasDecimal = false;
try {
sb.append((char)c);
buf.next();
} else if(c == '.') {
+ hasDecimal = true;
sb.append((char)c);
buf.next();
} else if(isSpecialChar((char)c)) {
String numStr = sb.toString();
try {
// what number type to use here?
- BigDecimal num = new BigDecimal(numStr);
+ // BigDecimal num = new BigDecimal(numStr);
+ Object num = (hasDecimal ?
+ (Number)Double.valueOf(numStr) :
+ (Number)Long.valueOf(numStr));
foundNum = true;
- return new Token(TokenType.LITERAL, num, numStr, Value.Type.BIG_DEC);
+ return new Token(TokenType.LITERAL, num, numStr,
+ (hasDecimal ? Value.Type.DOUBLE : Value.Type.LONG));
} catch(NumberFormatException ne) {
throw new IllegalArgumentException(
"Invalid number literal " + numStr + " " + buf, ne);
package com.healthmarketscience.jackcess.impl.expr;
-import junit.framework.TestCase;
+import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
+import com.healthmarketscience.jackcess.DatabaseBuilder;
+import com.healthmarketscience.jackcess.TestUtil;
import com.healthmarketscience.jackcess.expr.Expression;
+import com.healthmarketscience.jackcess.expr.Function;
+import com.healthmarketscience.jackcess.expr.Value;
+import junit.framework.TestCase;
/**
*
*/
public class ExpressionatorTest extends TestCase
{
-
public ExpressionatorTest(String name) {
super(name);
}
"<EBinaryOp>{<ELiteralValue>{\"A\"} + <EBinaryOp>{<EParen>{(<EBetweenOp>{<ELiteralValue>{\"B\"} Not Between <EBinaryOp>{<ELiteralValue>{37} - <ELiteralValue>{15}} And <ELiteralValue>{52}})} / <ELiteralValue>{4}}}");
+ }
+
+ public void testSimpleMathExpressions() throws Exception
+ {
+ for(int i = -10; i < 10; ++i) {
+ assertEquals((long)-i, eval("=-(" + i + ")"));
+ }
+
+ for(int i = -10; i < 10; ++i) {
+ for(int j = -10; j < 10; ++j) {
+ assertEquals((long)(i + j), eval("=" + i + " + " + j));
+ }
+ }
+
+ for(int i = -10; i < 10; ++i) {
+ for(int j = -10; j < 10; ++j) {
+ assertEquals((long)(i - j), eval("=" + i + " - " + j));
+ }
+ }
+
+ for(int i = -10; i < 10; ++i) {
+ for(int j = -10; j < 10; ++j) {
+ assertEquals((long)(i * j), eval("=" + i + " * " + j));
+ }
+ }
+
+ for(int i = -10; i < 10; ++i) {
+ for(int j = -10; j < 10; ++j) {
+ try {
+ assertEquals((long)(i / j), eval("=" + i + " \\ " + j));
+ if(j == 0) {
+ fail("ArithmeticException should have been thrown");
+ }
+ } catch(ArithmeticException ae) {
+ if(j != 0) {
+ throw ae;
+ }
+ }
+ }
+ }
+
+ // for(int i = -10; i < 10; ++i) {
+ // for(int j = -10; j < 10; ++j) {
+ // System.out.println("FOO " + i + " " + j);
+ // assertEquals((long)(Math.pow(i, j)), eval("=" + i + " ^ " + j));
+ // }
+ // }
+
+
}
private static void validateExpr(String exprStr, String debugStr) {
assertEquals(debugStr, expr.toDebugString());
assertEquals(cleanStr, expr.toString());
}
+
+ private static Object eval(String exprStr) {
+ Expression expr = Expressionator.parse(
+ Expressionator.Type.DEFAULT_VALUE, exprStr, new TestContext());
+ return expr.evalDefault();
+ }
+
+ private static final class TestContext implements Expressionator.ParseContext
+ {
+ public SimpleDateFormat createDateFormat(String formatStr) {
+ SimpleDateFormat sdf = DatabaseBuilder.createDateFormat(formatStr);
+ sdf.setTimeZone(TestUtil.TEST_TZ);
+ return sdf;
+ }
+
+ public Function getExpressionFunction(String name) {
+ return null;
+ }
+ }
}