Skip to content

Commit

Permalink
fix(lexer): fixed issue with raw in numeric scanning
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jun 4, 2019
1 parent f6d6b8e commit db21faf
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 6 deletions.
9 changes: 6 additions & 3 deletions src/lexer/numeric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,14 @@ export function scanNumber(parser: ParserState, context: Context, isFloat: boole
}
}

let isBigInt = false;
let isBigInt: 0 | 1 = 0;

if (
parser.nextCP === Chars.LowerN &&
(kind & (NumberKind.Decimal | NumberKind.Binary | NumberKind.Octal | NumberKind.Hex)) !== 0
) {
if (isFloat) report(parser, Errors.InvalidBigInt);
isBigInt = true;
isBigInt = 1;
nextCodePoint(parser);
// Scan any exponential notation
} else if ((parser.nextCP | 32) === Chars.LowerE) {
Expand Down Expand Up @@ -151,6 +152,8 @@ export function scanNumber(parser: ParserState, context: Context, isFloat: boole
: isBigInt
? parseInt(parser.source.slice(parser.tokenIndex, parser.index), 0xa)
: +parser.source.slice(parser.tokenIndex, parser.index);
if (context & Context.OptionsRaw) parser.tokenRaw = parser.source.slice(parser.tokenValue, parser.index);

if (context & Context.OptionsRaw || isBigInt) parser.tokenRaw = parser.source.slice(parser.tokenIndex, parser.index);

return isBigInt ? Token.BigIntLiteral : Token.NumericLiteral;
}
17 changes: 16 additions & 1 deletion test/parser/expressions/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('Expressions - Array', () => {
'[[a] = b] = x',
'[,,,] = x',
'[...a] = x',
'[...async] = x',
'v = [...a, b]',
'[a,] = x',
'0, [{ x }] = [null]',
Expand Down Expand Up @@ -53,6 +54,9 @@ describe('Expressions - Array', () => {
'let b = [42];',
'let c = [42, 7];',
'let [d, ...e] = [1, 2, 3, 4, 5];',
'let [async, ...e] = [1, 2, 3, 4, 5];',
'let [d, ...async] = [1, 2, 3, 4, 5];',
'let [async, ...await] = [1, 2, 3, 4, 5];',
`[...x];`,
`[...x] = y;`,
`[...[x].foo] = x`,
Expand Down Expand Up @@ -83,6 +87,7 @@ describe('Expressions - Array', () => {
`[a,a,]`,
`[a,,,]`,
'([...x]) => y',
'([...async]) => y',
'[...(x,y)]',
'[...(x,y)]',
`[a,a,,]`,
Expand Down Expand Up @@ -124,6 +129,7 @@ describe('Expressions - Array', () => {
'[...x, y];',
'[...x];',
'[...x] = y;',
'[...async] = y;',
'[...this];',
'[...new x];',
'[...x/y];',
Expand All @@ -149,6 +155,7 @@ describe('Expressions - Array', () => {
'[...a, ...b]',
'[...a, , ...b]',
'[...[...a]]',
'[...[...async]]',
'[, ...a]',
'[, , ...a]',
'[,]',
Expand Down Expand Up @@ -274,6 +281,7 @@ describe('Expressions - Array', () => {
'[, , x, , ...y] = [1, 2, 3, 4, 5, 6];',
'[...[x]] = [ , ];',
'[...[x[yield]]] =[101];',
'[...[async[yield]]] = [await];',
'[...x[yield]] =[101];',
'0, { yield } = {};',
'[[[[[[[101]]]]]]];',
Expand Down Expand Up @@ -345,6 +353,11 @@ describe('Expressions - Array', () => {
'[(x) => y = (z)]',
'[(x), y = x] = x;',
'[(x), y] = x;',
'[(async), y] = x;',
'[(x), async] = x;',
'[(x), await] = x;',
'[(x), async] = await;',
'[(x), y] = x;',
'[(a), ] = x;',
'([(x), y] = x);'
]) {
Expand Down Expand Up @@ -492,6 +505,7 @@ describe('Expressions - Array', () => {
['[{..}]', Context.None],
['[{..}.x]', Context.None],
['[{..}=x]', Context.None],
[`[[async].await()] = x`, Context.None],
[`[[foo].food()] = x`, Context.None],
[`[[foo].food() = x] = x`, Context.None],
[`[[..][foo]] = x`, Context.None],
Expand Down Expand Up @@ -621,7 +635,8 @@ describe('Expressions - Array', () => {
['[(1) = (a = b.c)]', Context.None],
['[([{ x = y }] = b.call(c)) = ()]', Context.None],
['[(a = b.call(c)) = ()]', Context.None],
['[(a = b.call(c)) = (a = b / 2)]', Context.None]
['[(a = b.call(c)) = (a = b / 2)]', Context.None],
['[(a = async.call(c)) = (a = b / 2)]', Context.None]
]);

pass('Expressions - Array (pass)', [
Expand Down
162 changes: 162 additions & 0 deletions test/parser/expressions/bigint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { Context } from '../../../src/common';
import { pass, fail } from '../../test-utils';
import * as t from 'assert';
import { parseSource } from '../../../src/parser';

describe('Expressions - BigInt', () => {
for (const arg of [
'-1n',
`const minus_one = BigInt(-1);`,
'x(30n, "foo", "bar");',
`18757382984821n`,
'0b1111n',
'a.b(c(0b1), 1n);',
'340282366920938463463374607431768211456n',
'a(3, 14n)',
'431768211456n - 431768211456n',
'class X { static async await(){} }',
'(function x() { if (a === 0) return (1n / a) === (1n / b); })',
'(function x() { for (var i = 0n; i < a.length; i++) { if (!x(a[i], b[i])) return false; } })',
'var x = 2n ** 1000000000n;',
'5n % 1n',
'5n, 5n / 1n',
'foo(5n, -5n / -1n);',
'0n, 5n % 1n',
'0n, -5n % -1n',
'0n === 0n',
'var x = 2n ** 31n - 1n;',
'var x = kMaxInt - 32n - 2n;',
'x = [2n ** 64n - 1n, 2n ** 64n - 2n, 4n, 3n, 2n, 1n, 0n]',
`var data = [{
a: 0x26ffcdbd233a53e7ca4612f2b02e1f2c1d885c3177e7n,
r: 0x26ffcdbd233a53e7ca4612f2b02e1f2c1d885c3177e6n
}, {
a: 0xf2a29a35193377a223ef0d6d98db95eeb24a4165f288fd2b4an,
r: 0xf2a29a35193377a223ef0d6d98db95eeb24a4165f288fd2b49n
}, {
a: 0x454d22e29e6104n,
r: 0x454d22e29e6103n
}, {
a: -0xb00874640d30e6fce6bf79508378ed17e44dacb48a4200bce536cec462b3c2n,
r: -0xb00874640d30e6fce6bf79508378ed17e44dacb48a4200bce536cec462b3c3n
}, {
a: 0x4c151a24d765249c2bab4a1915b24b80ae437417c5n,
r: 0x4c151a24d765249c2bab4a1915b24b80ae437417c4n
}, {
a: -0xcbd476b1f9ca08ff820941n,
r: -0xcbd476b1f9ca08ff820942n
}, {
a: -0xe848e5830fa1035322b39c2cdd031109ca8n,
r: -0xe848e5830fa1035322b39c2cdd031109ca9n
}, {
a: -0x4d58c5e190f0ebac5bb36ca4d214069f69726c63a5n,
r: -0x4d58c5e190f0ebac5bb36ca4d214069f69726c63a6n
}, {
a: 0x9b396n,
r: 0x9b395n
}, {
a: 0x593921fe8b9d4906cn,
r: 0x593921fe8b9d4906bn
}, {
a: -0xe127928c7cecd6e9ca94d98e858f9c76a0fccac62203aac7710cef1f9e352n,
r: -0xe127928c7cecd6e9ca94d98e858f9c76a0fccac62203aac7710cef1f9e353n
}, {
a: 0xeb14cd952d06eb6fc613016f73b7339cbdd010n,
r: 0xeb14cd952d06eb6fc613016f73b7339cbdd00fn
}, {
a: -0xfdeab6a3dbd603137f680413fecc9e1c80n,
r: -0xfdeab6a3dbd603137f680413fecc9e1c81n
}, {
a: -0x7e9abbdfad170df2129dae8e15088a02b9ba99276a351a05n,
r: -0x7e9abbdfad170df2129dae8e15088a02b9ba99276a351a06n
}, {
a: 0x7b98f57n,
r: 0x7b98f56n
}, {
a: -0x919751deb470faa60d7c5c995c8bed72f9542d710fbbf1341n,
r: -0x919751deb470faa60d7c5c995c8bed72f9542d710fbbf1342n
}, {
a: -0xc5541d89b118a88afdd187228440427c8a24f9d9bn,
r: -0xc5541d89b118a88afdd187228440427c8a24f9d9cn
}, {
a: -0xe6c88a170595fn,
r: -0xe6c88a1705960n
}, {
a: -0xa1ffbfa388c332804dc4dc973n,
r: -0xa1ffbfa388c332804dc4dc974n
}, {
a: 0x67b768ce0c415127a77402861d1901dd7f60a8624ebea6ecafe03adc3cen,
r: 0x67b768ce0c415127a77402861d1901dd7f60a8624ebea6ecafe03adc3cdn
}];`
]) {
it(`${arg}`, () => {
t.doesNotThrow(() => {
parseSource(`${arg}`, undefined, Context.OptionsWebCompat);
});
});
}

pass('Expressions - BigInt (pass)', [
[
'1n',
Context.OptionsRanges,
{
type: 'Program',
sourceType: 'script',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'BigIntLiteral',
value: 1,
bigint: '1n',
start: 0,
end: 2
},
start: 0,
end: 2
}
],
start: 0,
end: 2
}
],
[
'1n + 2333333n',
Context.OptionsRanges,
{
type: 'Program',
sourceType: 'script',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'BinaryExpression',
left: {
type: 'BigIntLiteral',
value: 1,
bigint: '1n',
start: 0,
end: 2
},
right: {
type: 'BigIntLiteral',
value: 2333333,
bigint: '2333333n',
start: 5,
end: 13
},
operator: '+',
start: 0,
end: 13
},
start: 0,
end: 13
}
],
start: 0,
end: 13
}
]
]);
});
8 changes: 7 additions & 1 deletion test/parser/expressions/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ describe('Expressions - Object', () => {
'async',
'await',
'async *method(a, b,) {}',
'async *method(a, async,) {}',
'async *method(x, y = x, z = y) {}',
'async *method(x = y, y) {}',
'prop: 12',
Expand All @@ -702,6 +703,7 @@ describe('Expressions - Object', () => {
'async: foo',
'await: foo',
'*method([[x, y, z] = [4, 5, 6]]) {}',
'*method([[x, async, z] = [4, 5, 6]]) {}',
'async *method([[,] = g()]) {}',
'async *method([x = 23]) {}',
'async *method([x]) {}',
Expand All @@ -714,6 +716,7 @@ describe('Expressions - Object', () => {
'async *method([x = 23] = [undefined]) {}',
'async *method([x] = g[Symbol.iterator] = function() {}) {}',
'async *method([...x] = {}) {}',
'async *method([...async] = {}) {}',
'async *method({ w: [x, y, z] = [4, 5, 6] } = {}) {}',
'async *method({ [function foo() {}]: x } = {}) {}',
'async *method({ x: y = thrower() } = {}) {}',
Expand Down Expand Up @@ -813,6 +816,7 @@ describe('Expressions - Object', () => {
' ...async () => { }',
'...obj',
'...obj',
'async: {a: b}',
'"foo": {a: b}',
'"foo": [a]',
'"foo": ({a: b})',
Expand All @@ -822,6 +826,7 @@ describe('Expressions - Object', () => {
'"foo": {x} = "bar"',
'"foo": [x] = "bar"',
'"foo": (x) = "bar"',
'"foo": (x) = async',
'key: bar = x',
'key: bar + x',
'key: bar.foo = x',
Expand All @@ -834,7 +839,8 @@ describe('Expressions - Object', () => {
'x = 1} = {',
'x, y = 1, z = 2} = {',
'a: [b = 1, c = 2][1]} = {a:[]',
'a: [b = 1, c = 2].b} = {a:[]'
'a: [b = 1, c = 2].b} = {a:[]',
'async'
]) {
it(`({ ${arg} })`, () => {
t.doesNotThrow(() => {
Expand Down
2 changes: 1 addition & 1 deletion test/parser/miscellaneous/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as t from 'assert';
import { parseModule, parseScript, parse } from '../../../src/grumpy';
import { parseModule, parseScript, parse } from '../../../src/meriyah';

describe('Expressions - API', () => {
it('should parse script code with "parse"', () => {
Expand Down

0 comments on commit db21faf

Please sign in to comment.