diff --git a/acorn.js b/acorn.js index b00096460b..a2f4aa1a91 100644 --- a/acorn.js +++ b/acorn.js @@ -536,9 +536,9 @@ // The `forceRegexp` parameter is used in the one case where the // `tokRegexpAllowed` trick does not work. See `parseStatement`. - function readToken_dot(code) { + function readToken_dot() { var next = input.charCodeAt(tokPos+1); - if (next >= 48 && next <= 57) return readNumber(String.fromCharCode(code)); + if (next >= 48 && next <= 57) return readNumber(true); ++tokPos; return finishToken(_dot); } @@ -600,7 +600,7 @@ // The interpretation of a dot depends on whether it is followed // by a digit. case 46: // '.' - return readToken_dot(code); + return readToken_dot(); // Punctuation tokens. case 40: ++tokPos; return finishToken(_parenL); @@ -621,7 +621,7 @@ // Anything else beginning with a digit is an integer, octal // number, or float. case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9 - return readNumber(String.fromCharCode(code)); + return readNumber(false); // Quotes produce strings. case 34: case 39: // '"', "'" @@ -746,18 +746,18 @@ // Read an integer, octal integer, or floating-point number. - function readNumber(ch) { - var start = tokPos, isFloat = ch === "."; - if (!isFloat && readInt(10) == null) raise(start, "Invalid number"); - if (isFloat || input.charAt(tokPos) === ".") { - var next = input.charAt(++tokPos); - if (next === "-" || next === "+") ++tokPos; - if (readInt(10) === null && ch === ".") raise(start, "Invalid number"); + function readNumber(startsWithDot) { + var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48; + if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number"); + if (input.charCodeAt(tokPos) === 46) { + ++tokPos; + readInt(10); isFloat = true; } - if (/e/i.test(input.charAt(tokPos))) { - var next = input.charAt(++tokPos); - if (next === "-" || next === "+") ++tokPos; + var next = input.charCodeAt(tokPos); + if (next === 69 || next === 101) { // 'eE' + next = input.charCodeAt(++tokPos); + if (next === 43 || next === 45) ++tokPos; // '+-' if (readInt(10) === null) raise(start, "Invalid number") isFloat = true; } @@ -765,7 +765,7 @@ var str = input.slice(start, tokPos), val; if (isFloat) val = parseFloat(str); - else if (ch !== "0" || str.length === 1) val = parseInt(str, 10); + else if (!octal || str.length === 1) val = parseInt(str, 10); else if (/[89]/.test(str) || strict) raise(start, "Invalid number"); else val = parseInt(str, 8); return finishToken(_num, val); diff --git a/index.html b/index.html index 0a3e94590d..7b308ba7b8 100644 --- a/index.html +++ b/index.html @@ -341,9 +341,9 @@ into it.
All in the name of speed.
The forceRegexp parameter is used in the one case where the
-tokRegexpAllowed trick does not work. See parseStatement.
function readToken_dot(code) {
+tokRegexpAllowed trick does not work. See parseStatement. function readToken_dot() {
var next = input.charCodeAt(tokPos+1);
- if (next >= 48 && next <= 57) return readNumber(String.fromCharCode(code));
+ if (next >= 48 && next <= 57) return readNumber(true);
++tokPos;
return finishToken(_dot);
}
@@ -403,7 +403,7 @@ into it.
function getTokenFromCode(code) {
switch(code) {The interpretation of a dot depends on whether it is followed by a digit.
case 46: // '.'
- return readToken_dot(code);Punctuation tokens.
case 40: ++tokPos; return finishToken(_parenL);
+ return readToken_dot();Punctuation tokens.
case 40: ++tokPos; return finishToken(_parenL);
case 41: ++tokPos; return finishToken(_parenR);
case 59: ++tokPos; return finishToken(_semi);
case 44: ++tokPos; return finishToken(_comma);
@@ -416,7 +416,7 @@ by a digit. Anything else beginning with a digit is an integer, octal number, or float.
case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
- return readNumber(String.fromCharCode(code));Quotes produce strings.
case 34: case 39: // '"', "'"
+ return readNumber(false);Quotes produce strings.
case 34: case 39: // '"', "'"
return readString(code);Operators are parsed inline in tiny state machines. '=' (61) is
often referred to. finishOp simply skips the amount of
characters it is given as second argument, and returns a token
@@ -517,18 +517,18 @@ will return null unless the integer has exactly len di
if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
return finishToken(_num, val);
}
Read an integer, octal integer, or floating-point number.
- function readNumber(ch) {
- var start = tokPos, isFloat = ch === ".";
- if (!isFloat && readInt(10) == null) raise(start, "Invalid number");
- if (isFloat || input.charAt(tokPos) === ".") {
- var next = input.charAt(++tokPos);
- if (next === "-" || next === "+") ++tokPos;
- if (readInt(10) === null && ch === ".") raise(start, "Invalid number");
+ function readNumber(startsWithDot) {
+ var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48;
+ if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number");
+ if (input.charCodeAt(tokPos) === 46) {
+ ++tokPos;
+ readInt(10);
isFloat = true;
}
- if (/e/i.test(input.charAt(tokPos))) {
- var next = input.charAt(++tokPos);
- if (next === "-" || next === "+") ++tokPos;
+ var next = input.charCodeAt(tokPos);
+ if (next === 69 || next === 101) { // 'eE'
+ next = input.charCodeAt(++tokPos);
+ if (next === 43 || next === 45) ++tokPos; // '+-'
if (readInt(10) === null) raise(start, "Invalid number")
isFloat = true;
}
@@ -536,7 +536,7 @@ will return null unless the integer has exactly len di
var str = input.slice(start, tokPos), val;
if (isFloat) val = parseFloat(str);
- else if (ch !== "0" || str.length === 1) val = parseInt(str, 10);
+ else if (!octal || str.length === 1) val = parseInt(str, 10);
else if (/[89]/.test(str) || strict) raise(start, "Invalid number");
else val = parseInt(str, 8);
return finishToken(_num, val);
diff --git a/test/tests.js b/test/tests.js
index 7e14ad7a33..f01f5d3c53 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -25987,6 +25987,37 @@ test("123..toString(10)", {
]
});
+test("123.+2", {
+ type: "Program",
+ start: 0,
+ end: 6,
+ body: [
+ {
+ type: "ExpressionStatement",
+ start: 0,
+ end: 6,
+ expression: {
+ type: "BinaryExpression",
+ start: 0,
+ left: {
+ type: "Literal",
+ start: 0,
+ end: 4,
+ value: 123
+ },
+ operator: "+",
+ right: {
+ type: "Literal",
+ start: 5,
+ end: 6,
+ value: 2
+ },
+ end: 6
+ }
+ }
+ ]
+});
+
test("a\u2028b", {
type: "Program",
start: 0,