JS parser: added NUMBER_INT token type
This commit is contained in:
@@ -182,8 +182,11 @@ public class JsParser {
|
||||
case TokenStream.STRING:
|
||||
return new JsStringLiteral(node.getString());
|
||||
|
||||
case TokenStream.NUMBER_INT:
|
||||
return mapIntNumber(node);
|
||||
|
||||
case TokenStream.NUMBER:
|
||||
return mapNumber(node);
|
||||
return mapDoubleNumber(node);
|
||||
|
||||
case TokenStream.CALL:
|
||||
return mapCall(node);
|
||||
@@ -751,7 +754,11 @@ public class JsParser {
|
||||
return newExpr;
|
||||
}
|
||||
|
||||
private JsExpression mapNumber(Node numberNode) {
|
||||
private JsExpression mapIntNumber(Node numberNode) {
|
||||
return new JsNumberLiteral.JsIntLiteral((int) numberNode.getDouble());
|
||||
}
|
||||
|
||||
private JsExpression mapDoubleNumber(Node numberNode) {
|
||||
return new JsNumberLiteral.JsDoubleLiteral(numberNode.getDouble());
|
||||
}
|
||||
|
||||
@@ -1111,7 +1118,7 @@ public class JsParser {
|
||||
return mapPrefixOperation(JsUnaryOperator.TYPEOF, unOp);
|
||||
|
||||
case TokenStream.ADD:
|
||||
if (unOp.getFirstChild().getType() != TokenStream.NUMBER) {
|
||||
if (!isJsNumber(unOp.getFirstChild())) {
|
||||
return mapPrefixOperation(JsUnaryOperator.POS, unOp);
|
||||
}
|
||||
else {
|
||||
@@ -1171,4 +1178,9 @@ public class JsParser {
|
||||
private void pushScope(JsScope scope) {
|
||||
scopeStack.push(scope);
|
||||
}
|
||||
|
||||
private boolean isJsNumber(Node jsNode) {
|
||||
int type = jsNode.getType();
|
||||
return type == TokenStream.NUMBER || type == TokenStream.NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,10 @@ public class IRFactory {
|
||||
/**
|
||||
* Number (for literals)
|
||||
*/
|
||||
public Object createNumber(int number) {
|
||||
return Node.newNumber(number);
|
||||
}
|
||||
|
||||
public Object createNumber(double number) {
|
||||
return Node.newNumber(number);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,11 @@ public class Node implements Cloneable {
|
||||
|
||||
private static class NumberNode extends Node {
|
||||
|
||||
NumberNode(int number) {
|
||||
super(TokenStream.NUMBER_INT);
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
NumberNode(double number) {
|
||||
super(TokenStream.NUMBER);
|
||||
this.number = number;
|
||||
@@ -184,6 +189,10 @@ public class Node implements Cloneable {
|
||||
intDatum = value;
|
||||
}
|
||||
|
||||
public static Node newNumber(int number) {
|
||||
return new NumberNode(number);
|
||||
}
|
||||
|
||||
public static Node newNumber(double number) {
|
||||
return new NumberNode(number);
|
||||
}
|
||||
@@ -599,6 +608,10 @@ public class Node implements Cloneable {
|
||||
sb.append(' ');
|
||||
sb.append(hashCode());
|
||||
break;
|
||||
case TokenStream.NUMBER_INT:
|
||||
sb.append(' ');
|
||||
sb.append((int) getDouble());
|
||||
break;
|
||||
case TokenStream.NUMBER:
|
||||
sb.append(' ');
|
||||
sb.append(getDouble());
|
||||
|
||||
@@ -1284,11 +1284,16 @@ public class Parser {
|
||||
sourceAddString(ts.NAME, s);
|
||||
property = nf.createString(ts.getString());
|
||||
break;
|
||||
case TokenStream.NUMBER:
|
||||
double n = ts.getNumber();
|
||||
case TokenStream.NUMBER_INT:
|
||||
int n = (int) ts.getNumber();
|
||||
sourceAddNumber(n);
|
||||
property = nf.createNumber(n);
|
||||
break;
|
||||
case TokenStream.NUMBER:
|
||||
double d = ts.getNumber();
|
||||
sourceAddNumber(d);
|
||||
property = nf.createNumber(d);
|
||||
break;
|
||||
case TokenStream.RC:
|
||||
// trailing comma is OK.
|
||||
ts.ungetToken(tt);
|
||||
@@ -1332,11 +1337,16 @@ public class Parser {
|
||||
sourceAddString(ts.NAME, name);
|
||||
return nf.createName(name);
|
||||
|
||||
case TokenStream.NUMBER:
|
||||
double n = ts.getNumber();
|
||||
case TokenStream.NUMBER_INT:
|
||||
int n = (int)ts.getNumber();
|
||||
sourceAddNumber(n);
|
||||
return nf.createNumber(n);
|
||||
|
||||
case TokenStream.NUMBER:
|
||||
double d = ts.getNumber();
|
||||
sourceAddNumber(d);
|
||||
return nf.createNumber(d);
|
||||
|
||||
case TokenStream.STRING:
|
||||
String s = ts.getString();
|
||||
sourceAddString(ts.STRING, s);
|
||||
@@ -1449,34 +1459,33 @@ public class Parser {
|
||||
* could take up to 12 bytes.
|
||||
*/
|
||||
|
||||
long lbits = (long) n;
|
||||
if (lbits != n) {
|
||||
// if it's floating point, save as a Double bit pattern.
|
||||
// (12/15/97 our scanner only returns Double for f.p.)
|
||||
lbits = Double.doubleToLongBits(n);
|
||||
sourceAdd('D');
|
||||
sourceAdd((char) (lbits >> 48));
|
||||
sourceAdd((char) (lbits >> 32));
|
||||
sourceAdd((char) (lbits >> 16));
|
||||
sourceAdd((char) lbits);
|
||||
} else {
|
||||
// we can ignore negative values, bc they're already prefixed
|
||||
// by UNARYOP SUB
|
||||
if (Context.check && lbits < 0)
|
||||
Context.codeBug();
|
||||
long lbits = Double.doubleToLongBits(n);
|
||||
sourceAdd('D');
|
||||
sourceAdd((char) (lbits >> 48));
|
||||
sourceAdd((char) (lbits >> 32));
|
||||
sourceAdd((char) (lbits >> 16));
|
||||
sourceAdd((char) lbits);
|
||||
}
|
||||
|
||||
// will it fit in a char?
|
||||
// this gives a short encoding for integer values up to 2^16.
|
||||
if (lbits <= Character.MAX_VALUE) {
|
||||
sourceAdd('S');
|
||||
sourceAdd((char) lbits);
|
||||
} else { // Integral, but won't fit in a char. Store as a long.
|
||||
sourceAdd('J');
|
||||
sourceAdd((char) (lbits >> 48));
|
||||
sourceAdd((char) (lbits >> 32));
|
||||
sourceAdd((char) (lbits >> 16));
|
||||
sourceAdd((char) lbits);
|
||||
}
|
||||
private void sourceAddNumber(int n) {
|
||||
sourceAdd((char) TokenStream.NUMBER_INT);
|
||||
|
||||
// we can ignore negative values, bc they're already prefixed
|
||||
// by UNARYOP SUB
|
||||
if (Context.check && (long) n < 0)
|
||||
Context.codeBug();
|
||||
|
||||
// will it fit in a char?
|
||||
// this gives a short encoding for integer values up to 2^16.
|
||||
if ((long) n <= Character.MAX_VALUE) {
|
||||
sourceAdd('S');
|
||||
sourceAdd((char) (long) n);
|
||||
} else { // Integral, but won't fit in a char. Store as a long.
|
||||
sourceAdd('J');
|
||||
sourceAdd((char) ((long) n >> 48));
|
||||
sourceAdd((char) ((long) n >> 32));
|
||||
sourceAdd((char) ((long) n >> 16));
|
||||
sourceAdd((char) (long) n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -256,6 +256,7 @@ public class TokenStream {
|
||||
SCRIPT = 147, // top-level node for entire script
|
||||
|
||||
LAST_TOKEN = 147,
|
||||
NUMBER_INT = 148,
|
||||
|
||||
// This value is only used as a return value for getTokenHelper,
|
||||
// which is only called from getToken and exists to avoid an excessive
|
||||
@@ -314,7 +315,8 @@ public class TokenStream {
|
||||
case SETELEM: return "setelem";
|
||||
case CALL: return "call";
|
||||
case NAME: return "name";
|
||||
case NUMBER: return "number";
|
||||
case NUMBER_INT: return "integer";
|
||||
case NUMBER: return "double";
|
||||
case STRING: return "string";
|
||||
case ZERO: return "zero";
|
||||
case ONE: return "one";
|
||||
@@ -444,6 +446,8 @@ public class TokenStream {
|
||||
case NAME:
|
||||
return name + " `" + this.string + "'";
|
||||
|
||||
case NUMBER_INT:
|
||||
return "NUMBER_INT " + (int) this.number;
|
||||
case NUMBER:
|
||||
return "NUMBER " + this.number;
|
||||
}
|
||||
@@ -684,7 +688,7 @@ public class TokenStream {
|
||||
this.pushbackToken = EOF;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isJSKeyword(String s) {
|
||||
return getKeywordId(s) != 0;
|
||||
}
|
||||
@@ -980,6 +984,11 @@ public class TokenStream {
|
||||
}
|
||||
|
||||
this.number = dval;
|
||||
|
||||
if (isInteger) {
|
||||
return NUMBER_INT;
|
||||
}
|
||||
|
||||
return NUMBER;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user