redscript-mc 3.0.1 → 3.0.2
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/.github/workflows/ci.yml +1 -0
- package/README.md +119 -313
- package/README.zh.md +118 -314
- package/ROADMAP.md +5 -5
- package/dist/data/impl_test/function/counter/get.mcfunction +5 -0
- package/dist/data/impl_test/function/counter/inc.mcfunction +7 -0
- package/dist/data/impl_test/function/counter/new.mcfunction +4 -0
- package/dist/data/impl_test/function/load.mcfunction +1 -0
- package/dist/data/impl_test/function/test_impl.mcfunction +10 -0
- package/dist/data/minecraft/tags/function/load.json +5 -0
- package/dist/data/playground/function/load.mcfunction +1 -0
- package/dist/data/playground/function/start.mcfunction +4 -0
- package/dist/data/playground/function/start__say_macro_t1.mcfunction +1 -0
- package/dist/data/playground/function/stop.mcfunction +5 -0
- package/dist/data/playground/function/stop__say_macro_t0.mcfunction +1 -0
- package/dist/data/stdlib_queue8_test/function/__queue_append_apply.mcfunction +4 -0
- package/dist/data/stdlib_queue8_test/function/__queue_peek_apply.mcfunction +4 -0
- package/dist/data/stdlib_queue8_test/function/__queue_size_raw_apply.mcfunction +4 -0
- package/dist/data/stdlib_queue8_test/function/load.mcfunction +1 -0
- package/dist/data/stdlib_queue8_test/function/queue_clear.mcfunction +6 -0
- package/dist/data/stdlib_queue8_test/function/queue_empty__merge_1.mcfunction +5 -0
- package/dist/data/stdlib_queue8_test/function/queue_empty__then_0.mcfunction +5 -0
- package/dist/data/stdlib_queue8_test/function/queue_peek__merge_1.mcfunction +13 -0
- package/dist/data/stdlib_queue8_test/function/queue_peek__then_0.mcfunction +5 -0
- package/dist/data/stdlib_queue8_test/function/queue_pop__merge_1.mcfunction +15 -0
- package/dist/data/stdlib_queue8_test/function/queue_pop__then_0.mcfunction +5 -0
- package/dist/data/stdlib_queue8_test/function/queue_push__const_11.mcfunction +6 -0
- package/dist/data/stdlib_queue8_test/function/queue_push__const_22.mcfunction +6 -0
- package/dist/data/stdlib_queue8_test/function/queue_size.mcfunction +13 -0
- package/dist/data/stdlib_queue8_test/function/test_queue_push_and_size.mcfunction +13 -0
- package/dist/data/test/function/load.mcfunction +1 -0
- package/dist/data/test/function/say_at.mcfunction +6 -0
- package/dist/data/test/function/test.mcfunction +4 -0
- package/dist/pack.mcmeta +6 -0
- package/dist/package.json +1 -1
- package/dist/src/__tests__/formatter-extra.test.d.ts +7 -0
- package/dist/src/__tests__/formatter-extra.test.js +123 -0
- package/dist/src/__tests__/global-vars.test.d.ts +13 -0
- package/dist/src/__tests__/global-vars.test.js +156 -0
- package/dist/src/__tests__/lint/new-rules.test.d.ts +9 -0
- package/dist/src/__tests__/lint/new-rules.test.js +402 -0
- package/dist/src/__tests__/lsp-rename.test.d.ts +8 -0
- package/dist/src/__tests__/lsp-rename.test.js +157 -0
- package/dist/src/__tests__/mc-integration/say-fstring.test.d.ts +11 -0
- package/dist/src/__tests__/mc-integration/say-fstring.test.js +220 -0
- package/dist/src/__tests__/mc-integration/stdlib-coverage-2.test.js +1 -1
- package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.js +1 -1
- package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.js +1 -1
- package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.js +1 -1
- package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.js +1 -1
- package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.js +1 -1
- package/dist/src/__tests__/mc-integration/stdlib-coverage-8.test.js +1 -1
- package/dist/src/__tests__/mc-syntax.test.js +4 -1
- package/dist/src/__tests__/monomorphize-coverage.test.d.ts +9 -0
- package/dist/src/__tests__/monomorphize-coverage.test.js +204 -0
- package/dist/src/__tests__/optimizer-cse.test.d.ts +7 -0
- package/dist/src/__tests__/optimizer-cse.test.js +226 -0
- package/dist/src/__tests__/parser.test.js +4 -13
- package/dist/src/__tests__/repl-server-extra.test.js +6 -7
- package/dist/src/__tests__/repl-server.test.js +5 -7
- package/dist/src/__tests__/stdlib/queue.test.js +6 -6
- package/dist/src/cli.js +0 -0
- package/dist/src/lexer/index.js +2 -1
- package/dist/src/lint/index.d.ts +12 -5
- package/dist/src/lint/index.js +730 -5
- package/dist/src/lsp/main.js +0 -0
- package/dist/src/mc-test/client.d.ts +21 -0
- package/dist/src/mc-test/client.js +34 -0
- package/dist/src/mir/lower.js +108 -6
- package/dist/src/optimizer/interprocedural.js +37 -2
- package/dist/src/parser/decl-parser.d.ts +19 -0
- package/dist/src/parser/decl-parser.js +323 -0
- package/dist/src/parser/expr-parser.d.ts +46 -0
- package/dist/src/parser/expr-parser.js +759 -0
- package/dist/src/parser/index.d.ts +8 -129
- package/dist/src/parser/index.js +13 -2262
- package/dist/src/parser/stmt-parser.d.ts +28 -0
- package/dist/src/parser/stmt-parser.js +577 -0
- package/dist/src/parser/type-parser.d.ts +20 -0
- package/dist/src/parser/type-parser.js +257 -0
- package/dist/src/parser/utils.d.ts +34 -0
- package/dist/src/parser/utils.js +141 -0
- package/docs/dev/README-mc-integration-tests.md +141 -0
- package/docs/lint-rules.md +162 -0
- package/docs/stdlib/bigint.md +2 -0
- package/editors/vscode/README.md +63 -41
- package/editors/vscode/out/extension.js +1881 -1776
- package/editors/vscode/out/lsp-server.js +4257 -3651
- package/editors/vscode/package-lock.json +3 -3
- package/editors/vscode/package.json +1 -1
- package/examples/loops-demo.mcrs +87 -0
- package/package.json +1 -1
- package/redscript-docs/docs/en/stdlib/advanced.md +629 -0
- package/redscript-docs/docs/en/stdlib/bigint.md +316 -0
- package/redscript-docs/docs/en/stdlib/bits.md +292 -0
- package/redscript-docs/docs/en/stdlib/bossbar.md +177 -0
- package/redscript-docs/docs/en/stdlib/calculus.md +289 -0
- package/redscript-docs/docs/en/stdlib/color.md +353 -0
- package/redscript-docs/docs/en/stdlib/combat.md +88 -0
- package/redscript-docs/docs/en/stdlib/cooldown.md +82 -0
- package/redscript-docs/docs/en/stdlib/dialog.md +155 -0
- package/redscript-docs/docs/en/stdlib/easing.md +558 -0
- package/redscript-docs/docs/en/stdlib/ecs.md +475 -0
- package/redscript-docs/docs/en/stdlib/effects.md +324 -0
- package/redscript-docs/docs/en/stdlib/events.md +3 -0
- package/redscript-docs/docs/en/stdlib/expr.md +45 -0
- package/redscript-docs/docs/en/stdlib/fft.md +141 -0
- package/redscript-docs/docs/en/stdlib/geometry.md +430 -0
- package/redscript-docs/docs/en/stdlib/graph.md +259 -0
- package/redscript-docs/docs/en/stdlib/heap.md +185 -0
- package/redscript-docs/docs/en/stdlib/interactions.md +179 -0
- package/redscript-docs/docs/en/stdlib/inventory.md +97 -0
- package/redscript-docs/docs/en/stdlib/linalg.md +557 -0
- package/redscript-docs/docs/en/stdlib/list.md +559 -0
- package/redscript-docs/docs/en/stdlib/map.md +140 -0
- package/redscript-docs/docs/en/stdlib/math.md +193 -0
- package/redscript-docs/docs/en/stdlib/math_hp.md +149 -0
- package/redscript-docs/docs/en/stdlib/matrix.md +403 -0
- package/redscript-docs/docs/en/stdlib/mobs.md +965 -0
- package/redscript-docs/docs/en/stdlib/noise.md +244 -0
- package/redscript-docs/docs/en/stdlib/ode.md +253 -0
- package/redscript-docs/docs/en/stdlib/parabola.md +342 -0
- package/redscript-docs/docs/en/stdlib/particles.md +311 -0
- package/redscript-docs/docs/en/stdlib/pathfind.md +255 -0
- package/redscript-docs/docs/en/stdlib/physics.md +493 -0
- package/redscript-docs/docs/en/stdlib/player.md +78 -0
- package/redscript-docs/docs/en/stdlib/quaternion.md +673 -0
- package/redscript-docs/docs/en/stdlib/queue.md +134 -0
- package/redscript-docs/docs/en/stdlib/random.md +223 -0
- package/redscript-docs/docs/en/stdlib/result.md +143 -0
- package/redscript-docs/docs/en/stdlib/scheduler.md +183 -0
- package/redscript-docs/docs/en/stdlib/set_int.md +190 -0
- package/redscript-docs/docs/en/stdlib/sets.md +101 -0
- package/redscript-docs/docs/en/stdlib/signal.md +400 -0
- package/redscript-docs/docs/en/stdlib/sort.md +104 -0
- package/redscript-docs/docs/en/stdlib/spawn.md +147 -0
- package/redscript-docs/docs/en/stdlib/state.md +142 -0
- package/redscript-docs/docs/en/stdlib/strings.md +154 -0
- package/redscript-docs/docs/en/stdlib/tags.md +3451 -0
- package/redscript-docs/docs/en/stdlib/teams.md +153 -0
- package/redscript-docs/docs/en/stdlib/timer.md +246 -0
- package/redscript-docs/docs/en/stdlib/vec.md +158 -0
- package/redscript-docs/docs/en/stdlib/world.md +298 -0
- package/redscript-docs/docs/zh/stdlib/advanced.md +615 -0
- package/redscript-docs/docs/zh/stdlib/bigint.md +316 -0
- package/redscript-docs/docs/zh/stdlib/bits.md +292 -0
- package/redscript-docs/docs/zh/stdlib/bossbar.md +170 -0
- package/redscript-docs/docs/zh/stdlib/calculus.md +287 -0
- package/redscript-docs/docs/zh/stdlib/color.md +353 -0
- package/redscript-docs/docs/zh/stdlib/combat.md +88 -0
- package/redscript-docs/docs/zh/stdlib/cooldown.md +84 -0
- package/redscript-docs/docs/zh/stdlib/dialog.md +152 -0
- package/redscript-docs/docs/zh/stdlib/easing.md +558 -0
- package/redscript-docs/docs/zh/stdlib/ecs.md +472 -0
- package/redscript-docs/docs/zh/stdlib/effects.md +324 -0
- package/redscript-docs/docs/zh/stdlib/events.md +3 -0
- package/redscript-docs/docs/zh/stdlib/expr.md +37 -0
- package/redscript-docs/docs/zh/stdlib/fft.md +128 -0
- package/redscript-docs/docs/zh/stdlib/geometry.md +430 -0
- package/redscript-docs/docs/zh/stdlib/graph.md +259 -0
- package/redscript-docs/docs/zh/stdlib/heap.md +185 -0
- package/redscript-docs/docs/zh/stdlib/interactions.md +160 -0
- package/redscript-docs/docs/zh/stdlib/inventory.md +94 -0
- package/redscript-docs/docs/zh/stdlib/linalg.md +543 -0
- package/redscript-docs/docs/zh/stdlib/list.md +561 -0
- package/redscript-docs/docs/zh/stdlib/map.md +132 -0
- package/redscript-docs/docs/zh/stdlib/math.md +193 -0
- package/redscript-docs/docs/zh/stdlib/math_hp.md +143 -0
- package/redscript-docs/docs/zh/stdlib/matrix.md +396 -0
- package/redscript-docs/docs/zh/stdlib/mobs.md +965 -0
- package/redscript-docs/docs/zh/stdlib/noise.md +244 -0
- package/redscript-docs/docs/zh/stdlib/ode.md +243 -0
- package/redscript-docs/docs/zh/stdlib/parabola.md +337 -0
- package/redscript-docs/docs/zh/stdlib/particles.md +307 -0
- package/redscript-docs/docs/zh/stdlib/pathfind.md +255 -0
- package/redscript-docs/docs/zh/stdlib/physics.md +493 -0
- package/redscript-docs/docs/zh/stdlib/player.md +78 -0
- package/redscript-docs/docs/zh/stdlib/quaternion.md +669 -0
- package/redscript-docs/docs/zh/stdlib/queue.md +124 -0
- package/redscript-docs/docs/zh/stdlib/random.md +222 -0
- package/redscript-docs/docs/zh/stdlib/result.md +147 -0
- package/redscript-docs/docs/zh/stdlib/scheduler.md +173 -0
- package/redscript-docs/docs/zh/stdlib/set_int.md +180 -0
- package/redscript-docs/docs/zh/stdlib/sets.md +107 -0
- package/redscript-docs/docs/zh/stdlib/signal.md +373 -0
- package/redscript-docs/docs/zh/stdlib/sort.md +104 -0
- package/redscript-docs/docs/zh/stdlib/spawn.md +142 -0
- package/redscript-docs/docs/zh/stdlib/state.md +134 -0
- package/redscript-docs/docs/zh/stdlib/strings.md +107 -0
- package/redscript-docs/docs/zh/stdlib/tags.md +3451 -0
- package/redscript-docs/docs/zh/stdlib/teams.md +150 -0
- package/redscript-docs/docs/zh/stdlib/timer.md +254 -0
- package/redscript-docs/docs/zh/stdlib/vec.md +158 -0
- package/redscript-docs/docs/zh/stdlib/world.md +289 -0
- package/src/__tests__/formatter-extra.test.ts +139 -0
- package/src/__tests__/global-vars.test.ts +171 -0
- package/src/__tests__/lint/new-rules.test.ts +437 -0
- package/src/__tests__/lsp-rename.test.ts +171 -0
- package/src/__tests__/mc-integration/say-fstring.test.ts +211 -0
- package/src/__tests__/mc-integration/stdlib-coverage-2.test.ts +1 -1
- package/src/__tests__/mc-integration/stdlib-coverage-3.test.ts +1 -1
- package/src/__tests__/mc-integration/stdlib-coverage-4.test.ts +1 -1
- package/src/__tests__/mc-integration/stdlib-coverage-5.test.ts +1 -1
- package/src/__tests__/mc-integration/stdlib-coverage-6.test.ts +1 -1
- package/src/__tests__/mc-integration/stdlib-coverage-7.test.ts +1 -1
- package/src/__tests__/mc-integration/stdlib-coverage-8.test.ts +1 -1
- package/src/__tests__/mc-syntax.test.ts +3 -0
- package/src/__tests__/monomorphize-coverage.test.ts +220 -0
- package/src/__tests__/optimizer-cse.test.ts +250 -0
- package/src/__tests__/parser.test.ts +4 -13
- package/src/__tests__/repl-server-extra.test.ts +6 -6
- package/src/__tests__/repl-server.test.ts +5 -6
- package/src/__tests__/stdlib/queue.test.ts +6 -6
- package/src/lexer/index.ts +2 -1
- package/src/lint/index.ts +713 -5
- package/src/mc-test/client.ts +40 -0
- package/src/mir/lower.ts +111 -2
- package/src/optimizer/interprocedural.ts +40 -2
- package/src/parser/decl-parser.ts +349 -0
- package/src/parser/expr-parser.ts +838 -0
- package/src/parser/index.ts +17 -2558
- package/src/parser/stmt-parser.ts +585 -0
- package/src/parser/type-parser.ts +276 -0
- package/src/parser/utils.ts +173 -0
- package/src/stdlib/queue.mcrs +19 -6
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StmtParser — statement parsing (if/while/for/match/execute/etc).
|
|
3
|
+
* Extends ExprParser so statement methods can call expression methods.
|
|
4
|
+
*/
|
|
5
|
+
import type { Stmt, Block } from '../ast/types';
|
|
6
|
+
import { ExprParser } from './expr-parser';
|
|
7
|
+
export declare class StmtParser extends ExprParser {
|
|
8
|
+
parseBlock(): Block;
|
|
9
|
+
parseStmt(): Stmt;
|
|
10
|
+
private parseLetStmt;
|
|
11
|
+
private parseLocalConstDecl;
|
|
12
|
+
private parseReturnStmt;
|
|
13
|
+
private parseIfStmt;
|
|
14
|
+
private parseWhileStmt;
|
|
15
|
+
private parseDoWhileStmt;
|
|
16
|
+
private parseRepeatStmt;
|
|
17
|
+
private parseParenOptionalCond;
|
|
18
|
+
private parseForStmt;
|
|
19
|
+
private parseForRangeStmt;
|
|
20
|
+
private parseForeachStmt;
|
|
21
|
+
private parseMatchPattern;
|
|
22
|
+
private parseMatchStmt;
|
|
23
|
+
private parseAsStmt;
|
|
24
|
+
private parseAtStmt;
|
|
25
|
+
private parseExecuteStmt;
|
|
26
|
+
private parseExecuteCondition;
|
|
27
|
+
private parseExprStmt;
|
|
28
|
+
}
|
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* StmtParser — statement parsing (if/while/for/match/execute/etc).
|
|
4
|
+
* Extends ExprParser so statement methods can call expression methods.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.StmtParser = void 0;
|
|
8
|
+
const diagnostics_1 = require("../diagnostics");
|
|
9
|
+
const expr_parser_1 = require("./expr-parser");
|
|
10
|
+
class StmtParser extends expr_parser_1.ExprParser {
|
|
11
|
+
// -------------------------------------------------------------------------
|
|
12
|
+
// Block
|
|
13
|
+
// -------------------------------------------------------------------------
|
|
14
|
+
parseBlock() {
|
|
15
|
+
this.expect('{');
|
|
16
|
+
const stmts = [];
|
|
17
|
+
while (!this.check('}') && !this.check('eof')) {
|
|
18
|
+
try {
|
|
19
|
+
stmts.push(this.parseStmt());
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err instanceof diagnostics_1.DiagnosticError) {
|
|
23
|
+
this.parseErrors.push(err);
|
|
24
|
+
this.syncToNextStmt();
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
this.expect('}');
|
|
32
|
+
return stmts;
|
|
33
|
+
}
|
|
34
|
+
// -------------------------------------------------------------------------
|
|
35
|
+
// Statement dispatch
|
|
36
|
+
// -------------------------------------------------------------------------
|
|
37
|
+
parseStmt() {
|
|
38
|
+
if (this.check('let'))
|
|
39
|
+
return this.parseLetStmt();
|
|
40
|
+
if (this.check('const'))
|
|
41
|
+
return this.parseLocalConstDecl();
|
|
42
|
+
if (this.check('return'))
|
|
43
|
+
return this.parseReturnStmt();
|
|
44
|
+
if (this.check('break')) {
|
|
45
|
+
const token = this.advance();
|
|
46
|
+
if (this.check('ident')) {
|
|
47
|
+
const labelToken = this.advance();
|
|
48
|
+
this.match(';');
|
|
49
|
+
return this.withLoc({ kind: 'break_label', label: labelToken.value }, token);
|
|
50
|
+
}
|
|
51
|
+
this.match(';');
|
|
52
|
+
return this.withLoc({ kind: 'break' }, token);
|
|
53
|
+
}
|
|
54
|
+
if (this.check('continue')) {
|
|
55
|
+
const token = this.advance();
|
|
56
|
+
if (this.check('ident')) {
|
|
57
|
+
const labelToken = this.advance();
|
|
58
|
+
this.match(';');
|
|
59
|
+
return this.withLoc({ kind: 'continue_label', label: labelToken.value }, token);
|
|
60
|
+
}
|
|
61
|
+
this.match(';');
|
|
62
|
+
return this.withLoc({ kind: 'continue' }, token);
|
|
63
|
+
}
|
|
64
|
+
if (this.check('if'))
|
|
65
|
+
return this.parseIfStmt();
|
|
66
|
+
// Labeled loop: ident ':' (while|for|foreach|repeat)
|
|
67
|
+
if (this.check('ident') && this.peek(1).kind === ':') {
|
|
68
|
+
const labelToken = this.advance();
|
|
69
|
+
this.advance(); // consume ':'
|
|
70
|
+
let loopStmt;
|
|
71
|
+
if (this.check('while')) {
|
|
72
|
+
loopStmt = this.parseWhileStmt();
|
|
73
|
+
}
|
|
74
|
+
else if (this.check('for')) {
|
|
75
|
+
loopStmt = this.parseForStmt();
|
|
76
|
+
}
|
|
77
|
+
else if (this.check('foreach')) {
|
|
78
|
+
loopStmt = this.parseForeachStmt();
|
|
79
|
+
}
|
|
80
|
+
else if (this.check('repeat')) {
|
|
81
|
+
loopStmt = this.parseRepeatStmt();
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw new diagnostics_1.DiagnosticError('ParseError', `Expected loop statement after label '${labelToken.value}:', found '${this.peek().kind}'`, { line: labelToken.line, col: labelToken.col });
|
|
85
|
+
}
|
|
86
|
+
return this.withLoc({ kind: 'labeled_loop', label: labelToken.value, body: loopStmt }, labelToken);
|
|
87
|
+
}
|
|
88
|
+
if (this.check('while'))
|
|
89
|
+
return this.parseWhileStmt();
|
|
90
|
+
if (this.check('do'))
|
|
91
|
+
return this.parseDoWhileStmt();
|
|
92
|
+
if (this.check('repeat'))
|
|
93
|
+
return this.parseRepeatStmt();
|
|
94
|
+
if (this.check('for'))
|
|
95
|
+
return this.parseForStmt();
|
|
96
|
+
if (this.check('foreach'))
|
|
97
|
+
return this.parseForeachStmt();
|
|
98
|
+
if (this.check('match'))
|
|
99
|
+
return this.parseMatchStmt();
|
|
100
|
+
if (this.check('as'))
|
|
101
|
+
return this.parseAsStmt();
|
|
102
|
+
if (this.check('at'))
|
|
103
|
+
return this.parseAtStmt();
|
|
104
|
+
if (this.check('execute'))
|
|
105
|
+
return this.parseExecuteStmt();
|
|
106
|
+
if (this.check('raw_cmd')) {
|
|
107
|
+
const token = this.advance();
|
|
108
|
+
const cmd = token.value;
|
|
109
|
+
this.match(';');
|
|
110
|
+
return this.withLoc({ kind: 'raw', cmd }, token);
|
|
111
|
+
}
|
|
112
|
+
return this.parseExprStmt();
|
|
113
|
+
}
|
|
114
|
+
// -------------------------------------------------------------------------
|
|
115
|
+
// Individual statement parsers
|
|
116
|
+
// -------------------------------------------------------------------------
|
|
117
|
+
parseLetStmt() {
|
|
118
|
+
const letToken = this.expect('let');
|
|
119
|
+
if (this.check('(')) {
|
|
120
|
+
this.advance();
|
|
121
|
+
const names = [];
|
|
122
|
+
do {
|
|
123
|
+
names.push(this.expect('ident').value);
|
|
124
|
+
} while (this.match(','));
|
|
125
|
+
this.expect(')');
|
|
126
|
+
let type;
|
|
127
|
+
if (this.match(':'))
|
|
128
|
+
type = this.parseType();
|
|
129
|
+
this.expect('=');
|
|
130
|
+
const init = this.parseExpr();
|
|
131
|
+
this.match(';');
|
|
132
|
+
return this.withLoc({ kind: 'let_destruct', names, type, init }, letToken);
|
|
133
|
+
}
|
|
134
|
+
const name = this.expect('ident').value;
|
|
135
|
+
let type;
|
|
136
|
+
if (this.match(':'))
|
|
137
|
+
type = this.parseType();
|
|
138
|
+
this.expect('=');
|
|
139
|
+
const init = this.parseExpr();
|
|
140
|
+
this.match(';');
|
|
141
|
+
return this.withLoc({ kind: 'let', name, type, init }, letToken);
|
|
142
|
+
}
|
|
143
|
+
parseLocalConstDecl() {
|
|
144
|
+
const constToken = this.expect('const');
|
|
145
|
+
const name = this.expect('ident').value;
|
|
146
|
+
this.expect(':');
|
|
147
|
+
const type = this.parseType();
|
|
148
|
+
this.expect('=');
|
|
149
|
+
const value = this.parseExpr();
|
|
150
|
+
this.match(';');
|
|
151
|
+
return this.withLoc({ kind: 'const_decl', name, type, value }, constToken);
|
|
152
|
+
}
|
|
153
|
+
parseReturnStmt() {
|
|
154
|
+
const returnToken = this.expect('return');
|
|
155
|
+
let value;
|
|
156
|
+
if (!this.check(';') && !this.check('}') && !this.check('eof')) {
|
|
157
|
+
value = this.parseExpr();
|
|
158
|
+
}
|
|
159
|
+
this.match(';');
|
|
160
|
+
return this.withLoc({ kind: 'return', value }, returnToken);
|
|
161
|
+
}
|
|
162
|
+
parseIfStmt() {
|
|
163
|
+
const ifToken = this.expect('if');
|
|
164
|
+
// if let Some(x) = expr { ... }
|
|
165
|
+
if (this.check('let') && this.peek(1).kind === 'ident' && this.peek(1).value === 'Some') {
|
|
166
|
+
this.advance();
|
|
167
|
+
this.advance();
|
|
168
|
+
this.expect('(');
|
|
169
|
+
const binding = this.expect('ident').value;
|
|
170
|
+
this.expect(')');
|
|
171
|
+
this.expect('=');
|
|
172
|
+
const init = this.parseExpr();
|
|
173
|
+
const then = this.parseBlock();
|
|
174
|
+
let else_;
|
|
175
|
+
if (this.match('else')) {
|
|
176
|
+
else_ = this.check('if') ? [this.parseIfStmt()] : this.parseBlock();
|
|
177
|
+
}
|
|
178
|
+
return this.withLoc({ kind: 'if_let_some', binding, init, then, else_ }, ifToken);
|
|
179
|
+
}
|
|
180
|
+
const cond = this.parseParenOptionalCond();
|
|
181
|
+
const then = this.parseBlock();
|
|
182
|
+
let else_;
|
|
183
|
+
if (this.match('else')) {
|
|
184
|
+
else_ = this.check('if') ? [this.parseIfStmt()] : this.parseBlock();
|
|
185
|
+
}
|
|
186
|
+
return this.withLoc({ kind: 'if', cond, then, else_ }, ifToken);
|
|
187
|
+
}
|
|
188
|
+
parseWhileStmt() {
|
|
189
|
+
const whileToken = this.expect('while');
|
|
190
|
+
if (this.check('let') && this.peek(1).kind === 'ident' && this.peek(1).value === 'Some') {
|
|
191
|
+
this.advance();
|
|
192
|
+
this.advance();
|
|
193
|
+
this.expect('(');
|
|
194
|
+
const binding = this.expect('ident').value;
|
|
195
|
+
this.expect(')');
|
|
196
|
+
this.expect('=');
|
|
197
|
+
const init = this.parseExpr();
|
|
198
|
+
const body = this.parseBlock();
|
|
199
|
+
return this.withLoc({ kind: 'while_let_some', binding, init, body }, whileToken);
|
|
200
|
+
}
|
|
201
|
+
const cond = this.parseParenOptionalCond();
|
|
202
|
+
const body = this.parseBlock();
|
|
203
|
+
return this.withLoc({ kind: 'while', cond, body }, whileToken);
|
|
204
|
+
}
|
|
205
|
+
parseDoWhileStmt() {
|
|
206
|
+
const doToken = this.expect('do');
|
|
207
|
+
const body = this.parseBlock();
|
|
208
|
+
this.expect('while');
|
|
209
|
+
const cond = this.parseParenOptionalCond();
|
|
210
|
+
this.match(';');
|
|
211
|
+
return this.withLoc({ kind: 'do_while', cond, body }, doToken);
|
|
212
|
+
}
|
|
213
|
+
parseRepeatStmt() {
|
|
214
|
+
const repeatToken = this.expect('repeat');
|
|
215
|
+
const countToken = this.expect('int_lit');
|
|
216
|
+
const count = parseInt(countToken.value, 10);
|
|
217
|
+
const body = this.parseBlock();
|
|
218
|
+
return this.withLoc({ kind: 'repeat', count, body }, repeatToken);
|
|
219
|
+
}
|
|
220
|
+
parseParenOptionalCond() {
|
|
221
|
+
if (this.match('(')) {
|
|
222
|
+
const cond = this.parseExpr();
|
|
223
|
+
this.expect(')');
|
|
224
|
+
return cond;
|
|
225
|
+
}
|
|
226
|
+
return this.parseExpr();
|
|
227
|
+
}
|
|
228
|
+
parseForStmt() {
|
|
229
|
+
const forToken = this.expect('for');
|
|
230
|
+
if (this.check('ident') && this.peek(1).kind === 'in') {
|
|
231
|
+
return this.parseForRangeStmt(forToken);
|
|
232
|
+
}
|
|
233
|
+
this.expect('(');
|
|
234
|
+
if (this.check('let') && this.peek(1).kind === 'ident' && this.peek(2).kind === 'in' && this.peek(3).kind === 'ident' && this.peek(4).kind === ',') {
|
|
235
|
+
this.advance();
|
|
236
|
+
const binding = this.expect('ident').value;
|
|
237
|
+
this.expect('in');
|
|
238
|
+
const arrayName = this.expect('ident').value;
|
|
239
|
+
this.expect(',');
|
|
240
|
+
const lenExpr = this.parseExpr();
|
|
241
|
+
this.expect(')');
|
|
242
|
+
const body = this.parseBlock();
|
|
243
|
+
return this.withLoc({ kind: 'for_in_array', binding, arrayName, lenExpr, body }, forToken);
|
|
244
|
+
}
|
|
245
|
+
let init;
|
|
246
|
+
if (this.check('let')) {
|
|
247
|
+
const letToken = this.expect('let');
|
|
248
|
+
const name = this.expect('ident').value;
|
|
249
|
+
let type;
|
|
250
|
+
if (this.match(':'))
|
|
251
|
+
type = this.parseType();
|
|
252
|
+
this.expect('=');
|
|
253
|
+
const initExpr = this.parseExpr();
|
|
254
|
+
const initStmt = { kind: 'let', name, type, init: initExpr };
|
|
255
|
+
init = this.withLoc(initStmt, letToken);
|
|
256
|
+
}
|
|
257
|
+
this.expect(';');
|
|
258
|
+
const cond = this.parseExpr();
|
|
259
|
+
this.expect(';');
|
|
260
|
+
const step = this.parseExpr();
|
|
261
|
+
this.expect(')');
|
|
262
|
+
const body = this.parseBlock();
|
|
263
|
+
return this.withLoc({ kind: 'for', init, cond, step, body }, forToken);
|
|
264
|
+
}
|
|
265
|
+
parseForRangeStmt(forToken) {
|
|
266
|
+
const varName = this.expect('ident').value;
|
|
267
|
+
this.expect('in');
|
|
268
|
+
let start;
|
|
269
|
+
let end;
|
|
270
|
+
let inclusive = false;
|
|
271
|
+
if (this.check('range_lit')) {
|
|
272
|
+
const rangeToken = this.advance();
|
|
273
|
+
const raw = rangeToken.value;
|
|
274
|
+
inclusive = raw.includes('..=');
|
|
275
|
+
const range = this.parseRangeValue(raw);
|
|
276
|
+
start = this.withLoc({ kind: 'int_lit', value: range.min ?? 0 }, rangeToken);
|
|
277
|
+
if (range.max !== null && range.max !== undefined) {
|
|
278
|
+
end = this.withLoc({ kind: 'int_lit', value: range.max }, rangeToken);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
end = this.parseUnaryExpr();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
const arrayOrStart = this.parseExpr();
|
|
286
|
+
if (!this.check('range_lit')) {
|
|
287
|
+
const body = this.parseBlock();
|
|
288
|
+
return this.withLoc({ kind: 'for_each', binding: varName, array: arrayOrStart, body }, forToken);
|
|
289
|
+
}
|
|
290
|
+
start = arrayOrStart;
|
|
291
|
+
if (this.check('range_lit')) {
|
|
292
|
+
const rangeOp = this.advance();
|
|
293
|
+
inclusive = rangeOp.value.includes('=');
|
|
294
|
+
const afterOp = rangeOp.value.replace(/^\.\.=?/, '');
|
|
295
|
+
if (afterOp.length > 0) {
|
|
296
|
+
end = this.withLoc({ kind: 'int_lit', value: parseInt(afterOp, 10) }, rangeOp);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
end = this.parseExpr();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.error('Expected .. or ..= in for-range expression. Example: for i in 0..10 { ... }');
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const body = this.parseBlock();
|
|
307
|
+
return this.withLoc({ kind: 'for_range', varName, start, end, inclusive, body }, forToken);
|
|
308
|
+
}
|
|
309
|
+
parseForeachStmt() {
|
|
310
|
+
const foreachToken = this.expect('foreach');
|
|
311
|
+
this.expect('(');
|
|
312
|
+
const binding = this.expect('ident').value;
|
|
313
|
+
this.expect('in');
|
|
314
|
+
const iterable = this.parseExpr();
|
|
315
|
+
this.expect(')');
|
|
316
|
+
let executeContext;
|
|
317
|
+
const execIdentKeywords = ['positioned', 'rotated', 'facing', 'anchored', 'align', 'on', 'summon'];
|
|
318
|
+
if (this.check('as') || this.check('at') || this.check('in') || (this.check('ident') && execIdentKeywords.includes(this.peek().value))) {
|
|
319
|
+
let context = '';
|
|
320
|
+
while (!this.check('{') && !this.check('eof')) {
|
|
321
|
+
context += this.advance().value + ' ';
|
|
322
|
+
}
|
|
323
|
+
executeContext = context.trim();
|
|
324
|
+
}
|
|
325
|
+
const body = this.parseBlock();
|
|
326
|
+
return this.withLoc({ kind: 'foreach', binding, iterable, body, executeContext }, foreachToken);
|
|
327
|
+
}
|
|
328
|
+
// -------------------------------------------------------------------------
|
|
329
|
+
// Match
|
|
330
|
+
// -------------------------------------------------------------------------
|
|
331
|
+
parseMatchPattern() {
|
|
332
|
+
if (this.check('ident') && this.peek().value === '_') {
|
|
333
|
+
this.advance();
|
|
334
|
+
return { kind: 'PatWild' };
|
|
335
|
+
}
|
|
336
|
+
if (this.check('ident') && this.peek().value === 'None') {
|
|
337
|
+
this.advance();
|
|
338
|
+
return { kind: 'PatNone' };
|
|
339
|
+
}
|
|
340
|
+
if (this.check('ident') && this.peek().value === 'Some') {
|
|
341
|
+
this.advance();
|
|
342
|
+
this.expect('(');
|
|
343
|
+
const binding = this.expect('ident').value;
|
|
344
|
+
this.expect(')');
|
|
345
|
+
return { kind: 'PatSome', binding };
|
|
346
|
+
}
|
|
347
|
+
if (this.check('ident') && this.peek(1).kind === '::') {
|
|
348
|
+
const enumName = this.advance().value;
|
|
349
|
+
this.expect('::');
|
|
350
|
+
const variant = this.expect('ident').value;
|
|
351
|
+
const bindings = [];
|
|
352
|
+
if (this.check('(')) {
|
|
353
|
+
this.advance();
|
|
354
|
+
while (!this.check(')') && !this.check('eof')) {
|
|
355
|
+
bindings.push(this.expect('ident').value);
|
|
356
|
+
if (!this.match(','))
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
this.expect(')');
|
|
360
|
+
}
|
|
361
|
+
return { kind: 'PatEnum', enumName, variant, bindings };
|
|
362
|
+
}
|
|
363
|
+
if (this.check('int_lit')) {
|
|
364
|
+
const tok = this.advance();
|
|
365
|
+
return { kind: 'PatInt', value: parseInt(tok.value, 10) };
|
|
366
|
+
}
|
|
367
|
+
if (this.check('-') && this.peek(1).kind === 'int_lit') {
|
|
368
|
+
this.advance();
|
|
369
|
+
const tok = this.advance();
|
|
370
|
+
return { kind: 'PatInt', value: -parseInt(tok.value, 10) };
|
|
371
|
+
}
|
|
372
|
+
const e = this.parseExpr();
|
|
373
|
+
return { kind: 'PatExpr', expr: e };
|
|
374
|
+
}
|
|
375
|
+
parseMatchStmt() {
|
|
376
|
+
const matchToken = this.expect('match');
|
|
377
|
+
let expr;
|
|
378
|
+
if (this.check('(')) {
|
|
379
|
+
this.advance();
|
|
380
|
+
expr = this.parseExpr();
|
|
381
|
+
this.expect(')');
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
expr = this.parseExpr();
|
|
385
|
+
}
|
|
386
|
+
this.expect('{');
|
|
387
|
+
const arms = [];
|
|
388
|
+
while (!this.check('}') && !this.check('eof')) {
|
|
389
|
+
const pattern = this.parseMatchPattern();
|
|
390
|
+
this.expect('=>');
|
|
391
|
+
const body = this.parseBlock();
|
|
392
|
+
this.match(',');
|
|
393
|
+
arms.push({ pattern, body });
|
|
394
|
+
}
|
|
395
|
+
this.expect('}');
|
|
396
|
+
return this.withLoc({ kind: 'match', expr, arms }, matchToken);
|
|
397
|
+
}
|
|
398
|
+
// -------------------------------------------------------------------------
|
|
399
|
+
// As / At / Execute
|
|
400
|
+
// -------------------------------------------------------------------------
|
|
401
|
+
parseAsStmt() {
|
|
402
|
+
const asToken = this.expect('as');
|
|
403
|
+
const as_sel = this.parseSelector();
|
|
404
|
+
if (this.match('at')) {
|
|
405
|
+
const at_sel = this.parseSelector();
|
|
406
|
+
const body = this.parseBlock();
|
|
407
|
+
return this.withLoc({ kind: 'as_at', as_sel, at_sel, body }, asToken);
|
|
408
|
+
}
|
|
409
|
+
const body = this.parseBlock();
|
|
410
|
+
return this.withLoc({ kind: 'as_block', selector: as_sel, body }, asToken);
|
|
411
|
+
}
|
|
412
|
+
parseAtStmt() {
|
|
413
|
+
const atToken = this.expect('at');
|
|
414
|
+
const selector = this.parseSelector();
|
|
415
|
+
const body = this.parseBlock();
|
|
416
|
+
return this.withLoc({ kind: 'at_block', selector, body }, atToken);
|
|
417
|
+
}
|
|
418
|
+
parseExecuteStmt() {
|
|
419
|
+
const executeToken = this.expect('execute');
|
|
420
|
+
const subcommands = [];
|
|
421
|
+
while (!this.check('run') && !this.check('eof')) {
|
|
422
|
+
if (this.match('as')) {
|
|
423
|
+
const selector = this.parseSelector();
|
|
424
|
+
subcommands.push({ kind: 'as', selector });
|
|
425
|
+
}
|
|
426
|
+
else if (this.match('at')) {
|
|
427
|
+
const selector = this.parseSelector();
|
|
428
|
+
subcommands.push({ kind: 'at', selector });
|
|
429
|
+
}
|
|
430
|
+
else if (this.checkIdent('positioned')) {
|
|
431
|
+
this.advance();
|
|
432
|
+
if (this.match('as')) {
|
|
433
|
+
const selector = this.parseSelector();
|
|
434
|
+
subcommands.push({ kind: 'positioned_as', selector });
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
const x = this.parseCoordToken();
|
|
438
|
+
const y = this.parseCoordToken();
|
|
439
|
+
const z = this.parseCoordToken();
|
|
440
|
+
subcommands.push({ kind: 'positioned', x, y, z });
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
else if (this.checkIdent('rotated')) {
|
|
444
|
+
this.advance();
|
|
445
|
+
if (this.match('as')) {
|
|
446
|
+
const selector = this.parseSelector();
|
|
447
|
+
subcommands.push({ kind: 'rotated_as', selector });
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
const yaw = this.parseCoordToken();
|
|
451
|
+
const pitch = this.parseCoordToken();
|
|
452
|
+
subcommands.push({ kind: 'rotated', yaw, pitch });
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
else if (this.checkIdent('facing')) {
|
|
456
|
+
this.advance();
|
|
457
|
+
if (this.checkIdent('entity')) {
|
|
458
|
+
this.advance();
|
|
459
|
+
const selector = this.parseSelector();
|
|
460
|
+
const anchor = this.checkIdent('eyes') || this.checkIdent('feet') ? this.advance().value : 'feet';
|
|
461
|
+
subcommands.push({ kind: 'facing_entity', selector, anchor });
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
const x = this.parseCoordToken();
|
|
465
|
+
const y = this.parseCoordToken();
|
|
466
|
+
const z = this.parseCoordToken();
|
|
467
|
+
subcommands.push({ kind: 'facing', x, y, z });
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
else if (this.checkIdent('anchored')) {
|
|
471
|
+
this.advance();
|
|
472
|
+
const anchor = this.advance().value;
|
|
473
|
+
subcommands.push({ kind: 'anchored', anchor });
|
|
474
|
+
}
|
|
475
|
+
else if (this.checkIdent('align')) {
|
|
476
|
+
this.advance();
|
|
477
|
+
const axes = this.advance().value;
|
|
478
|
+
subcommands.push({ kind: 'align', axes });
|
|
479
|
+
}
|
|
480
|
+
else if (this.checkIdent('on')) {
|
|
481
|
+
this.advance();
|
|
482
|
+
const relation = this.advance().value;
|
|
483
|
+
subcommands.push({ kind: 'on', relation });
|
|
484
|
+
}
|
|
485
|
+
else if (this.checkIdent('summon')) {
|
|
486
|
+
this.advance();
|
|
487
|
+
const entity = this.advance().value;
|
|
488
|
+
subcommands.push({ kind: 'summon', entity });
|
|
489
|
+
}
|
|
490
|
+
else if (this.checkIdent('store')) {
|
|
491
|
+
this.advance();
|
|
492
|
+
const storeType = this.advance().value;
|
|
493
|
+
if (this.checkIdent('score')) {
|
|
494
|
+
this.advance();
|
|
495
|
+
const target = this.advance().value;
|
|
496
|
+
const targetObj = this.advance().value;
|
|
497
|
+
if (storeType === 'result') {
|
|
498
|
+
subcommands.push({ kind: 'store_result', target, targetObj });
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
subcommands.push({ kind: 'store_success', target, targetObj });
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
this.error('store currently only supports score target');
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else if (this.match('if')) {
|
|
509
|
+
this.parseExecuteCondition(subcommands, 'if');
|
|
510
|
+
}
|
|
511
|
+
else if (this.match('unless')) {
|
|
512
|
+
this.parseExecuteCondition(subcommands, 'unless');
|
|
513
|
+
}
|
|
514
|
+
else if (this.match('in')) {
|
|
515
|
+
let dim = this.advance().value;
|
|
516
|
+
if (this.match(':'))
|
|
517
|
+
dim += ':' + this.advance().value;
|
|
518
|
+
subcommands.push({ kind: 'in', dimension: dim });
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
this.error(`Unexpected token in execute statement: '${this.peek().value || this.peek().kind}'. Valid subcommands: as, at, positioned, align, facing, rotated, anchored, if, unless, in, store`);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
this.expect('run');
|
|
525
|
+
const body = this.parseBlock();
|
|
526
|
+
return this.withLoc({ kind: 'execute', subcommands, body }, executeToken);
|
|
527
|
+
}
|
|
528
|
+
parseExecuteCondition(subcommands, type) {
|
|
529
|
+
if (this.checkIdent('entity') || this.check('selector')) {
|
|
530
|
+
if (this.checkIdent('entity'))
|
|
531
|
+
this.advance();
|
|
532
|
+
const selectorOrVar = this.parseSelectorOrVarSelector();
|
|
533
|
+
subcommands.push({ kind: type === 'if' ? 'if_entity' : 'unless_entity', ...selectorOrVar });
|
|
534
|
+
}
|
|
535
|
+
else if (this.checkIdent('block')) {
|
|
536
|
+
this.advance();
|
|
537
|
+
const x = this.parseCoordToken();
|
|
538
|
+
const y = this.parseCoordToken();
|
|
539
|
+
const z = this.parseCoordToken();
|
|
540
|
+
const block = this.parseBlockId();
|
|
541
|
+
subcommands.push({ kind: type === 'if' ? 'if_block' : 'unless_block', pos: [x, y, z], block });
|
|
542
|
+
}
|
|
543
|
+
else if (this.checkIdent('score')) {
|
|
544
|
+
this.advance();
|
|
545
|
+
const target = this.advance().value;
|
|
546
|
+
const targetObj = this.advance().value;
|
|
547
|
+
if (this.checkIdent('matches')) {
|
|
548
|
+
this.advance();
|
|
549
|
+
const range = this.advance().value;
|
|
550
|
+
subcommands.push({ kind: type === 'if' ? 'if_score_range' : 'unless_score_range', target, targetObj, range });
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
const op = this.advance().value;
|
|
554
|
+
const source = this.advance().value;
|
|
555
|
+
const sourceObj = this.advance().value;
|
|
556
|
+
subcommands.push({
|
|
557
|
+
kind: type === 'if' ? 'if_score' : 'unless_score',
|
|
558
|
+
target, targetObj, op, source, sourceObj
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
this.error(`Unknown condition type after ${type}`);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
// -------------------------------------------------------------------------
|
|
567
|
+
// Expression statement
|
|
568
|
+
// -------------------------------------------------------------------------
|
|
569
|
+
parseExprStmt() {
|
|
570
|
+
const expr = this.parseExpr();
|
|
571
|
+
this.match(';');
|
|
572
|
+
const exprToken = this.getLocToken(expr) ?? this.peek();
|
|
573
|
+
return this.withLoc({ kind: 'expr', expr }, exprToken);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
exports.StmtParser = StmtParser;
|
|
577
|
+
//# sourceMappingURL=stmt-parser.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeParser — parses type annotations and generic type arguments.
|
|
3
|
+
* Extends ParserBase to gain token navigation.
|
|
4
|
+
*/
|
|
5
|
+
import type { TypeNode, Param } from '../ast/types';
|
|
6
|
+
import { ParserBase } from './utils';
|
|
7
|
+
export declare class TypeParser extends ParserBase {
|
|
8
|
+
parseType(): TypeNode;
|
|
9
|
+
parseFunctionType(): TypeNode;
|
|
10
|
+
/**
|
|
11
|
+
* Try to parse `<Type, ...>` as explicit generic type arguments.
|
|
12
|
+
* Returns the parsed type list if successful, null if this looks like a comparison.
|
|
13
|
+
* Does NOT consume any tokens if it returns null.
|
|
14
|
+
*/
|
|
15
|
+
tryParseTypeArgs(): TypeNode[] | null;
|
|
16
|
+
isLambdaStart(): boolean;
|
|
17
|
+
typeTokenLength(offset: number): number;
|
|
18
|
+
parseParams(implTypeName?: string): Param[];
|
|
19
|
+
parseInterfaceParams(): Param[];
|
|
20
|
+
}
|