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