@ibyar/expressions 0.5.1 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +5 -4
- package/api/abstract.d.ts +5 -6
- package/api/abstract.js +3 -3
- package/api/abstract.js.map +1 -1
- package/api/class/class.d.ts +202 -0
- package/api/class/class.js +635 -0
- package/api/class/class.js.map +1 -0
- package/api/class/decorator.d.ts +20 -0
- package/api/class/decorator.js +48 -0
- package/api/class/decorator.js.map +1 -0
- package/api/computing/call.d.ts +3 -1
- package/api/computing/call.js +16 -4
- package/api/computing/call.js.map +1 -1
- package/api/computing/debugger.d.ts +15 -0
- package/api/computing/debugger.js +35 -0
- package/api/computing/debugger.js.map +1 -0
- package/api/computing/new.d.ts +2 -1
- package/api/computing/new.js +4 -0
- package/api/computing/new.js.map +1 -1
- package/api/computing/rest.d.ts +6 -6
- package/api/computing/rest.js +5 -2
- package/api/computing/rest.js.map +1 -1
- package/api/computing/return.d.ts +2 -1
- package/api/computing/return.js +3 -0
- package/api/computing/return.js.map +1 -1
- package/api/computing/spread.d.ts +2 -1
- package/api/computing/spread.js +5 -2
- package/api/computing/spread.js.map +1 -1
- package/api/computing/throw.d.ts +2 -1
- package/api/computing/throw.js +3 -0
- package/api/computing/throw.js.map +1 -1
- package/api/computing/yield.d.ts +2 -1
- package/api/computing/yield.js +3 -0
- package/api/computing/yield.js.map +1 -1
- package/api/definition/array.d.ts +12 -12
- package/api/definition/array.js +31 -25
- package/api/definition/array.js.map +1 -1
- package/api/definition/bind.d.ts +2 -2
- package/api/definition/bind.js +1 -1
- package/api/definition/bind.js.map +1 -1
- package/api/definition/function.d.ts +40 -51
- package/api/definition/function.js +291 -309
- package/api/definition/function.js.map +1 -1
- package/api/definition/member.d.ts +2 -2
- package/api/definition/member.js +1 -1
- package/api/definition/member.js.map +1 -1
- package/api/definition/object.d.ts +15 -12
- package/api/definition/object.js +43 -13
- package/api/definition/object.js.map +1 -1
- package/api/definition/statement.d.ts +2 -2
- package/api/definition/statement.js +7 -3
- package/api/definition/statement.js.map +1 -1
- package/api/definition/values.d.ts +35 -50
- package/api/definition/values.js +66 -149
- package/api/definition/values.js.map +1 -1
- package/api/deserialize/deserialize.d.ts +2 -1
- package/api/deserialize/deserialize.js +4 -1
- package/api/deserialize/deserialize.js.map +1 -1
- package/api/deserialize/type-store.d.ts +2 -2
- package/api/deserialize/type-store.js.map +1 -1
- package/api/expression.d.ts +13 -18
- package/api/expression.js.map +1 -1
- package/api/index.d.ts +2 -0
- package/api/index.js +2 -0
- package/api/index.js.map +1 -1
- package/api/module/common.d.ts +29 -0
- package/api/module/common.js +71 -0
- package/api/module/common.js.map +1 -0
- package/api/module/export.d.ts +66 -25
- package/api/module/export.js +270 -58
- package/api/module/export.js.map +1 -1
- package/api/module/import.d.ts +61 -25
- package/api/module/import.js +226 -68
- package/api/module/import.js.map +1 -1
- package/api/operators/assignment.d.ts +2 -2
- package/api/operators/assignment.js +1 -1
- package/api/operators/assignment.js.map +1 -1
- package/api/operators/await.d.ts +2 -2
- package/api/operators/await.js +1 -1
- package/api/operators/await.js.map +1 -1
- package/api/operators/binary.d.ts +2 -2
- package/api/operators/binary.js +1 -1
- package/api/operators/binary.js.map +1 -1
- package/api/operators/chaining.d.ts +2 -2
- package/api/operators/chaining.js +1 -1
- package/api/operators/chaining.js.map +1 -1
- package/api/operators/comma.d.ts +2 -2
- package/api/operators/comma.js +2 -2
- package/api/operators/comma.js.map +1 -1
- package/api/operators/grouping.d.ts +2 -2
- package/api/operators/grouping.js +1 -1
- package/api/operators/grouping.js.map +1 -1
- package/api/operators/logical.d.ts +2 -2
- package/api/operators/logical.js +1 -1
- package/api/operators/logical.js.map +1 -1
- package/api/operators/pipeline.d.ts +2 -2
- package/api/operators/pipeline.js +1 -1
- package/api/operators/pipeline.js.map +1 -1
- package/api/operators/ternary.d.ts +2 -2
- package/api/operators/ternary.js +1 -1
- package/api/operators/ternary.js.map +1 -1
- package/api/operators/unary.d.ts +3 -3
- package/api/operators/unary.js +4 -3
- package/api/operators/unary.js.map +1 -1
- package/api/operators/update.d.ts +2 -2
- package/api/operators/update.js +1 -1
- package/api/operators/update.js.map +1 -1
- package/api/{app/program.d.ts → program.d.ts} +8 -9
- package/api/program.js +45 -0
- package/api/program.js.map +1 -0
- package/api/statement/control/block.d.ts +4 -5
- package/api/statement/control/block.js +22 -23
- package/api/statement/control/block.js.map +1 -1
- package/api/statement/control/empty.d.ts +1 -1
- package/api/statement/control/empty.js.map +1 -1
- package/api/statement/control/if.d.ts +2 -2
- package/api/statement/control/if.js +1 -1
- package/api/statement/control/if.js.map +1 -1
- package/api/statement/control/switch.d.ts +4 -5
- package/api/statement/control/switch.js +13 -9
- package/api/statement/control/switch.js.map +1 -1
- package/api/statement/control/terminate.d.ts +38 -13
- package/api/statement/control/terminate.js +81 -20
- package/api/statement/control/terminate.js.map +1 -1
- package/api/statement/declarations/declares.d.ts +17 -16
- package/api/statement/declarations/declares.js +24 -19
- package/api/statement/declarations/declares.js.map +1 -1
- package/api/statement/iterations/for.d.ts +5 -5
- package/api/statement/iterations/for.js +29 -23
- package/api/statement/iterations/for.js.map +1 -1
- package/api/statement/iterations/while.d.ts +3 -3
- package/api/statement/iterations/while.js +17 -13
- package/api/statement/iterations/while.js.map +1 -1
- package/api/utils.d.ts +5 -0
- package/api/utils.js +4 -0
- package/api/utils.js.map +1 -0
- package/package.json +5 -5
- package/scope/event.d.ts +2 -2
- package/scope/event.js +8 -14
- package/scope/event.js.map +1 -1
- package/scope/finalizer.d.ts +4 -0
- package/scope/finalizer.js +11 -0
- package/scope/finalizer.js.map +1 -0
- package/scope/proxy.d.ts +2 -3
- package/scope/proxy.js +22 -26
- package/scope/proxy.js.map +1 -1
- package/scope/scope.d.ts +42 -53
- package/scope/scope.js +73 -143
- package/scope/scope.js.map +1 -1
- package/scope/stack.d.ts +43 -26
- package/scope/stack.js +148 -102
- package/scope/stack.js.map +1 -1
- package/v8/enums.d.ts +204 -0
- package/v8/enums.js +375 -0
- package/v8/enums.js.map +1 -0
- package/v8/index.d.ts +2 -1
- package/v8/index.js +2 -1
- package/v8/index.js.map +1 -1
- package/v8/inline.d.ts +177 -0
- package/v8/inline.js +1973 -0
- package/v8/inline.js.map +1 -0
- package/v8/nodes.d.ts +8 -7
- package/v8/nodes.js +37 -63
- package/v8/nodes.js.map +1 -1
- package/v8/parser.d.ts +41 -151
- package/v8/parser.js +507 -1578
- package/v8/parser.js.map +1 -1
- package/v8/stream.d.ts +35 -3
- package/v8/stream.js +616 -164
- package/v8/stream.js.map +1 -1
- package/v8/token.d.ts +15 -9
- package/v8/token.js +79 -46
- package/v8/token.js.map +1 -1
- package/visit/visitor.js +4 -7
- package/visit/visitor.js.map +1 -1
- package/api/app/class.d.ts +0 -117
- package/api/app/class.js +0 -292
- package/api/app/class.js.map +0 -1
- package/api/app/program.js +0 -39
- package/api/app/program.js.map +0 -1
- package/api/module/module.d.ts +0 -26
- package/api/module/module.js +0 -63
- package/api/module/module.js.map +0 -1
- package/v8/app.d.ts +0 -0
- package/v8/app.js +0 -2
- package/v8/app.js.map +0 -1
package/v8/stream.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { Token, TokenExpression } from './token.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { GlobalThisNode, OfNode, Identifier, SymbolNode, AsNode, Literal, ThisNode, NullNode, UndefinedNode, TrueNode, FalseNode, DefaultNode, YieldIdentifier, ConstructorIdentifier, ArgumentsIdentifier, NameIdentifier, EvalIdentifier, SuperIdentifier, LetIdentifier, SetIdentifier, GetIdentifier, AwaitIdentifier, AsyncIdentifier } from '../api/definition/values.js';
|
|
3
|
+
import { PrivateIdentifier } from '../api/class/class.js';
|
|
4
|
+
import { DebuggerStatement } from '../api/computing/debugger.js';
|
|
5
|
+
import { isStrict, LanguageMode } from './enums.js';
|
|
6
|
+
const FORBIDDEN_CODE_POINT = ['200b', '200c', '200d', 'feff'];
|
|
7
|
+
export const IdentifierRegex = /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
|
|
8
|
+
export const IdentifierStartRegex = /[_$a-zA-Z\xA0-\uFFFF]/;
|
|
9
|
+
export const IdentifierPartRegex = /[_$a-zA-Z0-9\xA0-\uFFFF]/;
|
|
4
10
|
const EOFToken = Object.freeze(new TokenExpression(Token.EOS));
|
|
5
11
|
;
|
|
6
12
|
export class PreTemplateLiteral {
|
|
@@ -9,20 +15,33 @@ export class PreTemplateLiteral {
|
|
|
9
15
|
this.expressions = expressions;
|
|
10
16
|
}
|
|
11
17
|
}
|
|
18
|
+
;
|
|
19
|
+
export class TemplateStringLiteral {
|
|
20
|
+
constructor(string) {
|
|
21
|
+
this.string = string;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
12
24
|
export class TokenStream {
|
|
13
|
-
constructor() {
|
|
25
|
+
constructor(mode = LanguageMode.Strict) {
|
|
26
|
+
this.mode = mode;
|
|
14
27
|
this.pos = 0;
|
|
15
28
|
this.savedPosition = 0;
|
|
16
29
|
}
|
|
17
|
-
static getTokenStream(source) {
|
|
30
|
+
static getTokenStream(source, mode) {
|
|
18
31
|
if (Array.isArray(source)) {
|
|
19
|
-
return new TokenStreamer(source);
|
|
32
|
+
return new TokenStreamer(source, mode);
|
|
20
33
|
}
|
|
21
34
|
else if (typeof source === 'string') {
|
|
22
|
-
return new TokenStreamImpl(source);
|
|
35
|
+
return new TokenStreamImpl(source, mode);
|
|
23
36
|
}
|
|
24
37
|
throw new Error(`Can't build token stream for ${source}`);
|
|
25
38
|
}
|
|
39
|
+
setLanguageMode(mode) {
|
|
40
|
+
this.mode = mode;
|
|
41
|
+
}
|
|
42
|
+
getLanguageMode() {
|
|
43
|
+
return this.mode;
|
|
44
|
+
}
|
|
26
45
|
save() {
|
|
27
46
|
this.savedPosition = this.pos;
|
|
28
47
|
this.savedCurrent = this.current;
|
|
@@ -185,8 +204,8 @@ export class TokenStream {
|
|
|
185
204
|
}
|
|
186
205
|
}
|
|
187
206
|
export class TokenStreamer extends TokenStream {
|
|
188
|
-
constructor(tokens) {
|
|
189
|
-
super();
|
|
207
|
+
constructor(tokens, mode) {
|
|
208
|
+
super(mode);
|
|
190
209
|
this.tokens = tokens;
|
|
191
210
|
}
|
|
192
211
|
next() {
|
|
@@ -202,10 +221,16 @@ export class TokenStreamer extends TokenStream {
|
|
|
202
221
|
hasLineTerminatorBeforeNext() {
|
|
203
222
|
return false;
|
|
204
223
|
}
|
|
224
|
+
hasLineTerminatorAfterNext() {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
scanTemplateContinuation() {
|
|
228
|
+
return this.next();
|
|
229
|
+
}
|
|
205
230
|
}
|
|
206
231
|
export class TokenStreamImpl extends TokenStream {
|
|
207
|
-
constructor(expression) {
|
|
208
|
-
super();
|
|
232
|
+
constructor(expression, mode) {
|
|
233
|
+
super(mode);
|
|
209
234
|
this.expression = expression;
|
|
210
235
|
}
|
|
211
236
|
newToken(type, value) {
|
|
@@ -213,7 +238,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
213
238
|
}
|
|
214
239
|
next() {
|
|
215
240
|
if (this.pos >= this.expression.length) {
|
|
216
|
-
return EOFToken;
|
|
241
|
+
return this.current = EOFToken;
|
|
217
242
|
}
|
|
218
243
|
this.last = this.current;
|
|
219
244
|
if (this.isWhitespace() || this.isComment()) {
|
|
@@ -233,6 +258,9 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
233
258
|
|| this.isProperty()) {
|
|
234
259
|
return this.current;
|
|
235
260
|
}
|
|
261
|
+
else if (this.pos >= this.expression.length) {
|
|
262
|
+
return this.current = EOFToken;
|
|
263
|
+
}
|
|
236
264
|
else {
|
|
237
265
|
throw new Error(this.createError('Unknown character "' + this.expression.charAt(this.pos) + '"'));
|
|
238
266
|
}
|
|
@@ -242,20 +270,70 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
242
270
|
const str = this.expression.substring(this.pos, limit);
|
|
243
271
|
return /(?:\r?\n)/g.test(str);
|
|
244
272
|
}
|
|
273
|
+
hasLineTerminatorAfterNext() {
|
|
274
|
+
const start = this.peekPosition();
|
|
275
|
+
const end = this.peekAheadPosition();
|
|
276
|
+
const str = this.expression.substring(start, end);
|
|
277
|
+
return /(?:\r?\n)/g.test(str);
|
|
278
|
+
}
|
|
245
279
|
isString() {
|
|
246
280
|
const quote = this.expression.charAt(this.pos);
|
|
247
281
|
if (quote === '\'' || quote === '"') {
|
|
248
|
-
const
|
|
249
|
-
let
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
282
|
+
const start = this.pos;
|
|
283
|
+
let literal = [];
|
|
284
|
+
let c0 = '';
|
|
285
|
+
const advance = () => {
|
|
286
|
+
c0 = this.expression.charAt(++this.pos);
|
|
287
|
+
};
|
|
288
|
+
const advanceUntil = (check) => {
|
|
289
|
+
while (true) {
|
|
290
|
+
c0 = this.expression.charAt(++this.pos);
|
|
291
|
+
if (this.pos >= this.expression.length) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const result = check(c0);
|
|
295
|
+
if (result) {
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
const addLiteralChar = (char) => literal.push(char);
|
|
301
|
+
while (true) {
|
|
302
|
+
advanceUntil(char => {
|
|
303
|
+
if (char.charCodeAt(0) > 127) {
|
|
304
|
+
if (this.isStringLiteralLineTerminator(char)) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
addLiteralChar(char);
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
if (this.mayTerminateString(char))
|
|
311
|
+
return true;
|
|
312
|
+
addLiteralChar(c0);
|
|
313
|
+
return false;
|
|
314
|
+
});
|
|
315
|
+
while (c0 === '\\') {
|
|
316
|
+
advance();
|
|
317
|
+
const char = this.scanEscape(false);
|
|
318
|
+
if (char == '' || !char) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
addLiteralChar(char);
|
|
322
|
+
advance();
|
|
323
|
+
}
|
|
324
|
+
if (c0 === quote) {
|
|
325
|
+
advance();
|
|
326
|
+
const end = this.pos;
|
|
327
|
+
const string = literal.join('');
|
|
328
|
+
const rawString = this.expression.substring(start, end);
|
|
329
|
+
const stringNode = new Literal(string, rawString);
|
|
255
330
|
this.current = this.newToken(Token.STRING, stringNode);
|
|
256
331
|
return true;
|
|
257
332
|
}
|
|
258
|
-
|
|
333
|
+
if (c0 == '' || this.pos >= this.expression.length) {
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
addLiteralChar(c0);
|
|
259
337
|
}
|
|
260
338
|
}
|
|
261
339
|
return false;
|
|
@@ -263,50 +341,223 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
263
341
|
isTemplateLiteral() {
|
|
264
342
|
const quote = this.expression.charAt(this.pos);
|
|
265
343
|
if (quote === '`') {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
344
|
+
this.pos++;
|
|
345
|
+
this.current = this.scanTemplateSpan();
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
scanTemplateSpan() {
|
|
351
|
+
let result = Token.TEMPLATE_SPAN;
|
|
352
|
+
let literal = [], c0 = this.expression.charAt(this.pos);
|
|
353
|
+
const advance = () => {
|
|
354
|
+
this.pos++;
|
|
355
|
+
c0 = this.expression.charAt(this.pos);
|
|
356
|
+
};
|
|
357
|
+
const addLiteralChar = (char) => literal.push(char);
|
|
358
|
+
while (true) {
|
|
359
|
+
let c = c0;
|
|
360
|
+
if (c == '`') {
|
|
361
|
+
advance();
|
|
362
|
+
result = Token.TEMPLATE_TAIL;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
else if (c == '$' && this.expression.charAt(this.pos + 1) == '{') {
|
|
366
|
+
advance();
|
|
367
|
+
advance();
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
else if (c == '\\') {
|
|
371
|
+
advance();
|
|
372
|
+
if (this.isLineTerminator(c0)) {
|
|
373
|
+
let lastChar = c0;
|
|
374
|
+
advance();
|
|
375
|
+
if (lastChar == '\r') {
|
|
376
|
+
if (c0 == '\n')
|
|
377
|
+
advance();
|
|
378
|
+
lastChar = '\n';
|
|
287
379
|
}
|
|
288
|
-
|
|
380
|
+
addLiteralChar(lastChar);
|
|
289
381
|
}
|
|
290
|
-
else
|
|
291
|
-
|
|
382
|
+
else {
|
|
383
|
+
const char = this.scanEscape(true);
|
|
384
|
+
if (char === false) {
|
|
385
|
+
throw new SyntaxError(this.createError('Unterminated Template Escape char'));
|
|
386
|
+
}
|
|
387
|
+
addLiteralChar(char);
|
|
388
|
+
advance();
|
|
292
389
|
}
|
|
293
390
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
391
|
+
else if (c == '' || this.pos >= this.expression.length) {
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
advance();
|
|
396
|
+
if (c == '\r') {
|
|
397
|
+
if (c0 == '\n')
|
|
398
|
+
advance();
|
|
399
|
+
c = '\n';
|
|
400
|
+
}
|
|
401
|
+
addLiteralChar(c);
|
|
402
|
+
}
|
|
298
403
|
}
|
|
299
|
-
return
|
|
404
|
+
return this.newToken(result, new TemplateStringLiteral(literal.join('')));
|
|
405
|
+
}
|
|
406
|
+
scanTemplateContinuation() {
|
|
407
|
+
if (this.current.isNotType(Token.RBRACE)) {
|
|
408
|
+
throw new SyntaxError(this.createError('Unterminated Template Expr'));
|
|
409
|
+
}
|
|
410
|
+
return this.scanTemplateSpan();
|
|
411
|
+
}
|
|
412
|
+
scanEscape(scanTemplateSpan) {
|
|
413
|
+
let c0 = this.expression.charAt(this.pos);
|
|
414
|
+
let c = c0;
|
|
415
|
+
if (!scanTemplateSpan && this.isLineTerminator(c)) {
|
|
416
|
+
if (c == '\r' && this.expression.charAt(this.pos + 1) == '\n')
|
|
417
|
+
this.pos++;
|
|
418
|
+
return '\n';
|
|
419
|
+
}
|
|
420
|
+
switch (c) {
|
|
421
|
+
case 'b':
|
|
422
|
+
c = '\b';
|
|
423
|
+
break;
|
|
424
|
+
case 'f':
|
|
425
|
+
c = '\f';
|
|
426
|
+
break;
|
|
427
|
+
case 'n':
|
|
428
|
+
c = '\n';
|
|
429
|
+
break;
|
|
430
|
+
case 'r':
|
|
431
|
+
c = '\r';
|
|
432
|
+
break;
|
|
433
|
+
case 't':
|
|
434
|
+
c = '\t';
|
|
435
|
+
break;
|
|
436
|
+
case 'u': {
|
|
437
|
+
this.pos++;
|
|
438
|
+
c = this.scanUnicodeEscape();
|
|
439
|
+
if (c === false)
|
|
440
|
+
return false;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
case 'v':
|
|
444
|
+
c = '\v';
|
|
445
|
+
break;
|
|
446
|
+
case 'x': {
|
|
447
|
+
this.pos++;
|
|
448
|
+
c = this.scanHexNumber(2);
|
|
449
|
+
if (c === false)
|
|
450
|
+
return false;
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
case '0':
|
|
454
|
+
case '1':
|
|
455
|
+
case '2':
|
|
456
|
+
case '3':
|
|
457
|
+
case '4':
|
|
458
|
+
case '5':
|
|
459
|
+
case '6':
|
|
460
|
+
case '7':
|
|
461
|
+
this.pos++;
|
|
462
|
+
c = this.scanOctalEscape(c, 2);
|
|
463
|
+
break;
|
|
464
|
+
case '8':
|
|
465
|
+
case '9':
|
|
466
|
+
throw new SyntaxError(this.createError(`'\\8' and '\\9' are disallowed in strict mode.`));
|
|
467
|
+
}
|
|
468
|
+
return c;
|
|
469
|
+
}
|
|
470
|
+
scanUnicodeEscape() {
|
|
471
|
+
let c0 = this.expression.charAt(this.pos);
|
|
472
|
+
if (c0 == '{') {
|
|
473
|
+
this.pos++;
|
|
474
|
+
const cp = this.scanUnlimitedLengthHexNumber(0x10ffff);
|
|
475
|
+
c0 = this.expression.charAt(++this.pos);
|
|
476
|
+
if (c0 != '}') {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
return cp;
|
|
480
|
+
}
|
|
481
|
+
return this.scanHexNumber(4);
|
|
482
|
+
}
|
|
483
|
+
scanHexNumber(length) {
|
|
484
|
+
if (length > 4) {
|
|
485
|
+
throw new RangeError(this.createError('ScanHexNumber: length should be less than or equal to 4'));
|
|
486
|
+
}
|
|
487
|
+
let x = 0;
|
|
488
|
+
let scanned = this.pos;
|
|
489
|
+
let c0 = this.expression.charAt(scanned);
|
|
490
|
+
for (let i = 0; i < length; i++) {
|
|
491
|
+
let d = this.hexValue(c0);
|
|
492
|
+
if (d < 0) {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
x = x * 16 + d;
|
|
496
|
+
c0 = this.expression.charAt(++scanned);
|
|
497
|
+
}
|
|
498
|
+
this.pos = scanned - 1;
|
|
499
|
+
return String.fromCodePoint(x);
|
|
500
|
+
}
|
|
501
|
+
scanUnlimitedLengthHexNumber(max_value) {
|
|
502
|
+
let x = 0;
|
|
503
|
+
let scanned = this.pos;
|
|
504
|
+
let c0 = this.expression.charAt(scanned);
|
|
505
|
+
let d = this.hexValue(c0);
|
|
506
|
+
if (d < 0) {
|
|
507
|
+
throw new RangeError(this.createError('Invalid code'));
|
|
508
|
+
}
|
|
509
|
+
while (d >= 0) {
|
|
510
|
+
x = x * 16 + d;
|
|
511
|
+
if (x > max_value) {
|
|
512
|
+
throw new RangeError(this.createError('Undefined Unicode Code Point'));
|
|
513
|
+
}
|
|
514
|
+
c0 = this.expression.charAt(++scanned);
|
|
515
|
+
d = this.hexValue(c0);
|
|
516
|
+
}
|
|
517
|
+
this.pos = scanned - 1;
|
|
518
|
+
return String.fromCodePoint(x);
|
|
519
|
+
}
|
|
520
|
+
hexValue(c) {
|
|
521
|
+
let x = c.charCodeAt(0) - '0'.charCodeAt(0);
|
|
522
|
+
if (x <= 9)
|
|
523
|
+
return x;
|
|
524
|
+
x = (x | 0x20) - ('a'.charCodeAt(0) - '0'.charCodeAt(0));
|
|
525
|
+
if (x <= 5)
|
|
526
|
+
return x + 10;
|
|
527
|
+
return -1;
|
|
528
|
+
}
|
|
529
|
+
scanOctalEscape(c, length) {
|
|
530
|
+
if (!('0' <= c && c <= '7')) {
|
|
531
|
+
throw new SyntaxError(this.createError('Invalid octal escape sequence'));
|
|
532
|
+
}
|
|
533
|
+
const zero = '0'.charCodeAt(0);
|
|
534
|
+
let x = c.charCodeAt(0) - zero;
|
|
535
|
+
let scanned = 0;
|
|
536
|
+
let i = 0;
|
|
537
|
+
let char = '';
|
|
538
|
+
for (; i < length; i++) {
|
|
539
|
+
char = this.expression.charAt(this.pos + i);
|
|
540
|
+
let d = char.charCodeAt(0) - zero;
|
|
541
|
+
if (d < 0 || d > 7)
|
|
542
|
+
break;
|
|
543
|
+
const nx = x * 8 + d;
|
|
544
|
+
if (nx >= 256)
|
|
545
|
+
break;
|
|
546
|
+
x = nx;
|
|
547
|
+
scanned++;
|
|
548
|
+
}
|
|
549
|
+
this.pos += scanned - 1;
|
|
550
|
+
return String.fromCharCode(x);
|
|
300
551
|
}
|
|
301
552
|
isParentheses() {
|
|
302
553
|
const char = this.expression.charAt(this.pos);
|
|
303
554
|
if (char === '(') {
|
|
304
|
-
this.current = this.newToken(Token.
|
|
555
|
+
this.current = this.newToken(Token.LPAREN);
|
|
305
556
|
this.pos++;
|
|
306
557
|
return true;
|
|
307
558
|
}
|
|
308
559
|
else if (char === ')') {
|
|
309
|
-
this.current = this.newToken(Token.
|
|
560
|
+
this.current = this.newToken(Token.RPAREN);
|
|
310
561
|
this.pos++;
|
|
311
562
|
return true;
|
|
312
563
|
}
|
|
@@ -315,12 +566,12 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
315
566
|
isBracket() {
|
|
316
567
|
const char = this.expression.charAt(this.pos);
|
|
317
568
|
if (char === '[') {
|
|
318
|
-
this.current = this.newToken(Token.
|
|
569
|
+
this.current = this.newToken(Token.LBRACK);
|
|
319
570
|
this.pos++;
|
|
320
571
|
return true;
|
|
321
572
|
}
|
|
322
573
|
else if (char === ']') {
|
|
323
|
-
this.current = this.newToken(Token.
|
|
574
|
+
this.current = this.newToken(Token.RBRACK);
|
|
324
575
|
this.pos++;
|
|
325
576
|
return true;
|
|
326
577
|
}
|
|
@@ -329,12 +580,12 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
329
580
|
isCurlY() {
|
|
330
581
|
const char = this.expression.charAt(this.pos);
|
|
331
582
|
if (char === '{') {
|
|
332
|
-
this.current = this.newToken(Token.
|
|
583
|
+
this.current = this.newToken(Token.LBRACE);
|
|
333
584
|
this.pos++;
|
|
334
585
|
return true;
|
|
335
586
|
}
|
|
336
587
|
else if (char === '}') {
|
|
337
|
-
this.current = this.newToken(Token.
|
|
588
|
+
this.current = this.newToken(Token.RBRACE);
|
|
338
589
|
this.pos++;
|
|
339
590
|
return true;
|
|
340
591
|
}
|
|
@@ -361,47 +612,80 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
361
612
|
isProperty() {
|
|
362
613
|
let startPos = this.pos;
|
|
363
614
|
let i = startPos;
|
|
364
|
-
let hasLetter = false;
|
|
365
615
|
let isPrivate = false;
|
|
366
|
-
|
|
616
|
+
let escape = false;
|
|
617
|
+
let escapeFlag = false;
|
|
618
|
+
let char = this.expression.charAt(i);
|
|
619
|
+
if (char === '#') {
|
|
367
620
|
isPrivate = true;
|
|
621
|
+
startPos++;
|
|
622
|
+
i++;
|
|
623
|
+
}
|
|
624
|
+
char = this.expression.charAt(i);
|
|
625
|
+
if (!IdentifierStartRegex.test(char)) {
|
|
626
|
+
if (char === '\\' && this.expression.charAt(i + 1) === 'u') {
|
|
627
|
+
i += 2;
|
|
628
|
+
escapeFlag = escape = true;
|
|
629
|
+
}
|
|
630
|
+
else {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
368
635
|
i++;
|
|
369
636
|
}
|
|
370
637
|
for (; i < this.expression.length; i++) {
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
if (
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
638
|
+
char = this.expression.charAt(i);
|
|
639
|
+
if (!IdentifierPartRegex.test(char)) {
|
|
640
|
+
if (char === '\\' && this.expression.charAt(i + 1) === 'u') {
|
|
641
|
+
i++;
|
|
642
|
+
escapeFlag = escape = true;
|
|
377
643
|
continue;
|
|
378
644
|
}
|
|
379
|
-
|
|
380
|
-
|
|
645
|
+
if ('{' === char && escapeFlag) {
|
|
646
|
+
const end = this.expression.indexOf('}', i + 1);
|
|
647
|
+
if (end === -1) {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
escapeFlag = false;
|
|
651
|
+
i = end;
|
|
652
|
+
continue;
|
|
381
653
|
}
|
|
654
|
+
break;
|
|
382
655
|
}
|
|
383
|
-
|
|
384
|
-
|
|
656
|
+
}
|
|
657
|
+
let identifierName = this.expression.substring(startPos, i);
|
|
658
|
+
if (escape) {
|
|
659
|
+
identifierName = this.unescape(identifierName);
|
|
660
|
+
if (!IdentifierRegex.test(identifierName)) {
|
|
661
|
+
return false;
|
|
385
662
|
}
|
|
663
|
+
this.pos = i;
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
this.pos += identifierName.length + (isPrivate ? 1 : 0);
|
|
386
667
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
668
|
+
let node;
|
|
669
|
+
if (isPrivate) {
|
|
670
|
+
node = new PrivateIdentifier(identifierName);
|
|
671
|
+
this.current = this.newToken(Token.PRIVATE_NAME, node);
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
switch (identifierName) {
|
|
391
675
|
case 'this':
|
|
392
|
-
this.current = this.newToken(Token.THIS);
|
|
676
|
+
this.current = this.newToken(Token.THIS, ThisNode);
|
|
393
677
|
break;
|
|
394
678
|
case 'null':
|
|
395
|
-
this.current = this.newToken(Token.NULL_LITERAL);
|
|
679
|
+
this.current = this.newToken(Token.NULL_LITERAL, NullNode);
|
|
396
680
|
break;
|
|
397
681
|
case 'undefined':
|
|
398
|
-
this.current = this.newToken(Token.UNDEFINED_LITERAL);
|
|
682
|
+
this.current = this.newToken(Token.UNDEFINED_LITERAL, UndefinedNode);
|
|
399
683
|
break;
|
|
400
684
|
case 'true':
|
|
401
|
-
this.current = this.newToken(Token.TRUE_LITERAL);
|
|
685
|
+
this.current = this.newToken(Token.TRUE_LITERAL, TrueNode);
|
|
402
686
|
break;
|
|
403
687
|
case 'false':
|
|
404
|
-
this.current = this.newToken(Token.FALSE_LITERAL);
|
|
688
|
+
this.current = this.newToken(Token.FALSE_LITERAL, FalseNode);
|
|
405
689
|
break;
|
|
406
690
|
case 'globalThis':
|
|
407
691
|
this.current = this.newToken(Token.IDENTIFIER, GlobalThisNode);
|
|
@@ -415,24 +699,49 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
415
699
|
case 'as':
|
|
416
700
|
this.current = this.newToken(Token.IDENTIFIER, AsNode);
|
|
417
701
|
break;
|
|
702
|
+
case 'default':
|
|
703
|
+
this.current = this.newToken(Token.DEFAULT, DefaultNode);
|
|
704
|
+
break;
|
|
705
|
+
case 'yield':
|
|
706
|
+
this.current = this.newToken(Token.YIELD, YieldIdentifier);
|
|
707
|
+
break;
|
|
708
|
+
case 'constructor':
|
|
709
|
+
this.current = this.newToken(Token.IDENTIFIER, ConstructorIdentifier);
|
|
710
|
+
break;
|
|
711
|
+
case 'arguments':
|
|
712
|
+
this.current = this.newToken(Token.IDENTIFIER, ArgumentsIdentifier);
|
|
713
|
+
break;
|
|
714
|
+
case 'name':
|
|
715
|
+
this.current = this.newToken(Token.IDENTIFIER, NameIdentifier);
|
|
716
|
+
break;
|
|
717
|
+
case 'eval':
|
|
718
|
+
this.current = this.newToken(Token.IDENTIFIER, EvalIdentifier);
|
|
719
|
+
break;
|
|
720
|
+
case 'debugger':
|
|
721
|
+
this.current = this.newToken(Token.DEBUGGER, DebuggerStatement.INSTANCE);
|
|
722
|
+
break;
|
|
723
|
+
case 'class':
|
|
724
|
+
this.current = this.newToken(Token.CLASS);
|
|
725
|
+
break;
|
|
726
|
+
case 'await':
|
|
727
|
+
this.current = this.newToken(Token.AWAIT, AwaitIdentifier);
|
|
728
|
+
break;
|
|
729
|
+
case 'async':
|
|
730
|
+
this.current = this.newToken(Token.ASYNC, AsyncIdentifier);
|
|
731
|
+
break;
|
|
418
732
|
default:
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
this.current = this.newToken(Token.PRIVATE_NAME, node);
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
node = new Identifier(prop);
|
|
425
|
-
this.current = this.newToken(Token.IDENTIFIER, node);
|
|
426
|
-
}
|
|
733
|
+
node = new Identifier(identifierName);
|
|
734
|
+
this.current = this.newToken(Token.IDENTIFIER, node);
|
|
427
735
|
break;
|
|
428
736
|
}
|
|
429
|
-
this.pos += prop.length;
|
|
430
|
-
return true;
|
|
431
737
|
}
|
|
432
|
-
return
|
|
738
|
+
return true;
|
|
433
739
|
}
|
|
434
740
|
isWhitespace() {
|
|
435
741
|
let result = false;
|
|
742
|
+
while (FORBIDDEN_CODE_POINT.includes(this.expression.charCodeAt(this.pos).toString(16))) {
|
|
743
|
+
this.pos++;
|
|
744
|
+
}
|
|
436
745
|
let char = this.expression.charAt(this.pos);
|
|
437
746
|
while (/\s/.test(char)) {
|
|
438
747
|
result = true;
|
|
@@ -447,45 +756,117 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
447
756
|
isComment() {
|
|
448
757
|
const char = this.expression.charAt(this.pos);
|
|
449
758
|
const nextChar = this.expression.charAt(this.pos + 1);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
759
|
+
let closeTag;
|
|
760
|
+
let endPos;
|
|
761
|
+
switch (true) {
|
|
762
|
+
case (char === '/' && nextChar === '/'):
|
|
763
|
+
closeTag = '\n';
|
|
764
|
+
endPos = this.expression.indexOf(closeTag, this.pos);
|
|
765
|
+
break;
|
|
766
|
+
case (char === '/' && nextChar === '*'):
|
|
767
|
+
closeTag = '*/';
|
|
768
|
+
endPos = this.expression.indexOf(closeTag, this.pos);
|
|
769
|
+
if (endPos === -1) {
|
|
770
|
+
throw new SyntaxError(this.createError('Invalid or unexpected token'));
|
|
771
|
+
}
|
|
772
|
+
break;
|
|
773
|
+
case (char === '<' && nextChar === '!'):
|
|
774
|
+
if ('<!--' === this.expression.substring(this.pos, this.pos + 4)) {
|
|
775
|
+
if (isStrict(this.mode)) {
|
|
776
|
+
throw new SyntaxError('Html Comment not allowed In Module');
|
|
777
|
+
}
|
|
778
|
+
const nextLinePos = this.expression.indexOf('\n', this.pos);
|
|
779
|
+
const closePos = this.expression.indexOf('-->', this.pos);
|
|
780
|
+
if (nextLinePos < closePos) {
|
|
781
|
+
closeTag = '\n';
|
|
782
|
+
endPos = nextLinePos;
|
|
783
|
+
}
|
|
784
|
+
else if (closePos < nextLinePos) {
|
|
785
|
+
closeTag = '-->';
|
|
786
|
+
endPos = closePos;
|
|
787
|
+
}
|
|
788
|
+
else {
|
|
789
|
+
closeTag = '';
|
|
790
|
+
endPos = -1;
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
case (char === '-' && nextChar === '-'):
|
|
795
|
+
if ('-->' === this.expression.substring(this.pos, this.pos + 3)) {
|
|
796
|
+
if (isStrict(this.mode)) {
|
|
797
|
+
throw new SyntaxError('Html Comment not allowed In Module');
|
|
798
|
+
}
|
|
799
|
+
let indexOfLastLine = this.expression.lastIndexOf('\n', this.pos + 1);
|
|
800
|
+
if (indexOfLastLine == -1) {
|
|
801
|
+
indexOfLastLine = 0;
|
|
802
|
+
}
|
|
803
|
+
let lastLine = this.expression.substring(indexOfLastLine, this.pos + 3);
|
|
804
|
+
if (!/^\s*-->$/g.test(lastLine)) {
|
|
805
|
+
let lastBlockCommentPos = lastLine.lastIndexOf('*/');
|
|
806
|
+
if (lastBlockCommentPos == -1) {
|
|
807
|
+
return false;
|
|
808
|
+
}
|
|
809
|
+
lastLine = lastLine.substring(lastBlockCommentPos + 2);
|
|
810
|
+
if (!/^\s*-->$/g.test(lastLine)) {
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
endPos = this.expression.indexOf('\n', this.pos);
|
|
815
|
+
closeTag = '\n';
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
default:
|
|
819
|
+
return false;
|
|
463
820
|
}
|
|
464
|
-
|
|
821
|
+
this.pos = endPos == -1 ? this.expression.length : endPos + closeTag.length;
|
|
822
|
+
return true;
|
|
823
|
+
}
|
|
824
|
+
isLineTerminator(c) {
|
|
825
|
+
return /[\n\r\u2028\u2029]/.test(c);
|
|
826
|
+
}
|
|
827
|
+
isStringLiteralLineTerminator(c) {
|
|
828
|
+
return /[\n\r]/.test(c);
|
|
829
|
+
}
|
|
830
|
+
mayTerminateString(c) {
|
|
831
|
+
return (c == '\'' || c == '"' || c == '\n' || c == '\r' || c == '\\');
|
|
465
832
|
}
|
|
466
833
|
scanRegExpPattern() {
|
|
467
834
|
const peek = this.peek();
|
|
468
835
|
if (peek.isType(Token.DIV) || peek.isType(Token.DIV_ASSIGN)) {
|
|
469
836
|
this.next();
|
|
470
837
|
let pattern = peek.isType(Token.DIV_ASSIGN) ? '=' : '';
|
|
471
|
-
let start = this.pos;
|
|
472
838
|
let currentPos = this.pos;
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
839
|
+
let inCharacterClass = false;
|
|
840
|
+
let c = this.expression.charAt(currentPos);
|
|
841
|
+
while (c !== '/' || inCharacterClass) {
|
|
842
|
+
if (c == '' || this.isLineTerminator(c)) {
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
845
|
+
if (c === '\\') {
|
|
846
|
+
pattern += c;
|
|
847
|
+
c = this.expression.charAt(++currentPos);
|
|
848
|
+
if (c == '' || this.isLineTerminator(c)) {
|
|
849
|
+
return false;
|
|
850
|
+
}
|
|
851
|
+
pattern += c;
|
|
852
|
+
c = this.expression.charAt(++currentPos);
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
if (c == '[')
|
|
856
|
+
inCharacterClass = true;
|
|
857
|
+
if (c == ']')
|
|
858
|
+
inCharacterClass = false;
|
|
859
|
+
pattern += c;
|
|
860
|
+
c = this.expression.charAt(++currentPos);
|
|
861
|
+
}
|
|
481
862
|
}
|
|
482
|
-
pattern += this.expression.substring(start, currentPos);
|
|
483
863
|
currentPos++;
|
|
484
864
|
let flags = '';
|
|
485
865
|
const remainFlags = TokenStreamImpl.REGEXP_FLAGS.slice();
|
|
486
866
|
while (true) {
|
|
867
|
+
const code = this.expression.charCodeAt(currentPos);
|
|
487
868
|
const nextChar = this.expression.charAt(currentPos);
|
|
488
|
-
if (/[\.\s]/.test(nextChar)) {
|
|
869
|
+
if (/[\.\s]/.test(nextChar) || Number.isNaN(code)) {
|
|
489
870
|
break;
|
|
490
871
|
}
|
|
491
872
|
const nextCharIndex = remainFlags.indexOf(nextChar);
|
|
@@ -501,7 +882,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
501
882
|
currentPos++;
|
|
502
883
|
}
|
|
503
884
|
}
|
|
504
|
-
const regexNode = new
|
|
885
|
+
const regexNode = new Literal(new RegExp(pattern, flags), `/${pattern}/${flags}`, { pattern, flags });
|
|
505
886
|
this.current = this.newToken(Token.REGEXP_LITERAL, regexNode);
|
|
506
887
|
this.pos = currentPos;
|
|
507
888
|
return true;
|
|
@@ -517,52 +898,101 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
517
898
|
while (index >= 0) {
|
|
518
899
|
const c = v.charAt(++index);
|
|
519
900
|
switch (c) {
|
|
520
|
-
case '\'
|
|
521
|
-
case '
|
|
522
|
-
case '
|
|
523
|
-
case '
|
|
524
|
-
|
|
901
|
+
case '\b':
|
|
902
|
+
case '\f':
|
|
903
|
+
case '\n':
|
|
904
|
+
case '\r':
|
|
905
|
+
case '\t':
|
|
906
|
+
case '\v':
|
|
907
|
+
index++;
|
|
908
|
+
buffer += '\\' + c;
|
|
525
909
|
break;
|
|
526
910
|
case 'b':
|
|
911
|
+
index++;
|
|
527
912
|
buffer += '\b';
|
|
528
913
|
break;
|
|
529
914
|
case 'f':
|
|
915
|
+
index++;
|
|
530
916
|
buffer += '\f';
|
|
531
917
|
break;
|
|
532
918
|
case 'n':
|
|
919
|
+
index++;
|
|
533
920
|
buffer += '\n';
|
|
534
921
|
break;
|
|
535
922
|
case 'r':
|
|
923
|
+
index++;
|
|
536
924
|
buffer += '\r';
|
|
537
925
|
break;
|
|
538
926
|
case 't':
|
|
927
|
+
index++;
|
|
539
928
|
buffer += '\t';
|
|
540
929
|
break;
|
|
930
|
+
case 'v':
|
|
931
|
+
index++;
|
|
932
|
+
buffer += '\v';
|
|
933
|
+
break;
|
|
541
934
|
case 'u': {
|
|
542
|
-
|
|
543
|
-
if (
|
|
544
|
-
|
|
935
|
+
index++;
|
|
936
|
+
if ('{' === v.charAt(index)) {
|
|
937
|
+
index++;
|
|
938
|
+
const start = index;
|
|
939
|
+
const end = v.indexOf('}', start + 1);
|
|
940
|
+
const codePoint = v.substring(start, end);
|
|
941
|
+
buffer += String.fromCodePoint(parseInt(codePoint, 16));
|
|
942
|
+
index = end + 1;
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
const codePoint = v.substring(index, index + 4);
|
|
946
|
+
if (!TokenStreamImpl.UnicodePattern.test(codePoint)) {
|
|
947
|
+
throw new Error(this.createError('Illegal escape sequence: \\u ' + codePoint));
|
|
948
|
+
}
|
|
949
|
+
buffer += String.fromCodePoint(parseInt(codePoint, 16));
|
|
950
|
+
index += 4;
|
|
545
951
|
}
|
|
546
|
-
buffer += String.fromCharCode(parseInt(codePoint, 16));
|
|
547
|
-
index += 4;
|
|
548
952
|
break;
|
|
549
953
|
}
|
|
550
954
|
case 'x': {
|
|
551
|
-
|
|
955
|
+
index++;
|
|
956
|
+
let codePoint = v.substring(index, index + 2);
|
|
552
957
|
if (!TokenStreamImpl.DecimalPattern.test(codePoint)) {
|
|
553
|
-
throw new Error(this.createError('Illegal escape sequence: \\x' + codePoint));
|
|
958
|
+
throw new Error(this.createError('Illegal escape sequence: \\x ' + codePoint));
|
|
554
959
|
}
|
|
555
960
|
buffer += String.fromCharCode(parseInt(codePoint, 16));
|
|
556
961
|
index += 2;
|
|
557
962
|
break;
|
|
558
963
|
}
|
|
559
964
|
default:
|
|
560
|
-
|
|
965
|
+
if (!Number.isNaN(parseInt(c, 8))) {
|
|
966
|
+
let codePoint = c;
|
|
967
|
+
for (const i of [1, 2]) {
|
|
968
|
+
const tempChar = v.charAt(index + i);
|
|
969
|
+
if (!Number.isNaN(parseInt(tempChar, 8))) {
|
|
970
|
+
codePoint += tempChar;
|
|
971
|
+
}
|
|
972
|
+
else {
|
|
973
|
+
break;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
if (!TokenStreamImpl.AsciiPattern.test(codePoint)) {
|
|
977
|
+
throw new Error(this.createError('Illegal escape sequence: ASCII 8 base, ' + codePoint));
|
|
978
|
+
}
|
|
979
|
+
buffer += String.fromCharCode(parseInt(codePoint, 8));
|
|
980
|
+
index += codePoint.length;
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
index++;
|
|
984
|
+
buffer += c;
|
|
985
|
+
break;
|
|
561
986
|
}
|
|
562
|
-
++index;
|
|
563
987
|
let backslash = v.indexOf('\\', index);
|
|
564
|
-
|
|
565
|
-
|
|
988
|
+
if (backslash == -1) {
|
|
989
|
+
buffer += v.substring(index, v.length);
|
|
990
|
+
break;
|
|
991
|
+
}
|
|
992
|
+
else {
|
|
993
|
+
buffer += v.substring(index, backslash);
|
|
994
|
+
index = backslash;
|
|
995
|
+
}
|
|
566
996
|
}
|
|
567
997
|
return buffer;
|
|
568
998
|
}
|
|
@@ -600,7 +1030,9 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
600
1030
|
}
|
|
601
1031
|
}
|
|
602
1032
|
if (valid) {
|
|
603
|
-
const
|
|
1033
|
+
const string = this.expression.substring(startPos, pos);
|
|
1034
|
+
const rawString = this.expression.substring(this.pos, pos);
|
|
1035
|
+
const numNode = new Literal(parseInt(string, radix), rawString);
|
|
604
1036
|
this.current = this.newToken(Token.NUMBER, numNode);
|
|
605
1037
|
this.pos = pos;
|
|
606
1038
|
}
|
|
@@ -613,6 +1045,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
613
1045
|
let resetPos = pos;
|
|
614
1046
|
let foundDot = false;
|
|
615
1047
|
let foundDigits = false;
|
|
1048
|
+
let isOctal = false;
|
|
616
1049
|
let c;
|
|
617
1050
|
while (pos < this.expression.length) {
|
|
618
1051
|
c = this.expression.charAt(pos);
|
|
@@ -626,6 +1059,15 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
626
1059
|
pos++;
|
|
627
1060
|
valid = foundDigits;
|
|
628
1061
|
}
|
|
1062
|
+
else if ('o' == c.toLowerCase()) {
|
|
1063
|
+
if (pos == startPos + 1) {
|
|
1064
|
+
pos++;
|
|
1065
|
+
isOctal = true;
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
629
1071
|
else {
|
|
630
1072
|
break;
|
|
631
1073
|
}
|
|
@@ -656,13 +1098,26 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
656
1098
|
}
|
|
657
1099
|
}
|
|
658
1100
|
if (valid) {
|
|
1101
|
+
const rawString = this.expression.substring(startPos, pos);
|
|
659
1102
|
if (this.expression.charAt(pos) === 'n') {
|
|
660
|
-
const bigintNode = new
|
|
1103
|
+
const bigintNode = new Literal(BigInt(rawString), rawString + 'n', undefined, rawString);
|
|
661
1104
|
this.current = this.newToken(Token.BIGINT, bigintNode);
|
|
662
1105
|
pos++;
|
|
663
1106
|
}
|
|
664
1107
|
else {
|
|
665
|
-
|
|
1108
|
+
let numNode;
|
|
1109
|
+
if (isOctal) {
|
|
1110
|
+
const octal = rawString.substring(2);
|
|
1111
|
+
if (TokenStreamImpl.OctalPattern.test(octal)) {
|
|
1112
|
+
numNode = new Literal(parseInt(octal, 8), rawString);
|
|
1113
|
+
}
|
|
1114
|
+
else {
|
|
1115
|
+
return false;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
else {
|
|
1119
|
+
numNode = new Literal(parseFloat(rawString), rawString);
|
|
1120
|
+
}
|
|
666
1121
|
this.current = this.newToken(Token.NUMBER, numNode);
|
|
667
1122
|
}
|
|
668
1123
|
this.pos = pos;
|
|
@@ -970,12 +1425,12 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
970
1425
|
return true;
|
|
971
1426
|
case 'a':
|
|
972
1427
|
if (/async\s/.test(this.expression.substring(this.pos, this.pos + 6))) {
|
|
973
|
-
this.current = this.newToken(Token.ASYNC);
|
|
1428
|
+
this.current = this.newToken(Token.ASYNC, AsyncIdentifier);
|
|
974
1429
|
this.pos += 5;
|
|
975
1430
|
return true;
|
|
976
1431
|
}
|
|
977
1432
|
if (/await\s/.test(this.expression.substring(this.pos, this.pos + 6))) {
|
|
978
|
-
this.current = this.newToken(Token.AWAIT);
|
|
1433
|
+
this.current = this.newToken(Token.AWAIT, AwaitIdentifier);
|
|
979
1434
|
this.pos += 5;
|
|
980
1435
|
return true;
|
|
981
1436
|
}
|
|
@@ -1029,18 +1484,6 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1029
1484
|
return true;
|
|
1030
1485
|
}
|
|
1031
1486
|
return false;
|
|
1032
|
-
case 'y':
|
|
1033
|
-
if (/yield\s/.test(this.expression.substring(this.pos, this.pos + 6))) {
|
|
1034
|
-
this.current = this.newToken(Token.YIELD);
|
|
1035
|
-
this.pos += 6;
|
|
1036
|
-
return true;
|
|
1037
|
-
}
|
|
1038
|
-
else if (/yield\*\s/.test(this.expression.substring(this.pos, this.pos + 7))) {
|
|
1039
|
-
this.current = this.newToken(Token.YIELD);
|
|
1040
|
-
this.pos += 5;
|
|
1041
|
-
return true;
|
|
1042
|
-
}
|
|
1043
|
-
return false;
|
|
1044
1487
|
default:
|
|
1045
1488
|
return false;
|
|
1046
1489
|
}
|
|
@@ -1050,7 +1493,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1050
1493
|
switch (char) {
|
|
1051
1494
|
case 'b':
|
|
1052
1495
|
if (/break\s?;?/.test(this.expression.substring(this.pos, this.pos + 7))) {
|
|
1053
|
-
this.current = this.newToken(Token.BREAK
|
|
1496
|
+
this.current = this.newToken(Token.BREAK);
|
|
1054
1497
|
this.pos += 5;
|
|
1055
1498
|
return true;
|
|
1056
1499
|
}
|
|
@@ -1077,25 +1520,20 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1077
1520
|
return true;
|
|
1078
1521
|
}
|
|
1079
1522
|
else if (/continue[\s;]/.test(this.expression.substring(this.pos, this.pos + 9))) {
|
|
1080
|
-
this.current = this.newToken(Token.CONTINUE
|
|
1523
|
+
this.current = this.newToken(Token.CONTINUE);
|
|
1081
1524
|
this.pos += 8;
|
|
1082
1525
|
return true;
|
|
1083
1526
|
}
|
|
1084
1527
|
return false;
|
|
1085
1528
|
case 'd':
|
|
1086
|
-
if (
|
|
1529
|
+
if (/do[\s|\{]/.test(this.expression.substring(this.pos, this.pos + 3))) {
|
|
1087
1530
|
this.current = this.newToken(Token.DO);
|
|
1088
1531
|
this.pos += 2;
|
|
1089
1532
|
return true;
|
|
1090
1533
|
}
|
|
1091
|
-
else if (/^(default\s?:)/.test(this.expression.substring(this.pos, this.pos + 9))) {
|
|
1092
|
-
this.current = this.newToken(Token.DEFAULT);
|
|
1093
|
-
this.pos += 7;
|
|
1094
|
-
return true;
|
|
1095
|
-
}
|
|
1096
1534
|
return false;
|
|
1097
1535
|
case 'e':
|
|
1098
|
-
if (/else
|
|
1536
|
+
if (/else[\s|\{]/.test(this.expression.substring(this.pos, this.pos + 5))) {
|
|
1099
1537
|
this.current = this.newToken(Token.ELSE);
|
|
1100
1538
|
this.pos += 4;
|
|
1101
1539
|
return true;
|
|
@@ -1113,7 +1551,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1113
1551
|
return false;
|
|
1114
1552
|
case 'g':
|
|
1115
1553
|
if (/get\s/.test(this.expression.substring(this.pos, this.pos + 4))) {
|
|
1116
|
-
this.current = this.newToken(Token.GET);
|
|
1554
|
+
this.current = this.newToken(Token.GET, GetIdentifier);
|
|
1117
1555
|
this.pos += 4;
|
|
1118
1556
|
return true;
|
|
1119
1557
|
}
|
|
@@ -1136,7 +1574,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1136
1574
|
}
|
|
1137
1575
|
return false;
|
|
1138
1576
|
case 'i':
|
|
1139
|
-
if (/if
|
|
1577
|
+
if (/if[\s|\(]/.test(this.expression.substring(this.pos, this.pos + 3))) {
|
|
1140
1578
|
this.current = this.newToken(Token.IF);
|
|
1141
1579
|
this.pos += 2;
|
|
1142
1580
|
return true;
|
|
@@ -1154,7 +1592,7 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1154
1592
|
return false;
|
|
1155
1593
|
case 'l':
|
|
1156
1594
|
if (/let\s/.test(this.expression.substring(this.pos, this.pos + 4))) {
|
|
1157
|
-
this.current = this.newToken(Token.LET);
|
|
1595
|
+
this.current = this.newToken(Token.LET, LetIdentifier);
|
|
1158
1596
|
this.pos += 4;
|
|
1159
1597
|
return true;
|
|
1160
1598
|
}
|
|
@@ -1190,12 +1628,12 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1190
1628
|
return true;
|
|
1191
1629
|
}
|
|
1192
1630
|
if (/set\s/.test(this.expression.substring(this.pos, this.pos + 4))) {
|
|
1193
|
-
this.current = this.newToken(Token.SET);
|
|
1631
|
+
this.current = this.newToken(Token.SET, SetIdentifier);
|
|
1194
1632
|
this.pos += 4;
|
|
1195
1633
|
return true;
|
|
1196
1634
|
}
|
|
1197
1635
|
if (/super[\.\(]?/.test(this.expression.substring(this.pos, this.pos + 6))) {
|
|
1198
|
-
this.current = this.newToken(Token.SUPER);
|
|
1636
|
+
this.current = this.newToken(Token.SUPER, SuperIdentifier);
|
|
1199
1637
|
this.pos += 5;
|
|
1200
1638
|
return true;
|
|
1201
1639
|
}
|
|
@@ -1229,14 +1667,28 @@ export class TokenStreamImpl extends TokenStream {
|
|
|
1229
1667
|
}
|
|
1230
1668
|
createError(message) {
|
|
1231
1669
|
let coords = this.getCoordinates();
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1670
|
+
const lastLinePos = this.expression.lastIndexOf('\n', this.pos) + 1;
|
|
1671
|
+
let nextLinePos = this.expression.indexOf('\n', this.pos + 1);
|
|
1672
|
+
if (nextLinePos == -1) {
|
|
1673
|
+
nextLinePos = this.expression.length;
|
|
1674
|
+
}
|
|
1675
|
+
const subStart = Math.max(lastLinePos, this.pos - 25);
|
|
1676
|
+
const subEnd = Math.min(nextLinePos, this.pos + 25, this.expression.length);
|
|
1677
|
+
const errorAt = this.expression.substring(subStart, subEnd);
|
|
1678
|
+
const indictor = new Array(subEnd - subStart).fill(' ');
|
|
1679
|
+
indictor[this.pos - subStart] = '^';
|
|
1680
|
+
const errorIndictor = indictor.join('');
|
|
1681
|
+
return `
|
|
1682
|
+
> ${message}
|
|
1683
|
+
> token name: '${this.current?.token?.getName()}' ${this.current?.value ? `parsed: ${this.current.value.toString()}` : ''}
|
|
1684
|
+
> ${coords.line}:${coords.column}\t${errorAt}
|
|
1685
|
+
> ${coords.line}:${coords.column}\t${errorIndictor}
|
|
1686
|
+
`;
|
|
1237
1687
|
}
|
|
1238
1688
|
}
|
|
1239
1689
|
TokenStreamImpl.REGEXP_FLAGS = ['g', 'i', 'm', 's', 'u', 'y'];
|
|
1240
1690
|
TokenStreamImpl.UnicodePattern = /^[0-9a-f]{4}$/i;
|
|
1241
1691
|
TokenStreamImpl.DecimalPattern = /^[0-9a-f]{2}$/i;
|
|
1692
|
+
TokenStreamImpl.AsciiPattern = /^[0-7]{1,3}$/i;
|
|
1693
|
+
TokenStreamImpl.OctalPattern = /^[0-7]+$/i;
|
|
1242
1694
|
//# sourceMappingURL=stream.js.map
|