xbintsc 0.2.9 → 0.3.3
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/README.md +17 -2
- package/README.zh-CN.md +16 -2
- package/bin/xbintsc.js +49 -10
- package/dist/src/ast/expressions.d.ts +2 -0
- package/dist/src/binder/binder.d.ts +24 -98
- package/dist/src/binder/binder.js +13 -559
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/binder/declarations.d.ts +16 -0
- package/dist/src/binder/declarations.js +168 -0
- package/dist/src/binder/declarations.js.map +1 -0
- package/dist/src/binder/helpers.d.ts +11 -0
- package/dist/src/binder/helpers.js +46 -0
- package/dist/src/binder/helpers.js.map +1 -0
- package/dist/src/binder/references.d.ts +21 -0
- package/dist/src/binder/references.js +349 -0
- package/dist/src/binder/references.js.map +1 -0
- package/dist/src/binder/types.d.ts +114 -0
- package/dist/src/binder/types.js +27 -0
- package/dist/src/binder/types.js.map +1 -0
- package/dist/src/cli/main.d.ts +1 -0
- package/dist/src/cli/main.js +40 -0
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls/access.d.ts +13 -0
- package/dist/src/codegen/generator/calls/access.js +115 -0
- package/dist/src/codegen/generator/calls/access.js.map +1 -0
- package/dist/src/codegen/generator/calls/closures.d.ts +11 -0
- package/dist/src/codegen/generator/calls/closures.js +50 -0
- package/dist/src/codegen/generator/calls/closures.js.map +1 -0
- package/dist/src/codegen/generator/calls/invocation.d.ts +18 -0
- package/dist/src/codegen/generator/calls/invocation.js +242 -0
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -0
- package/dist/src/codegen/generator/calls/literals.d.ts +10 -0
- package/dist/src/codegen/generator/calls/literals.js +69 -0
- package/dist/src/codegen/generator/calls/literals.js.map +1 -0
- package/dist/src/codegen/generator/calls/super.d.ts +10 -0
- package/dist/src/codegen/generator/calls/super.js +47 -0
- package/dist/src/codegen/generator/calls/super.js.map +1 -0
- package/dist/src/codegen/generator/calls.d.ts +15 -24
- package/dist/src/codegen/generator/calls.js +15 -482
- package/dist/src/codegen/generator/calls.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +1 -1
- package/dist/src/codegen/generator/context.js +2 -2
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/expressions/assignment.d.ts +13 -0
- package/dist/src/codegen/generator/expressions/assignment.js +203 -0
- package/dist/src/codegen/generator/expressions/assignment.js.map +1 -0
- package/dist/src/codegen/generator/expressions/operators.d.ts +14 -0
- package/dist/src/codegen/generator/expressions/operators.js +163 -0
- package/dist/src/codegen/generator/expressions/operators.js.map +1 -0
- package/dist/src/codegen/generator/expressions/primary.d.ts +17 -0
- package/dist/src/codegen/generator/expressions/primary.js +260 -0
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -0
- package/dist/src/codegen/generator/expressions.d.ts +11 -21
- package/dist/src/codegen/generator/expressions.js +11 -494
- package/dist/src/codegen/generator/expressions.js.map +1 -1
- package/dist/src/codegen/generator/module.js +16 -4
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.js +8 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.d.ts +14 -0
- package/dist/src/codegen/generator/statements/control-flow.js +199 -0
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -0
- package/dist/src/codegen/generator/statements/dispatch.d.ts +12 -0
- package/dist/src/codegen/generator/statements/dispatch.js +100 -0
- package/dist/src/codegen/generator/statements/dispatch.js.map +1 -0
- package/dist/src/codegen/generator/statements/loops.d.ts +13 -0
- package/dist/src/codegen/generator/statements/loops.js +152 -0
- package/dist/src/codegen/generator/statements/loops.js.map +1 -0
- package/dist/src/codegen/generator/statements/variables.d.ts +13 -0
- package/dist/src/codegen/generator/statements/variables.js +146 -0
- package/dist/src/codegen/generator/statements/variables.js.map +1 -0
- package/dist/src/codegen/generator/statements.d.ts +13 -21
- package/dist/src/codegen/generator/statements.js +13 -568
- package/dist/src/codegen/generator/statements.js.map +1 -1
- package/dist/src/codegen/generator/tables.js +7 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/codegen/values.d.ts +17 -17
- package/dist/src/codegen/values.js +21 -57
- package/dist/src/codegen/values.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +1 -0
- package/dist/src/diagnostics/diagnostic.js +1 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/diagnostics/source.d.ts +1 -1
- package/dist/src/diagnostics/source.js +7 -12
- package/dist/src/diagnostics/source.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +4 -0
- package/dist/src/driver/compiler.js +51 -16
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/index.d.ts +5 -2
- package/dist/src/driver/index.js +5 -2
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/paths.d.ts +20 -0
- package/dist/src/driver/paths.js +49 -0
- package/dist/src/driver/paths.js.map +1 -1
- package/dist/src/driver/runtime-lib.d.ts +18 -0
- package/dist/src/driver/runtime-lib.js +31 -0
- package/dist/src/driver/runtime-lib.js.map +1 -0
- package/dist/src/driver/toolchain-download.d.ts +50 -0
- package/dist/src/driver/toolchain-download.js +76 -0
- package/dist/src/driver/toolchain-download.js.map +1 -0
- package/dist/src/driver/toolchain-provider.d.ts +33 -0
- package/dist/src/driver/toolchain-provider.js +71 -0
- package/dist/src/driver/toolchain-provider.js.map +1 -0
- package/dist/src/driver/toolchain.d.ts +9 -4
- package/dist/src/driver/toolchain.js +6 -10
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/extensions/node/child_process/index.d.ts +4 -2
- package/dist/src/extensions/node/child_process/index.js +4 -2
- package/dist/src/extensions/node/child_process/index.js.map +1 -1
- package/dist/src/extensions/node/events/index.d.ts +10 -0
- package/dist/src/extensions/node/events/index.js +22 -0
- package/dist/src/extensions/node/events/index.js.map +1 -0
- package/dist/src/extensions/node/index.js +6 -0
- package/dist/src/extensions/node/index.js.map +1 -1
- package/dist/src/extensions/node/querystring/index.d.ts +10 -0
- package/dist/src/extensions/node/querystring/index.js +25 -0
- package/dist/src/extensions/node/querystring/index.js.map +1 -0
- package/dist/src/extensions/node/util/index.d.ts +11 -0
- package/dist/src/extensions/node/util/index.js +41 -0
- package/dist/src/extensions/node/util/index.js.map +1 -0
- package/dist/src/extensions/registry.d.ts +6 -0
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lexer/scanner/identifiers.d.ts +9 -0
- package/dist/src/lexer/scanner/identifiers.js +33 -0
- package/dist/src/lexer/scanner/identifiers.js.map +1 -0
- package/dist/src/lexer/scanner/numbers.d.ts +10 -0
- package/dist/src/lexer/scanner/numbers.js +89 -0
- package/dist/src/lexer/scanner/numbers.js.map +1 -0
- package/dist/src/lexer/scanner/punctuation.d.ts +9 -0
- package/dist/src/lexer/scanner/punctuation.js +151 -0
- package/dist/src/lexer/scanner/punctuation.js.map +1 -0
- package/dist/src/lexer/scanner/regex.d.ts +11 -0
- package/dist/src/lexer/scanner/regex.js +69 -0
- package/dist/src/lexer/scanner/regex.js.map +1 -0
- package/dist/src/lexer/scanner/strings.d.ts +13 -0
- package/dist/src/lexer/scanner/strings.js +118 -0
- package/dist/src/lexer/scanner/strings.js.map +1 -0
- package/dist/src/lexer/scanner.d.ts +20 -27
- package/dist/src/lexer/scanner.js +11 -415
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/parser/declarations/classes.d.ts +14 -0
- package/dist/src/parser/declarations/classes.js +191 -0
- package/dist/src/parser/declarations/classes.js.map +1 -0
- package/dist/src/parser/declarations/functions.d.ts +17 -0
- package/dist/src/parser/declarations/functions.js +241 -0
- package/dist/src/parser/declarations/functions.js.map +1 -0
- package/dist/src/parser/declarations/type-members.d.ts +16 -0
- package/dist/src/parser/declarations/type-members.js +156 -0
- package/dist/src/parser/declarations/type-members.js.map +1 -0
- package/dist/src/parser/declarations.d.ts +13 -24
- package/dist/src/parser/declarations.js +13 -571
- package/dist/src/parser/declarations.js.map +1 -1
- package/dist/src/parser/helpers.js +13 -4
- package/dist/src/parser/helpers.js.map +1 -1
- package/dist/src/parser/literals.js +10 -1
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +24 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/driver/compiler.test.js +3 -0
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/driver/paths.test.d.ts +1 -0
- package/dist/tests/driver/paths.test.js +26 -0
- package/dist/tests/driver/paths.test.js.map +1 -0
- package/dist/tests/driver/toolchain-download.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-download.test.js +38 -0
- package/dist/tests/driver/toolchain-download.test.js.map +1 -0
- package/dist/tests/driver/toolchain-provider.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-provider.test.js +37 -0
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -0
- package/dist/tests/e2e/compile-node.test.d.ts +7 -0
- package/dist/tests/e2e/compile-node.test.js +123 -0
- package/dist/tests/e2e/compile-node.test.js.map +1 -0
- package/dist/tests/e2e/compile.test.d.ts +4 -1
- package/dist/tests/e2e/compile.test.js +78 -130
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/dist/tests/e2e/harness.d.ts +36 -0
- package/dist/tests/e2e/harness.js +64 -0
- package/dist/tests/e2e/harness.js.map +1 -0
- package/dist/tests/e2e/node-modules.test.js +60 -0
- package/dist/tests/e2e/node-modules.test.js.map +1 -1
- package/dist/tests/extensions/registry.test.js +4 -0
- package/dist/tests/extensions/registry.test.js.map +1 -1
- package/package.json +5 -3
- package/runtime/ext_node/buffer/buffer.c +12 -552
- package/runtime/ext_node/buffer/parts/byte-access.inc +35 -0
- package/runtime/ext_node/buffer/parts/construction.inc +60 -0
- package/runtime/ext_node/buffer/parts/integer-io.inc +119 -0
- package/runtime/ext_node/buffer/parts/methods.inc +135 -0
- package/runtime/ext_node/buffer/parts/prototype.inc +54 -0
- package/runtime/ext_node/buffer/parts/search.inc +86 -0
- package/runtime/ext_node/buffer/parts/static-api.inc +58 -0
- package/runtime/ext_node/child_process/child_process.c +37 -3
- package/runtime/ext_node/events/events.c +285 -0
- package/runtime/ext_node/http/http.c +11 -736
- package/runtime/ext_node/http/parts/client.inc +290 -0
- package/runtime/ext_node/http/parts/helpers.inc +45 -0
- package/runtime/ext_node/http/parts/prototypes.inc +57 -0
- package/runtime/ext_node/http/parts/response.inc +149 -0
- package/runtime/ext_node/http/parts/server.inc +133 -0
- package/runtime/ext_node/http/parts/string-builder.inc +58 -0
- package/runtime/ext_node/net/net.c +12 -504
- package/runtime/ext_node/net/parts/construction.inc +22 -0
- package/runtime/ext_node/net/parts/platform.inc +60 -0
- package/runtime/ext_node/net/parts/prototypes.inc +35 -0
- package/runtime/ext_node/net/parts/read-loop.inc +58 -0
- package/runtime/ext_node/net/parts/server.inc +131 -0
- package/runtime/ext_node/net/parts/socket-methods.inc +100 -0
- package/runtime/ext_node/net/parts/static-api.inc +93 -0
- package/runtime/ext_node/querystring/querystring.c +251 -0
- package/runtime/ext_node/util/util.c +456 -0
- package/runtime/rt.h +8 -2
- package/runtime/rt_internal.h +34 -0
- package/runtime/xt_bigint/arithmetic.inc +135 -0
- package/runtime/xt_bigint/bits.inc +98 -0
- package/runtime/xt_bigint/bitwise.inc +103 -0
- package/runtime/xt_bigint/compare.inc +30 -0
- package/runtime/xt_bigint/conversions.inc +51 -0
- package/runtime/xt_bigint/division.inc +85 -0
- package/runtime/xt_bigint/format.inc +145 -0
- package/runtime/xt_bigint/helpers.inc +92 -0
- package/runtime/xt_bigint/magnitude.inc +88 -0
- package/runtime/xt_bigint/public.inc +59 -0
- package/runtime/xt_bigint/small-arithmetic.inc +58 -0
- package/runtime/xt_bigint.c +42 -0
- package/runtime/xt_builtins.c +1 -0
- package/runtime/xt_io.c +7 -0
- package/runtime/xt_stdlib/arrays.inc +161 -0
- package/runtime/xt_stdlib/dispatch.inc +116 -0
- package/runtime/xt_stdlib/helpers.inc +23 -0
- package/runtime/xt_stdlib/math.inc +72 -0
- package/runtime/xt_stdlib/strings.inc +178 -0
- package/runtime/xt_stdlib.c +10 -549
- package/runtime/xt_stdlib2/array-statics.inc +37 -0
- package/runtime/xt_stdlib2/arrays.inc +189 -0
- package/runtime/xt_stdlib2/container.inc +23 -0
- package/runtime/xt_stdlib2/date.inc +72 -0
- package/runtime/xt_stdlib2/error.inc +22 -0
- package/runtime/xt_stdlib2/helpers.inc +43 -0
- package/runtime/xt_stdlib2/json.inc +213 -0
- package/runtime/xt_stdlib2/map.inc +95 -0
- package/runtime/xt_stdlib2/number-string-statics.inc +73 -0
- package/runtime/xt_stdlib2/numbers.inc +38 -0
- package/runtime/xt_stdlib2/objects.inc +41 -0
- package/runtime/xt_stdlib2/regexp-match.inc +204 -0
- package/runtime/xt_stdlib2/regexp.inc +20 -0
- package/runtime/xt_stdlib2/set.inc +105 -0
- package/runtime/xt_stdlib2/strings.inc +94 -0
- package/runtime/xt_stdlib2.c +19 -1278
- package/runtime/xt_values.c +155 -12
- package/scripts/build-runtime.ts +109 -0
- package/scripts/fetch-toolchain.ts +101 -0
- package/scripts/package-release.ts +192 -0
- package/src/ast/expressions.ts +2 -0
- package/src/binder/binder.ts +40 -725
- package/src/binder/declarations.ts +203 -0
- package/src/binder/helpers.ts +47 -0
- package/src/binder/references.ts +410 -0
- package/src/binder/types.ts +134 -0
- package/src/cli/main.ts +43 -0
- package/src/codegen/generator/calls/access.ts +139 -0
- package/src/codegen/generator/calls/closures.ts +60 -0
- package/src/codegen/generator/calls/invocation.ts +282 -0
- package/src/codegen/generator/calls/literals.ts +77 -0
- package/src/codegen/generator/calls/super.ts +61 -0
- package/src/codegen/generator/calls.ts +30 -552
- package/src/codegen/generator/context.ts +2 -2
- package/src/codegen/generator/expressions/assignment.ts +226 -0
- package/src/codegen/generator/expressions/operators.ts +182 -0
- package/src/codegen/generator/expressions/primary.ts +304 -0
- package/src/codegen/generator/expressions.ts +22 -553
- package/src/codegen/generator/module.ts +14 -4
- package/src/codegen/generator/state.ts +8 -0
- package/src/codegen/generator/statements/control-flow.ts +225 -0
- package/src/codegen/generator/statements/dispatch.ts +122 -0
- package/src/codegen/generator/statements/loops.ts +173 -0
- package/src/codegen/generator/statements/variables.ts +152 -0
- package/src/codegen/generator/statements.ts +26 -612
- package/src/codegen/generator/tables.ts +7 -0
- package/src/codegen/values.ts +22 -57
- package/src/diagnostics/diagnostic.ts +1 -0
- package/src/diagnostics/source.ts +7 -12
- package/src/driver/compiler.ts +61 -18
- package/src/driver/index.ts +17 -2
- package/src/driver/paths.ts +54 -0
- package/src/driver/runtime-lib.ts +32 -0
- package/src/driver/toolchain-download.ts +108 -0
- package/src/driver/toolchain-provider.ts +91 -0
- package/src/driver/toolchain.ts +29 -11
- package/src/extensions/node/child_process/index.ts +4 -2
- package/src/extensions/node/events/index.ts +27 -0
- package/src/extensions/node/index.ts +6 -0
- package/src/extensions/node/querystring/index.ts +29 -0
- package/src/extensions/node/util/index.ts +48 -0
- package/src/extensions/registry.ts +6 -0
- package/src/index.ts +1 -0
- package/src/lexer/scanner/identifiers.ts +37 -0
- package/src/lexer/scanner/numbers.ts +84 -0
- package/src/lexer/scanner/punctuation.ts +132 -0
- package/src/lexer/scanner/regex.ts +79 -0
- package/src/lexer/scanner/strings.ts +128 -0
- package/src/lexer/scanner.ts +35 -401
- package/src/parser/declarations/classes.ts +215 -0
- package/src/parser/declarations/functions.ts +254 -0
- package/src/parser/declarations/type-members.ts +181 -0
- package/src/parser/declarations.ts +32 -609
- package/src/parser/helpers.ts +13 -6
- package/src/parser/literals.ts +10 -1
- package/scripts/build-runtime.mjs +0 -55
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String and template literal scanning, including escape sequences and the
|
|
3
|
+
* template continuation protocol used by the parser.
|
|
4
|
+
*/
|
|
5
|
+
import { DiagnosticCode } from "../../diagnostics/diagnostic.js";
|
|
6
|
+
import { TokenKind } from "../token.js";
|
|
7
|
+
import { Char, isDigit, isLineBreak } from "../char.js";
|
|
8
|
+
export const stringMethods = {
|
|
9
|
+
scanString(start, precededByLineBreak, quote) {
|
|
10
|
+
this.pos++;
|
|
11
|
+
let result = "";
|
|
12
|
+
while (this.pos < this.text.length) {
|
|
13
|
+
const ch = this.text.charCodeAt(this.pos);
|
|
14
|
+
if (ch === quote) {
|
|
15
|
+
this.pos++;
|
|
16
|
+
return this.makeToken(TokenKind.StringLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
17
|
+
}
|
|
18
|
+
if (ch === Char.Backslash) {
|
|
19
|
+
result += this.scanEscapeSequence();
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (isLineBreak(ch)) {
|
|
23
|
+
this.error(DiagnosticCode.UnterminatedString, "Unterminated string literal", start);
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
result += this.text[this.pos];
|
|
27
|
+
this.pos++;
|
|
28
|
+
}
|
|
29
|
+
this.error(DiagnosticCode.UnterminatedString, "Unterminated string literal", start);
|
|
30
|
+
return this.makeToken(TokenKind.StringLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
31
|
+
},
|
|
32
|
+
scanEscapeSequence() {
|
|
33
|
+
this.pos++; // backslash
|
|
34
|
+
const ch = this.text.charCodeAt(this.pos);
|
|
35
|
+
switch (ch) {
|
|
36
|
+
case Char.LowerN:
|
|
37
|
+
this.pos++;
|
|
38
|
+
return "\n";
|
|
39
|
+
case Char.LowerT:
|
|
40
|
+
this.pos++;
|
|
41
|
+
return "\t";
|
|
42
|
+
case Char.LowerR:
|
|
43
|
+
this.pos++;
|
|
44
|
+
return "\r";
|
|
45
|
+
case Char.LowerB:
|
|
46
|
+
this.pos++;
|
|
47
|
+
return "\b";
|
|
48
|
+
case Char.LowerF:
|
|
49
|
+
this.pos++;
|
|
50
|
+
return "\f";
|
|
51
|
+
case Char.LowerU:
|
|
52
|
+
this.pos++;
|
|
53
|
+
if (this.text.charCodeAt(this.pos) === Char.OpenBrace) {
|
|
54
|
+
const close = this.text.indexOf("}", this.pos);
|
|
55
|
+
const hex = this.text.slice(this.pos + 1, close);
|
|
56
|
+
this.pos = close + 1;
|
|
57
|
+
return String.fromCodePoint(parseInt(hex, 16) || 0);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const hex = this.text.slice(this.pos, this.pos + 4);
|
|
61
|
+
this.pos += 4;
|
|
62
|
+
return String.fromCharCode(parseInt(hex, 16) || 0);
|
|
63
|
+
}
|
|
64
|
+
case Char.LowerX: {
|
|
65
|
+
const hex = this.text.slice(this.pos + 1, this.pos + 3);
|
|
66
|
+
this.pos += 3;
|
|
67
|
+
return String.fromCharCode(parseInt(hex, 16) || 0);
|
|
68
|
+
}
|
|
69
|
+
case Char.Zero:
|
|
70
|
+
// \0 is only a null escape when not followed by a digit.
|
|
71
|
+
if (!isDigit(this.text.charCodeAt(this.pos + 1))) {
|
|
72
|
+
this.pos++;
|
|
73
|
+
return "\0";
|
|
74
|
+
}
|
|
75
|
+
this.pos++;
|
|
76
|
+
return "\0";
|
|
77
|
+
default:
|
|
78
|
+
this.pos++;
|
|
79
|
+
return this.text[this.pos - 1] ?? "";
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
/** Scans a template literal chunk starting at a backtick or after `}`. */
|
|
83
|
+
scanTemplate(start, precededByLineBreak, isHead) {
|
|
84
|
+
if (isHead)
|
|
85
|
+
this.pos++; // opening backtick
|
|
86
|
+
let result = "";
|
|
87
|
+
for (;;) {
|
|
88
|
+
if (this.pos >= this.text.length) {
|
|
89
|
+
this.error(DiagnosticCode.UnterminatedTemplate, "Unterminated template literal", start);
|
|
90
|
+
return this.makeToken(TokenKind.NoSubstitutionTemplateLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
91
|
+
}
|
|
92
|
+
const ch = this.text.charCodeAt(this.pos);
|
|
93
|
+
if (ch === Char.Backtick) {
|
|
94
|
+
this.pos++;
|
|
95
|
+
return this.makeToken(TokenKind.NoSubstitutionTemplateLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
96
|
+
}
|
|
97
|
+
if (ch === Char.Dollar && this.text.charCodeAt(this.pos + 1) === Char.OpenBrace) {
|
|
98
|
+
this.pos += 2;
|
|
99
|
+
return this.makeToken(TokenKind.TemplateHead, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
100
|
+
}
|
|
101
|
+
if (ch === Char.Backslash) {
|
|
102
|
+
result += this.scanEscapeSequence();
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
result += this.text[this.pos];
|
|
106
|
+
this.pos++;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
/** Called by the parser after a template substitution expression. */
|
|
110
|
+
continueTemplate(offset) {
|
|
111
|
+
// `offset` points at the `}` that closes the substitution; skip it so the
|
|
112
|
+
// following characters are scanned as template text.
|
|
113
|
+
this.pos = Math.max(0, Math.min(offset + 1, this.text.length));
|
|
114
|
+
this._token = this.scanTemplate(this.pos, false, /* isHead */ false);
|
|
115
|
+
return this._token;
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../../../../src/lexer/scanner/strings.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import { DiagnosticBag } from "../diagnostics/diagnostic.js";
|
|
1
|
+
import { DiagnosticBag, DiagnosticCode } from "../diagnostics/diagnostic.js";
|
|
2
2
|
import type { SourceFile } from "../diagnostics/source.js";
|
|
3
|
-
import { Token } from "./token.js";
|
|
3
|
+
import { Token, TokenKind } from "./token.js";
|
|
4
|
+
import { type IdentifierMethods } from "./scanner/identifiers.js";
|
|
5
|
+
import { type NumberMethods } from "./scanner/numbers.js";
|
|
6
|
+
import { type StringMethods } from "./scanner/strings.js";
|
|
7
|
+
import { type RegexMethods } from "./scanner/regex.js";
|
|
8
|
+
import { type PunctuationMethods } from "./scanner/punctuation.js";
|
|
4
9
|
/**
|
|
5
10
|
* Hand-written scanner for the TypeScript language. It produces a flat token
|
|
6
11
|
* stream consumed by the parser. Comments and trivia are skipped, but line
|
|
7
12
|
* breaks are tracked so the parser can implement ASI (automatic semicolon
|
|
8
13
|
* insertion) correctly.
|
|
14
|
+
*
|
|
15
|
+
* The scanning routines are split by token category under `scanner/` and
|
|
16
|
+
* merged onto the prototype below so each group can share the scanner state.
|
|
9
17
|
*/
|
|
10
18
|
export declare class Scanner {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
text: string;
|
|
20
|
+
pos: number;
|
|
21
|
+
readonly diagnostics: DiagnosticBag;
|
|
22
|
+
readonly source: SourceFile;
|
|
23
|
+
_token: Token;
|
|
16
24
|
constructor(source: SourceFile, diagnostics: DiagnosticBag);
|
|
17
25
|
get token(): Token;
|
|
18
26
|
get position(): number;
|
|
@@ -25,24 +33,9 @@ export declare class Scanner {
|
|
|
25
33
|
nextToken(): Token;
|
|
26
34
|
/** Scan everything, useful for lexer tests. */
|
|
27
35
|
tokenize(): Token[];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
private finishNumber;
|
|
34
|
-
private scanString;
|
|
35
|
-
private scanEscapeSequence;
|
|
36
|
-
/** Scans a template literal chunk starting at a backtick or after `}`. */
|
|
37
|
-
scanTemplate(start: number, precededByLineBreak: boolean, isHead: boolean): Token;
|
|
38
|
-
/** Called by the parser after a template substitution expression. */
|
|
39
|
-
continueTemplate(offset: number): Token;
|
|
40
|
-
/**
|
|
41
|
-
* True when a `/` in this position starts a regular expression rather than a
|
|
42
|
-
* division. The decision is made from the previous significant token.
|
|
43
|
-
*/
|
|
44
|
-
private regexAllowed;
|
|
45
|
-
/** Scan a `/pattern/flags` literal, starting at the leading slash. */
|
|
46
|
-
private scanRegex;
|
|
47
|
-
private scanPunctuation;
|
|
36
|
+
error(code: DiagnosticCode, message: string, start: number, end?: number): void;
|
|
37
|
+
scan(): Token;
|
|
38
|
+
makeToken(kind: TokenKind, start: number, end: number, text: string, precededByLineBreak: boolean, value?: string | number | bigint): Token;
|
|
39
|
+
}
|
|
40
|
+
export interface Scanner extends IdentifierMethods, NumberMethods, StringMethods, RegexMethods, PunctuationMethods {
|
|
48
41
|
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { DiagnosticCode } from "../diagnostics/diagnostic.js";
|
|
2
|
-
import {
|
|
3
|
-
import { Char, isDigit,
|
|
2
|
+
import { TokenKind } from "./token.js";
|
|
3
|
+
import { Char, isDigit, isIdentifierStart, isLineBreak, isWhiteSpace } from "./char.js";
|
|
4
|
+
import { identifierMethods } from "./scanner/identifiers.js";
|
|
5
|
+
import { numberMethods } from "./scanner/numbers.js";
|
|
6
|
+
import { stringMethods } from "./scanner/strings.js";
|
|
7
|
+
import { regexMethods } from "./scanner/regex.js";
|
|
8
|
+
import { punctuationMethods } from "./scanner/punctuation.js";
|
|
4
9
|
/**
|
|
5
10
|
* Hand-written scanner for the TypeScript language. It produces a flat token
|
|
6
11
|
* stream consumed by the parser. Comments and trivia are skipped, but line
|
|
7
12
|
* breaks are tracked so the parser can implement ASI (automatic semicolon
|
|
8
13
|
* insertion) correctly.
|
|
14
|
+
*
|
|
15
|
+
* The scanning routines are split by token category under `scanner/` and
|
|
16
|
+
* merged onto the prototype below so each group can share the scanner state.
|
|
9
17
|
*/
|
|
10
18
|
export class Scanner {
|
|
11
19
|
text;
|
|
@@ -137,418 +145,6 @@ export class Scanner {
|
|
|
137
145
|
makeToken(kind, start, end, text, precededByLineBreak, value) {
|
|
138
146
|
return { kind, start, end, text, value, precededByLineBreak };
|
|
139
147
|
}
|
|
140
|
-
scanIdentifier(start, precededByLineBreak) {
|
|
141
|
-
this.pos++;
|
|
142
|
-
while (this.pos < this.text.length) {
|
|
143
|
-
const ch = this.text.charCodeAt(this.pos);
|
|
144
|
-
if (isIdentifierPart(ch)) {
|
|
145
|
-
this.pos++;
|
|
146
|
-
}
|
|
147
|
-
else if (ch === Char.Backslash && this.text.charCodeAt(this.pos + 1) === Char.LowerU) {
|
|
148
|
-
this.pos += 2;
|
|
149
|
-
const hex = this.text.slice(this.pos, this.pos + 4);
|
|
150
|
-
this.pos += 4;
|
|
151
|
-
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
152
|
-
this.error(DiagnosticCode.InvalidEscape, "Invalid unicode escape in identifier", this.pos - 4, this.pos);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const text = this.text.slice(start, this.pos);
|
|
160
|
-
const keyword = KEYWORDS.get(text);
|
|
161
|
-
const kind = keyword ?? TokenKind.Identifier;
|
|
162
|
-
return this.makeToken(kind, start, this.pos, text, precededByLineBreak);
|
|
163
|
-
}
|
|
164
|
-
scanNumber(start, precededByLineBreak) {
|
|
165
|
-
const text = this.text;
|
|
166
|
-
let isBigInt = false;
|
|
167
|
-
// Radix prefixes.
|
|
168
|
-
if (text.charCodeAt(this.pos) === Char.Zero) {
|
|
169
|
-
const next = text.charCodeAt(this.pos + 1);
|
|
170
|
-
if (next === Char.LowerX || next === Char.UpperX) {
|
|
171
|
-
this.pos += 2;
|
|
172
|
-
while (isHexDigit(text.charCodeAt(this.pos)) || text.charCodeAt(this.pos) === Char.Underscore)
|
|
173
|
-
this.pos++;
|
|
174
|
-
isBigInt = text.charCodeAt(this.pos) === Char.LowerN;
|
|
175
|
-
if (isBigInt)
|
|
176
|
-
this.pos++;
|
|
177
|
-
return this.finishNumber(start, precededByLineBreak, isBigInt);
|
|
178
|
-
}
|
|
179
|
-
if (next === Char.LowerO || next === Char.UpperO || next === Char.LowerB || next === Char.UpperB) {
|
|
180
|
-
this.pos += 2;
|
|
181
|
-
while (isDigit(text.charCodeAt(this.pos)) || text.charCodeAt(this.pos) === Char.Underscore)
|
|
182
|
-
this.pos++;
|
|
183
|
-
isBigInt = text.charCodeAt(this.pos) === Char.LowerN;
|
|
184
|
-
if (isBigInt)
|
|
185
|
-
this.pos++;
|
|
186
|
-
return this.finishNumber(start, precededByLineBreak, isBigInt);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
while (isDigit(text.charCodeAt(this.pos)) || text.charCodeAt(this.pos) === Char.Underscore)
|
|
190
|
-
this.pos++;
|
|
191
|
-
if (text.charCodeAt(this.pos) === Char.Dot) {
|
|
192
|
-
this.pos++;
|
|
193
|
-
while (isDigit(text.charCodeAt(this.pos)) || text.charCodeAt(this.pos) === Char.Underscore)
|
|
194
|
-
this.pos++;
|
|
195
|
-
}
|
|
196
|
-
const e = text.charCodeAt(this.pos);
|
|
197
|
-
if (e === Char.LowerE || e === Char.UpperE) {
|
|
198
|
-
const save = this.pos;
|
|
199
|
-
this.pos++;
|
|
200
|
-
const sign = text.charCodeAt(this.pos);
|
|
201
|
-
if (sign === Char.Plus || sign === Char.Minus)
|
|
202
|
-
this.pos++;
|
|
203
|
-
if (isDigit(text.charCodeAt(this.pos))) {
|
|
204
|
-
while (isDigit(text.charCodeAt(this.pos)) || text.charCodeAt(this.pos) === Char.Underscore)
|
|
205
|
-
this.pos++;
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
// Not an exponent, roll back.
|
|
209
|
-
this.pos = save;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
isBigInt = text.charCodeAt(this.pos) === Char.LowerN;
|
|
213
|
-
if (isBigInt)
|
|
214
|
-
this.pos++;
|
|
215
|
-
return this.finishNumber(start, precededByLineBreak, isBigInt);
|
|
216
|
-
}
|
|
217
|
-
finishNumber(start, precededByLineBreak, isBigInt) {
|
|
218
|
-
let raw = this.text.slice(start, this.pos);
|
|
219
|
-
const cleaned = raw.replace(/_/g, "");
|
|
220
|
-
if (isBigInt) {
|
|
221
|
-
raw = raw.slice(0, -1).replace(/_/g, "");
|
|
222
|
-
const parsed = Number(raw);
|
|
223
|
-
if (parsed !== parsed) {
|
|
224
|
-
this.error(DiagnosticCode.InvalidNumber, `Invalid BigInt literal '${raw}'`, start, this.pos);
|
|
225
|
-
return this.makeToken(TokenKind.BigIntLiteral, start, this.pos, raw, precededByLineBreak, 0);
|
|
226
|
-
}
|
|
227
|
-
return this.makeToken(TokenKind.BigIntLiteral, start, this.pos, raw, precededByLineBreak, parsed);
|
|
228
|
-
}
|
|
229
|
-
let value;
|
|
230
|
-
if (/^0[xX]/.test(cleaned))
|
|
231
|
-
value = parseInt(cleaned.slice(2), 16);
|
|
232
|
-
else if (/^0[oO]/.test(cleaned))
|
|
233
|
-
value = parseInt(cleaned.slice(2), 8);
|
|
234
|
-
else if (/^0[bB]/.test(cleaned))
|
|
235
|
-
value = parseInt(cleaned.slice(2), 2);
|
|
236
|
-
else
|
|
237
|
-
value = Number(cleaned);
|
|
238
|
-
if (Number.isNaN(value)) {
|
|
239
|
-
this.error(DiagnosticCode.InvalidNumber, `Invalid numeric literal '${raw}'`, start, this.pos);
|
|
240
|
-
value = 0;
|
|
241
|
-
}
|
|
242
|
-
return this.makeToken(TokenKind.NumericLiteral, start, this.pos, raw, precededByLineBreak, value);
|
|
243
|
-
}
|
|
244
|
-
scanString(start, precededByLineBreak, quote) {
|
|
245
|
-
this.pos++;
|
|
246
|
-
let result = "";
|
|
247
|
-
while (this.pos < this.text.length) {
|
|
248
|
-
const ch = this.text.charCodeAt(this.pos);
|
|
249
|
-
if (ch === quote) {
|
|
250
|
-
this.pos++;
|
|
251
|
-
return this.makeToken(TokenKind.StringLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
252
|
-
}
|
|
253
|
-
if (ch === Char.Backslash) {
|
|
254
|
-
result += this.scanEscapeSequence();
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
|
-
if (isLineBreak(ch)) {
|
|
258
|
-
this.error(DiagnosticCode.UnterminatedString, "Unterminated string literal", start);
|
|
259
|
-
break;
|
|
260
|
-
}
|
|
261
|
-
result += this.text[this.pos];
|
|
262
|
-
this.pos++;
|
|
263
|
-
}
|
|
264
|
-
this.error(DiagnosticCode.UnterminatedString, "Unterminated string literal", start);
|
|
265
|
-
return this.makeToken(TokenKind.StringLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
266
|
-
}
|
|
267
|
-
scanEscapeSequence() {
|
|
268
|
-
this.pos++; // backslash
|
|
269
|
-
const ch = this.text.charCodeAt(this.pos);
|
|
270
|
-
switch (ch) {
|
|
271
|
-
case Char.LowerN:
|
|
272
|
-
this.pos++;
|
|
273
|
-
return "\n";
|
|
274
|
-
case Char.LowerT:
|
|
275
|
-
this.pos++;
|
|
276
|
-
return "\t";
|
|
277
|
-
case Char.LowerR:
|
|
278
|
-
this.pos++;
|
|
279
|
-
return "\r";
|
|
280
|
-
case Char.LowerB:
|
|
281
|
-
this.pos++;
|
|
282
|
-
return "\b";
|
|
283
|
-
case Char.LowerF:
|
|
284
|
-
this.pos++;
|
|
285
|
-
return "\f";
|
|
286
|
-
case Char.LowerU:
|
|
287
|
-
this.pos++;
|
|
288
|
-
if (this.text.charCodeAt(this.pos) === Char.OpenBrace) {
|
|
289
|
-
const close = this.text.indexOf("}", this.pos);
|
|
290
|
-
const hex = this.text.slice(this.pos + 1, close);
|
|
291
|
-
this.pos = close + 1;
|
|
292
|
-
return String.fromCodePoint(parseInt(hex, 16) || 0);
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
const hex = this.text.slice(this.pos, this.pos + 4);
|
|
296
|
-
this.pos += 4;
|
|
297
|
-
return String.fromCharCode(parseInt(hex, 16) || 0);
|
|
298
|
-
}
|
|
299
|
-
case Char.LowerX: {
|
|
300
|
-
const hex = this.text.slice(this.pos + 1, this.pos + 3);
|
|
301
|
-
this.pos += 3;
|
|
302
|
-
return String.fromCharCode(parseInt(hex, 16) || 0);
|
|
303
|
-
}
|
|
304
|
-
case Char.Zero:
|
|
305
|
-
// \0 is only a null escape when not followed by a digit.
|
|
306
|
-
if (!isDigit(this.text.charCodeAt(this.pos + 1))) {
|
|
307
|
-
this.pos++;
|
|
308
|
-
return "\0";
|
|
309
|
-
}
|
|
310
|
-
this.pos++;
|
|
311
|
-
return "\0";
|
|
312
|
-
default:
|
|
313
|
-
this.pos++;
|
|
314
|
-
return this.text[this.pos - 1] ?? "";
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/** Scans a template literal chunk starting at a backtick or after `}`. */
|
|
318
|
-
scanTemplate(start, precededByLineBreak, isHead) {
|
|
319
|
-
if (isHead)
|
|
320
|
-
this.pos++; // opening backtick
|
|
321
|
-
let result = "";
|
|
322
|
-
for (;;) {
|
|
323
|
-
if (this.pos >= this.text.length) {
|
|
324
|
-
this.error(DiagnosticCode.UnterminatedTemplate, "Unterminated template literal", start);
|
|
325
|
-
return this.makeToken(TokenKind.NoSubstitutionTemplateLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
326
|
-
}
|
|
327
|
-
const ch = this.text.charCodeAt(this.pos);
|
|
328
|
-
if (ch === Char.Backtick) {
|
|
329
|
-
this.pos++;
|
|
330
|
-
return this.makeToken(TokenKind.NoSubstitutionTemplateLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
331
|
-
}
|
|
332
|
-
if (ch === Char.Dollar && this.text.charCodeAt(this.pos + 1) === Char.OpenBrace) {
|
|
333
|
-
this.pos += 2;
|
|
334
|
-
return this.makeToken(TokenKind.TemplateHead, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak, result);
|
|
335
|
-
}
|
|
336
|
-
if (ch === Char.Backslash) {
|
|
337
|
-
result += this.scanEscapeSequence();
|
|
338
|
-
continue;
|
|
339
|
-
}
|
|
340
|
-
result += this.text[this.pos];
|
|
341
|
-
this.pos++;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
/** Called by the parser after a template substitution expression. */
|
|
345
|
-
continueTemplate(offset) {
|
|
346
|
-
// `offset` points at the `}` that closes the substitution; skip it so the
|
|
347
|
-
// following characters are scanned as template text.
|
|
348
|
-
this.pos = Math.max(0, Math.min(offset + 1, this.text.length));
|
|
349
|
-
this._token = this.scanTemplate(this.pos, false, /* isHead */ false);
|
|
350
|
-
return this._token;
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* True when a `/` in this position starts a regular expression rather than a
|
|
354
|
-
* division. The decision is made from the previous significant token.
|
|
355
|
-
*/
|
|
356
|
-
regexAllowed() {
|
|
357
|
-
switch (this._token.kind) {
|
|
358
|
-
case TokenKind.Identifier:
|
|
359
|
-
case TokenKind.PrivateIdentifier:
|
|
360
|
-
case TokenKind.NumericLiteral:
|
|
361
|
-
case TokenKind.BigIntLiteral:
|
|
362
|
-
case TokenKind.StringLiteral:
|
|
363
|
-
case TokenKind.NoSubstitutionTemplateLiteral:
|
|
364
|
-
case TokenKind.TemplateTail:
|
|
365
|
-
case TokenKind.RegularExpressionLiteral:
|
|
366
|
-
case TokenKind.CloseParen:
|
|
367
|
-
case TokenKind.CloseBracket:
|
|
368
|
-
case TokenKind.TrueKeyword:
|
|
369
|
-
case TokenKind.FalseKeyword:
|
|
370
|
-
case TokenKind.NullKeyword:
|
|
371
|
-
case TokenKind.UndefinedKeyword:
|
|
372
|
-
case TokenKind.ThisKeyword:
|
|
373
|
-
case TokenKind.PlusPlus:
|
|
374
|
-
case TokenKind.MinusMinus:
|
|
375
|
-
return false;
|
|
376
|
-
default:
|
|
377
|
-
return true;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
/** Scan a `/pattern/flags` literal, starting at the leading slash. */
|
|
381
|
-
scanRegex(start, precededByLineBreak) {
|
|
382
|
-
this.pos++; // opening slash
|
|
383
|
-
let inClass = false;
|
|
384
|
-
for (;;) {
|
|
385
|
-
if (this.pos >= this.text.length) {
|
|
386
|
-
this.error(DiagnosticCode.InvalidCharacter, "Unterminated regular expression", start);
|
|
387
|
-
break;
|
|
388
|
-
}
|
|
389
|
-
const ch = this.text.charCodeAt(this.pos);
|
|
390
|
-
if (ch === Char.Backslash) {
|
|
391
|
-
this.pos += 2;
|
|
392
|
-
continue;
|
|
393
|
-
}
|
|
394
|
-
if (ch === Char.LineFeed || ch === Char.CarriageReturn)
|
|
395
|
-
break;
|
|
396
|
-
if (ch === 91 /* [ */)
|
|
397
|
-
inClass = true;
|
|
398
|
-
else if (ch === 93 /* ] */)
|
|
399
|
-
inClass = false;
|
|
400
|
-
else if (ch === Char.Slash && !inClass) {
|
|
401
|
-
this.pos++;
|
|
402
|
-
break;
|
|
403
|
-
}
|
|
404
|
-
this.pos++;
|
|
405
|
-
}
|
|
406
|
-
// Flags.
|
|
407
|
-
while (this.pos < this.text.length && isIdentifierPart(this.text.charCodeAt(this.pos)))
|
|
408
|
-
this.pos++;
|
|
409
|
-
return this.makeToken(TokenKind.RegularExpressionLiteral, start, this.pos, this.text.slice(start, this.pos), precededByLineBreak);
|
|
410
|
-
}
|
|
411
|
-
scanPunctuation(start, precededByLineBreak) {
|
|
412
|
-
const text = this.text;
|
|
413
|
-
const ch = text.charCodeAt(this.pos);
|
|
414
|
-
const next = text.charCodeAt(this.pos + 1);
|
|
415
|
-
const third = text.charCodeAt(this.pos + 2);
|
|
416
|
-
const fourth = text.charCodeAt(this.pos + 3);
|
|
417
|
-
const emit = (kind, length) => {
|
|
418
|
-
this.pos += length;
|
|
419
|
-
return this.makeToken(kind, start, this.pos, text.slice(start, this.pos), precededByLineBreak);
|
|
420
|
-
};
|
|
421
|
-
switch (ch) {
|
|
422
|
-
case Char.OpenBrace:
|
|
423
|
-
return emit(TokenKind.OpenBrace, 1);
|
|
424
|
-
case Char.CloseBrace:
|
|
425
|
-
return emit(TokenKind.CloseBrace, 1);
|
|
426
|
-
case Char.OpenParen:
|
|
427
|
-
return emit(TokenKind.OpenParen, 1);
|
|
428
|
-
case Char.CloseParen:
|
|
429
|
-
return emit(TokenKind.CloseParen, 1);
|
|
430
|
-
case Char.OpenBracket:
|
|
431
|
-
return emit(TokenKind.OpenBracket, 1);
|
|
432
|
-
case Char.CloseBracket:
|
|
433
|
-
return emit(TokenKind.CloseBracket, 1);
|
|
434
|
-
case Char.Semicolon:
|
|
435
|
-
return emit(TokenKind.Semicolon, 1);
|
|
436
|
-
case Char.Comma:
|
|
437
|
-
return emit(TokenKind.Comma, 1);
|
|
438
|
-
case Char.At:
|
|
439
|
-
return emit(TokenKind.At, 1);
|
|
440
|
-
case Char.Tilde:
|
|
441
|
-
return emit(TokenKind.Tilde, 1);
|
|
442
|
-
case Char.Colon:
|
|
443
|
-
return emit(TokenKind.Colon, 1);
|
|
444
|
-
case Char.Dot:
|
|
445
|
-
if (next === Char.Dot && third === Char.Dot)
|
|
446
|
-
return emit(TokenKind.DotDotDot, 3);
|
|
447
|
-
return emit(TokenKind.Dot, 1);
|
|
448
|
-
case Char.Question:
|
|
449
|
-
if (next === Char.Question) {
|
|
450
|
-
if (third === Char.Equals)
|
|
451
|
-
return emit(TokenKind.QuestionQuestionEquals, 3);
|
|
452
|
-
return emit(TokenKind.QuestionQuestion, 2);
|
|
453
|
-
}
|
|
454
|
-
if (next === Char.Dot && !isDigit(third))
|
|
455
|
-
return emit(TokenKind.QuestionDot, 2);
|
|
456
|
-
return emit(TokenKind.Question, 1);
|
|
457
|
-
case Char.Equals:
|
|
458
|
-
if (next === Char.Equals && third === Char.Equals)
|
|
459
|
-
return emit(TokenKind.EqualsEqualsEquals, 3);
|
|
460
|
-
if (next === Char.Equals)
|
|
461
|
-
return emit(TokenKind.EqualsEquals, 2);
|
|
462
|
-
if (next === Char.GreaterThan)
|
|
463
|
-
return emit(TokenKind.EqualsGreaterThan, 2);
|
|
464
|
-
return emit(TokenKind.Equals, 1);
|
|
465
|
-
case Char.Exclamation:
|
|
466
|
-
if (next === Char.Equals && third === Char.Equals)
|
|
467
|
-
return emit(TokenKind.ExclamationEqualsEquals, 3);
|
|
468
|
-
if (next === Char.Equals)
|
|
469
|
-
return emit(TokenKind.ExclamationEquals, 2);
|
|
470
|
-
return emit(TokenKind.Exclamation, 1);
|
|
471
|
-
case Char.Plus:
|
|
472
|
-
if (next === Char.Plus)
|
|
473
|
-
return emit(TokenKind.PlusPlus, 2);
|
|
474
|
-
if (next === Char.Equals)
|
|
475
|
-
return emit(TokenKind.PlusEquals, 2);
|
|
476
|
-
return emit(TokenKind.Plus, 1);
|
|
477
|
-
case Char.Minus:
|
|
478
|
-
if (next === Char.Minus)
|
|
479
|
-
return emit(TokenKind.MinusMinus, 2);
|
|
480
|
-
if (next === Char.Equals)
|
|
481
|
-
return emit(TokenKind.MinusEquals, 2);
|
|
482
|
-
return emit(TokenKind.Minus, 1);
|
|
483
|
-
case Char.Asterisk:
|
|
484
|
-
if (next === Char.Asterisk) {
|
|
485
|
-
if (third === Char.Equals)
|
|
486
|
-
return emit(TokenKind.AsteriskAsteriskEquals, 3);
|
|
487
|
-
return emit(TokenKind.AsteriskAsterisk, 2);
|
|
488
|
-
}
|
|
489
|
-
if (next === Char.Equals)
|
|
490
|
-
return emit(TokenKind.AsteriskEquals, 2);
|
|
491
|
-
return emit(TokenKind.Asterisk, 1);
|
|
492
|
-
case Char.Slash:
|
|
493
|
-
if (next === Char.Equals)
|
|
494
|
-
return emit(TokenKind.SlashEquals, 2);
|
|
495
|
-
if (this.regexAllowed())
|
|
496
|
-
return this.scanRegex(start, precededByLineBreak);
|
|
497
|
-
return emit(TokenKind.Slash, 1);
|
|
498
|
-
case Char.Percent:
|
|
499
|
-
if (next === Char.Equals)
|
|
500
|
-
return emit(TokenKind.PercentEquals, 2);
|
|
501
|
-
return emit(TokenKind.Percent, 1);
|
|
502
|
-
case Char.LessThan:
|
|
503
|
-
if (next === Char.LessThan) {
|
|
504
|
-
if (third === Char.Equals)
|
|
505
|
-
return emit(TokenKind.LessThanLessThanEquals, 3);
|
|
506
|
-
return emit(TokenKind.LessThanLessThan, 2);
|
|
507
|
-
}
|
|
508
|
-
if (next === Char.Equals)
|
|
509
|
-
return emit(TokenKind.LessThanEquals, 2);
|
|
510
|
-
return emit(TokenKind.LessThan, 1);
|
|
511
|
-
case Char.GreaterThan:
|
|
512
|
-
if (next === Char.GreaterThan) {
|
|
513
|
-
if (third === Char.GreaterThan) {
|
|
514
|
-
if (fourth === Char.Equals)
|
|
515
|
-
return emit(TokenKind.GreaterThanGreaterThanGreaterThanEquals, 4);
|
|
516
|
-
return emit(TokenKind.GreaterThanGreaterThanGreaterThan, 3);
|
|
517
|
-
}
|
|
518
|
-
if (third === Char.Equals)
|
|
519
|
-
return emit(TokenKind.GreaterThanGreaterThanEquals, 3);
|
|
520
|
-
return emit(TokenKind.GreaterThanGreaterThan, 2);
|
|
521
|
-
}
|
|
522
|
-
if (next === Char.Equals)
|
|
523
|
-
return emit(TokenKind.GreaterThanEquals, 2);
|
|
524
|
-
return emit(TokenKind.GreaterThan, 1);
|
|
525
|
-
case Char.Ampersand:
|
|
526
|
-
if (next === Char.Ampersand) {
|
|
527
|
-
if (third === Char.Equals)
|
|
528
|
-
return emit(TokenKind.AmpersandAmpersandEquals, 3);
|
|
529
|
-
return emit(TokenKind.AmpersandAmpersand, 2);
|
|
530
|
-
}
|
|
531
|
-
if (next === Char.Equals)
|
|
532
|
-
return emit(TokenKind.AmpersandEquals, 2);
|
|
533
|
-
return emit(TokenKind.Ampersand, 1);
|
|
534
|
-
case Char.Bar:
|
|
535
|
-
if (next === Char.Bar) {
|
|
536
|
-
if (third === Char.Equals)
|
|
537
|
-
return emit(TokenKind.BarBarEquals, 3);
|
|
538
|
-
return emit(TokenKind.BarBar, 2);
|
|
539
|
-
}
|
|
540
|
-
if (next === Char.Equals)
|
|
541
|
-
return emit(TokenKind.BarEquals, 2);
|
|
542
|
-
return emit(TokenKind.Bar, 1);
|
|
543
|
-
case Char.Caret:
|
|
544
|
-
if (next === Char.Equals)
|
|
545
|
-
return emit(TokenKind.CaretEquals, 2);
|
|
546
|
-
return emit(TokenKind.Caret, 1);
|
|
547
|
-
default:
|
|
548
|
-
this.pos++;
|
|
549
|
-
this.error(DiagnosticCode.InvalidCharacter, `Invalid character '${text[start]}'`, start, this.pos);
|
|
550
|
-
return this.makeToken(TokenKind.Identifier, start, this.pos, text[start] ?? "", precededByLineBreak);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
148
|
}
|
|
149
|
+
Object.assign(Scanner.prototype, identifierMethods, numberMethods, stringMethods, regexMethods, punctuationMethods);
|
|
554
150
|
//# sourceMappingURL=scanner.js.map
|