Skip to content

Commit ee965e8

Browse files
authoredJun 13, 2020
Add numeric separators support (#725)
* Add numeric separators support * functional tests with node 12 * Differentiate error scenarios
1 parent ee6b8af commit ee965e8

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed
 

‎.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
include:
1111
- name: Functional tests
1212
script: test/functional.sh
13-
node_js: 14
13+
node_js: 12
1414
cache:
1515
directories:
1616
- node_modules

‎lib/parse.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
503503
}
504504

505505
function read_num(prefix) {
506-
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false;
506+
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false;
507507
var num = read_while(function(ch, i) {
508508
if (is_big_int) return false;
509509

510510
var code = ch.charCodeAt(0);
511511
switch (code) {
512+
case 95: // _
513+
return (numeric_separator = true);
512514
case 98: case 66: // bB
513515
return (has_x = true); // Can occur in hex sequence, don't return false yet
514516
case 111: case 79: // oO
@@ -536,6 +538,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
536538
if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
537539
parse_error("Legacy octal literals are not allowed in strict mode");
538540
}
541+
if (numeric_separator) {
542+
if (num.endsWith("_")) {
543+
parse_error("Numeric separators are not allowed at the end of numeric literals");
544+
} else if (num.includes("__")) {
545+
parse_error("Only one underscore is allowed as numeric separator");
546+
}
547+
num = num.replace(/_/g, "");
548+
}
539549
if (num.endsWith("n")) {
540550
const without_n = num.slice(0, -1);
541551
const allow_e = RE_HEX_NUMBER.test(without_n);

‎test/compress/numbers.js

+32-1
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,9 @@ keep_numbers: {
258258
const huge = 1000000000001;
259259
const big = 100000000001;
260260
const fractional = 100.2300200;
261+
const numeric_separators = 1_000_000_000_000;
261262
}
262-
expect_exact: "const exp=1000000000000;const negativeExp=0.00000001;const huge=1000000000001;const big=100000000001;const fractional=100.2300200;"
263+
expect_exact: "const exp=1000000000000;const negativeExp=0.00000001;const huge=1000000000001;const big=100000000001;const fractional=100.2300200;const numeric_separators=1_000_000_000_000;"
263264
}
264265

265266
keep_numbers_in_properties_as_is: {
@@ -271,3 +272,33 @@ keep_numbers_in_properties_as_is: {
271272
}
272273
expect_exact: "var Foo={1000000:80000000000};"
273274
}
275+
276+
numeric_separators: {
277+
input: {
278+
const one = 1_000;
279+
const two = 1_000_000;
280+
const bin = 0b0101_0101;
281+
const oct = 0o0123_4567;
282+
const hex = 0xDEAD_BEEF;
283+
const fractional = 1_000.000_100;
284+
const identifier = _1000;
285+
const negate_identifier = -_1000;
286+
}
287+
expect_exact: "const one=1e3;const two=1e6;const bin=85;const oct=342391;const hex=3735928559;const fractional=1000.0001;const identifier=_1000;const negate_identifier=-_1000;"
288+
}
289+
290+
numeric_separator_trailing_underscore: {
291+
input: `const trailing = 1000_`
292+
expect_error: ({
293+
name: "SyntaxError",
294+
message: "Numeric separators are not allowed at the end of numeric literals"
295+
})
296+
}
297+
298+
numeric_separator_double_underscore: {
299+
input: `const double = 1__000`
300+
expect_error: ({
301+
name: "SyntaxError",
302+
message: "Only one underscore is allowed as numeric separator"
303+
})
304+
}

0 commit comments

Comments
 (0)
Please sign in to comment.