ES2020 Feature: BigInt
Syntax:
New NumericLiteral syntax with a n suffix. Only decimal numbers with a suffix are valid. LegacyOctal or leading zeros are not valid.
123n
Grammar changes are to NumericLiteral. Basically allowing the BigInt n suffix on modern binary, octal, and hex numbers, or non-legacy-octal decimal literals.
NumericLiteral::
LegacyOctalIntegerLiteral
DecimalLiteral
+ DecimalIntegerLiteral BigIntLiteralSuffix
+ NumericLiteralBase
+ NumericLiteralBase BigIntLiteralSuffix
- BinaryIntegerLiteral
- OctalIntegerLiteral
- HexIntegerLiteral
+ NumericLiteralBase::
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+
+ BigIntLiteralSuffix :: n
Spec:
TC39: https://github.com/tc39/proposal-bigint https://tc39.es/proposal-bigint/
ESTree: https://github.com/estree/estree/blob/master/es2020.md
Literal
extend interface Literal <: Expression {
type: "Literal";
value: string | boolean | null | number | RegExp | bigint;
}
-
valueproperty can be aBigIntvalue to representBigIntliterals such as100n.
BigIntLiteral
interface BigIntLiteral <: Literal {
bigint: string;
}
-
bigintproperty is the string representation of theBigIntvalue. It doesn't include the suffixn. - In environments that don't support
BigIntvalues,valueproperty will benullas theBigIntvalue can't be represented natively.
Additional considerations
- Supported in Chrome and Firefox. Experimental in WebKit
- Supported in Node
Remaining Tasks:
- [ ] Add new
BigIntLiteralnode (nodes.ts,docs/syntax-tree-format.md) - [ ] Update Scanner (
scanner.tschanges fornnumeric suffix) - [ ] Update Parser (
parser.tsto create aBigIntLiteralnode for those numeric literals) - [ ] Provide Unit Tests and Coverage (see below)
- [ ] Update test262 (~test262.git#2ee3864136) / test262-stream (~1.3.0) (note that
test.attrs.negative.phase === 'early'should also now handletest.attrs.negative.phase === 'parse') - [ ] Handle runtimes where
globalThis.BigIntis available and not available (may require updating typescript to ~3.4
Test Cases
Valid:
0n
123n
0x123n
0o123n
0b101n
Invalid:
1.1n
1e1n
01n // Leading Zero (legacy hex) does not allow it
00n // Leading Zero does not allow it
09n // Leading Zero does not allow it
The tricky part about this is whether or not globalThis.BigInt is available.
If it is, then the BigIntLiteral's value property is a BigInt value.
If it is not, then the BitIntLiteral's value property is null.
Test coverage for that may require istanbul comments along the lines of:
const value = globalThis.BigInt ? globalThis.BigInt(string) : /* istanbul ignore next */ null;
return {
type: Token.NumericLiteral,
value: value,
...
};
Given unit tests run with a node where BigInt will be available but some browsers may not have it available.
I've created a pull for this in my fork: https://github.com/node-projects/esprima-next/pull/12
"dependencies": {
"esprima": "^4.0.1",
}
In my pakage.json,I use esprima-version-4.0.1 , but it's error when parsing bigint code, such as "var x = 0x123n".
How to use the new Feature about ES2020:BigInt?
@famgy I've created a fork: esprima-next wich has support. https://github.com/node-projects/esprima-next
@famgy I've created a fork: esprima-next wich has support. https://github.com/node-projects/esprima-next "dependencies": { "@babel/core": "^7.16.5", "@babel/preset-env": "^7.16.5", "esprima-next": "^5.7.0" }
usage: var BABEL = require("@babel/core"), ESPRIMA = require("esprima-next") var esCode = BABEL.transform('var x = 0x123n', { presets: ["@babel/preset-env"] }).code
var astCode = ESPRIMA.parseScript(esCode)
But, It's Error :
Error: Line 3: Unexpected token ILLEGAL at e.constructError (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:20546) at e.createError (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:20765) at e.throwError (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:20888) at e.throwUnexpectedToken (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:122742) at e.scanHexLiteral (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:131016) at e.scanNumericLiteral (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:133188) at e.lex (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:139302) at e.nextToken (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:55026) at e.parseVariableDeclaration (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:91452) at e.parseVariableDeclarationList (E:\Projects\JavaScript\jsobfx-es2020\node_modules\esprima-next\dist\esprima.js:1:91724) { index: 28,
I've been fixing issues with parsing on .NET side: https://github.com/sebastienros/esprima-dotnet/pull/214 , currently I haven't found any new problems with the current WIP version while integrating Jint with it.
@famgy my fork is not an ES5 lib and more, so it should be loaded via "import".
After clone esprima-next, and run test: var ESPRIMA = require('.');
It's OK ,such as : var astCode = ESPRIMA.parseScript('var x = 123n', { tolerant: true })
It's Error, such as: var astCode = ESPRIMA.parseScript('var x = 0x123n', { tolerant: true })
Is it the result that "123n" is valid, but "0x123n" is invalid ?