xbintsc 0.1.6 → 0.1.8

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.
Files changed (137) hide show
  1. package/README.md +7 -4
  2. package/dist/src/ast/common.d.ts +33 -0
  3. package/dist/src/ast/common.js +7 -0
  4. package/dist/src/ast/common.js.map +1 -0
  5. package/dist/src/ast/declarations.d.ts +110 -0
  6. package/dist/src/ast/declarations.js +5 -0
  7. package/dist/src/ast/declarations.js.map +1 -0
  8. package/dist/src/ast/expressions.d.ts +219 -0
  9. package/dist/src/ast/expressions.js +6 -0
  10. package/dist/src/ast/expressions.js.map +1 -0
  11. package/dist/src/ast/kinds.d.ts +160 -0
  12. package/dist/src/ast/kinds.js +171 -0
  13. package/dist/src/ast/kinds.js.map +1 -0
  14. package/dist/src/ast/modules.d.ts +61 -0
  15. package/dist/src/ast/modules.js +5 -0
  16. package/dist/src/ast/modules.js.map +1 -0
  17. package/dist/src/ast/nodes.d.ts +11 -839
  18. package/dist/src/ast/nodes.js +11 -237
  19. package/dist/src/ast/nodes.js.map +1 -1
  20. package/dist/src/ast/operators.d.ts +71 -0
  21. package/dist/src/ast/operators.js +77 -0
  22. package/dist/src/ast/operators.js.map +1 -0
  23. package/dist/src/ast/statements.d.ts +120 -0
  24. package/dist/src/ast/statements.js +5 -0
  25. package/dist/src/ast/statements.js.map +1 -0
  26. package/dist/src/ast/types.d.ts +123 -0
  27. package/dist/src/ast/types.js +6 -0
  28. package/dist/src/ast/types.js.map +1 -0
  29. package/dist/src/codegen/generator/calls.d.ts +22 -0
  30. package/dist/src/codegen/generator/calls.js +301 -0
  31. package/dist/src/codegen/generator/calls.js.map +1 -0
  32. package/dist/src/codegen/generator/context.d.ts +45 -0
  33. package/dist/src/codegen/generator/context.js +128 -0
  34. package/dist/src/codegen/generator/context.js.map +1 -0
  35. package/dist/src/codegen/generator/expressions.d.ts +22 -0
  36. package/dist/src/codegen/generator/expressions.js +383 -0
  37. package/dist/src/codegen/generator/expressions.js.map +1 -0
  38. package/dist/src/codegen/generator/generator.d.ts +22 -0
  39. package/dist/src/codegen/generator/generator.js +21 -0
  40. package/dist/src/codegen/generator/generator.js.map +1 -0
  41. package/dist/src/codegen/generator/module.d.ts +15 -0
  42. package/dist/src/codegen/generator/module.js +114 -0
  43. package/dist/src/codegen/generator/module.js.map +1 -0
  44. package/dist/src/codegen/generator/state.d.ts +40 -0
  45. package/dist/src/codegen/generator/state.js +84 -0
  46. package/dist/src/codegen/generator/state.js.map +1 -0
  47. package/dist/src/codegen/generator/statements.d.ts +22 -0
  48. package/dist/src/codegen/generator/statements.js +425 -0
  49. package/dist/src/codegen/generator/statements.js.map +1 -0
  50. package/dist/src/codegen/generator/tables.d.ts +19 -0
  51. package/dist/src/codegen/generator/tables.js +153 -0
  52. package/dist/src/codegen/generator/tables.js.map +1 -0
  53. package/dist/src/codegen/llvm.d.ts +4 -13
  54. package/dist/src/codegen/llvm.js +4 -1537
  55. package/dist/src/codegen/llvm.js.map +1 -1
  56. package/dist/src/driver/compiler.js +13 -4
  57. package/dist/src/driver/compiler.js.map +1 -1
  58. package/dist/src/lexer/char.d.ts +78 -0
  59. package/dist/src/lexer/char.js +106 -0
  60. package/dist/src/lexer/char.js.map +1 -0
  61. package/dist/src/lexer/scanner.js +1 -98
  62. package/dist/src/lexer/scanner.js.map +1 -1
  63. package/dist/src/parser/context.d.ts +58 -0
  64. package/dist/src/parser/context.js +174 -0
  65. package/dist/src/parser/context.js.map +1 -0
  66. package/dist/src/parser/declarations.d.ts +26 -0
  67. package/dist/src/parser/declarations.js +461 -0
  68. package/dist/src/parser/declarations.js.map +1 -0
  69. package/dist/src/parser/expressions.d.ts +27 -0
  70. package/dist/src/parser/expressions.js +437 -0
  71. package/dist/src/parser/expressions.js.map +1 -0
  72. package/dist/src/parser/helpers.d.ts +7 -0
  73. package/dist/src/parser/helpers.js +36 -0
  74. package/dist/src/parser/helpers.js.map +1 -0
  75. package/dist/src/parser/literals.d.ts +16 -0
  76. package/dist/src/parser/literals.js +193 -0
  77. package/dist/src/parser/literals.js.map +1 -0
  78. package/dist/src/parser/modules.d.ts +12 -0
  79. package/dist/src/parser/modules.js +175 -0
  80. package/dist/src/parser/modules.js.map +1 -0
  81. package/dist/src/parser/operators.d.ts +12 -0
  82. package/dist/src/parser/operators.js +172 -0
  83. package/dist/src/parser/operators.js.map +1 -0
  84. package/dist/src/parser/parser.d.ts +17 -122
  85. package/dist/src/parser/parser.js +18 -2311
  86. package/dist/src/parser/parser.js.map +1 -1
  87. package/dist/src/parser/speculation.d.ts +6 -0
  88. package/dist/src/parser/speculation.js +10 -0
  89. package/dist/src/parser/speculation.js.map +1 -0
  90. package/dist/src/parser/statements.d.ts +28 -0
  91. package/dist/src/parser/statements.js +402 -0
  92. package/dist/src/parser/statements.js.map +1 -0
  93. package/dist/src/parser/types.d.ts +21 -0
  94. package/dist/src/parser/types.js +338 -0
  95. package/dist/src/parser/types.js.map +1 -0
  96. package/package.json +1 -1
  97. package/runtime/rt_internal.h +106 -0
  98. package/runtime/xt_alloc.c +38 -0
  99. package/runtime/xt_builtins.c +192 -0
  100. package/runtime/xt_containers.c +225 -0
  101. package/runtime/xt_io.c +133 -0
  102. package/runtime/xt_stdlib.c +502 -0
  103. package/runtime/xt_values.c +291 -0
  104. package/scripts/build-runtime.mjs +8 -1
  105. package/src/ast/common.ts +210 -0
  106. package/src/ast/declarations.ts +130 -0
  107. package/src/ast/expressions.ts +275 -0
  108. package/src/ast/kinds.ts +176 -0
  109. package/src/ast/modules.ts +73 -0
  110. package/src/ast/nodes.ts +11 -1101
  111. package/src/ast/operators.ts +76 -0
  112. package/src/ast/statements.ts +148 -0
  113. package/src/ast/types.ts +173 -0
  114. package/src/codegen/generator/calls.ts +355 -0
  115. package/src/codegen/generator/context.ts +156 -0
  116. package/src/codegen/generator/expressions.ts +431 -0
  117. package/src/codegen/generator/generator.ts +35 -0
  118. package/src/codegen/generator/module.ts +139 -0
  119. package/src/codegen/generator/state.ts +126 -0
  120. package/src/codegen/generator/statements.ts +474 -0
  121. package/src/codegen/generator/tables.ts +171 -0
  122. package/src/codegen/llvm.ts +4 -1720
  123. package/src/driver/compiler.ts +17 -5
  124. package/src/lexer/char.ts +116 -0
  125. package/src/lexer/scanner.ts +9 -109
  126. package/src/parser/context.ts +196 -0
  127. package/src/parser/declarations.ts +502 -0
  128. package/src/parser/expressions.ts +465 -0
  129. package/src/parser/helpers.ts +42 -0
  130. package/src/parser/literals.ts +207 -0
  131. package/src/parser/modules.ts +194 -0
  132. package/src/parser/operators.ts +181 -0
  133. package/src/parser/parser.ts +35 -2373
  134. package/src/parser/speculation.ts +9 -0
  135. package/src/parser/statements.ts +457 -0
  136. package/src/parser/types.ts +365 -0
  137. package/runtime/xt_runtime.c +0 -1372
@@ -0,0 +1,502 @@
1
+ /**
2
+ * Declaration parsing: functions, classes, interfaces, type aliases, enums,
3
+ * namespaces and type members.
4
+ */
5
+
6
+ import { DiagnosticCode } from "../diagnostics/diagnostic.js";
7
+ import { TokenKind } from "../lexer/token.js";
8
+ import {
9
+ ModifierKind,
10
+ NodeFlags,
11
+ SyntaxKind,
12
+ type Block,
13
+ type ClassDeclaration,
14
+ type ClassElement,
15
+ type ConstructorDeclaration,
16
+ type EnumDeclaration,
17
+ type EnumMember,
18
+ type Expression,
19
+ type ExpressionWithTypeArguments,
20
+ type FunctionDeclaration,
21
+ type HeritageClause,
22
+ type Identifier,
23
+ type IndexSignature,
24
+ type InterfaceDeclaration,
25
+ type MethodDeclaration,
26
+ type MethodSignature,
27
+ type Modifier,
28
+ type ModuleDeclaration,
29
+ type Parameter,
30
+ type PropertyDeclaration,
31
+ type PropertyName,
32
+ type PropertySignature,
33
+ type StringLiteral,
34
+ type TypeAliasDeclaration,
35
+ type TypeElement,
36
+ type TypeNode,
37
+ type TypeParameterDeclaration,
38
+ } from "../ast/nodes.js";
39
+ import { expressionToPropertyName } from "./helpers.js";
40
+ import type { Parser } from "./parser.js";
41
+
42
+ export interface DeclarationMethods {
43
+ parseFunctionDeclaration(this: Parser, modifiers: Modifier[]): FunctionDeclaration;
44
+ parseTypeParameters(this: Parser): TypeParameterDeclaration[];
45
+ parseGreaterThan(this: Parser): void;
46
+ parseParameters(this: Parser): Parameter[];
47
+ parseReturnType(this: Parser): TypeNode;
48
+ parseClassDeclaration(this: Parser, modifiers: Modifier[]): ClassDeclaration;
49
+ parseHeritageClauses(this: Parser): HeritageClause[];
50
+ parseClassMembers(this: Parser): ClassElement[];
51
+ parseClassElement(this: Parser): ClassElement | undefined;
52
+ parsePropertyName(this: Parser): PropertyName;
53
+ parseInterfaceDeclaration(this: Parser, modifiers: Modifier[]): InterfaceDeclaration;
54
+ parseTypeAliasDeclaration(this: Parser, modifiers: Modifier[]): TypeAliasDeclaration;
55
+ parseEnumDeclaration(this: Parser, modifiers: Modifier[]): EnumDeclaration;
56
+ parseModuleDeclaration(this: Parser, modifiers: Modifier[]): ModuleDeclaration;
57
+ parseTypeMembers(this: Parser): TypeElement[];
58
+ parseTypeMember(this: Parser): TypeElement | undefined;
59
+ parseSemicolonOrComma(this: Parser): void;
60
+ }
61
+
62
+ export const declarationMethods: DeclarationMethods = {
63
+ // -- functions ------------------------------------------------------------
64
+
65
+ parseFunctionDeclaration(this: Parser, modifiers: Modifier[]): FunctionDeclaration {
66
+ const start = this.parseExpected(TokenKind.FunctionKeyword).start;
67
+ let flags = NodeFlags.None;
68
+ if (this.at(TokenKind.Asterisk)) {
69
+ this.nextToken();
70
+ flags |= NodeFlags.Generator;
71
+ }
72
+ if (this.hasModifier(modifiers, ModifierKind.Async)) flags |= NodeFlags.Async;
73
+ if (this.hasModifier(modifiers, ModifierKind.Declare)) flags |= NodeFlags.Declare;
74
+ let name: Identifier | undefined;
75
+ if (!this.at(TokenKind.OpenParen) && !this.at(TokenKind.LessThan)) name = this.parseIdentifier();
76
+ const typeParameters = this.parseTypeParameters();
77
+ const parameters = this.parseParameters();
78
+ let returnType: TypeNode | undefined;
79
+ if (this.at(TokenKind.Colon)) {
80
+ this.nextToken();
81
+ returnType = this.parseReturnType();
82
+ }
83
+ let body: Block | undefined;
84
+ if (this.at(TokenKind.OpenBrace)) body = this.parseBlock();
85
+ else this.parseSemicolon();
86
+ return {
87
+ kind: SyntaxKind.FunctionDeclaration,
88
+ name,
89
+ modifiers,
90
+ typeParameters,
91
+ parameters,
92
+ returnType,
93
+ body,
94
+ flags,
95
+ start,
96
+ end: body?.end ?? returnType?.end ?? parameters[parameters.length - 1]?.end ?? start,
97
+ };
98
+ },
99
+
100
+ parseTypeParameters(this: Parser): TypeParameterDeclaration[] {
101
+ if (!this.at(TokenKind.LessThan)) return [];
102
+ this.nextToken();
103
+ const params: TypeParameterDeclaration[] = [];
104
+ while (!this.at(TokenKind.GreaterThan) && !this.at(TokenKind.EndOfFile)) {
105
+ const name = this.parseIdentifier();
106
+ let constraint: TypeNode | undefined;
107
+ if (this.at(TokenKind.ExtendsKeyword)) {
108
+ this.nextToken();
109
+ constraint = this.parseType();
110
+ }
111
+ let defaultType: TypeNode | undefined;
112
+ if (this.at(TokenKind.Equals)) {
113
+ this.nextToken();
114
+ defaultType = this.parseType();
115
+ }
116
+ params.push({ kind: SyntaxKind.TypeParameterDeclaration, name, constraint, default: defaultType, start: name.start, end: defaultType?.end ?? constraint?.end ?? name.end });
117
+ if (this.at(TokenKind.Comma)) this.nextToken();
118
+ else break;
119
+ }
120
+ this.parseGreaterThan();
121
+ return params;
122
+ },
123
+
124
+ /** Consume a `>` that may have been lexed as `>>` / `>>>`, splitting it. */
125
+ parseGreaterThan(this: Parser): void {
126
+ const token = this.token;
127
+ if (token.kind === TokenKind.GreaterThan) {
128
+ this.nextToken();
129
+ return;
130
+ }
131
+ if (token.kind === TokenKind.GreaterThanGreaterThan || token.kind === TokenKind.GreaterThanGreaterThanGreaterThan) {
132
+ const extra = token.kind === TokenKind.GreaterThanGreaterThan ? 1 : 2;
133
+ this.tokens[this.index] = {
134
+ kind: extra === 1 ? TokenKind.GreaterThan : TokenKind.GreaterThanGreaterThan,
135
+ start: token.start + 1,
136
+ end: token.end,
137
+ text: token.text.slice(1),
138
+ precededByLineBreak: false,
139
+ };
140
+ return;
141
+ }
142
+ this.parseExpected(TokenKind.GreaterThan);
143
+ },
144
+
145
+ parseParameters(this: Parser): Parameter[] {
146
+ this.parseExpected(TokenKind.OpenParen);
147
+ const params: Parameter[] = [];
148
+ while (!this.at(TokenKind.CloseParen) && !this.at(TokenKind.EndOfFile)) {
149
+ const start = this.token.start;
150
+ const modifiers = this.tryParseModifiers();
151
+ let dotDotDotToken = false;
152
+ if (this.at(TokenKind.DotDotDot)) {
153
+ this.nextToken();
154
+ dotDotDotToken = true;
155
+ }
156
+ const name = this.parseIdentifier();
157
+ let questionToken = false;
158
+ if (this.at(TokenKind.Question)) {
159
+ this.nextToken();
160
+ questionToken = true;
161
+ }
162
+ let type: TypeNode | undefined;
163
+ if (this.at(TokenKind.Colon)) {
164
+ this.nextToken();
165
+ type = this.parseType();
166
+ }
167
+ let initializer: Expression | undefined;
168
+ if (this.at(TokenKind.Equals)) {
169
+ this.nextToken();
170
+ initializer = this.parseAssignmentExpression();
171
+ }
172
+ params.push({ kind: SyntaxKind.Parameter, name, modifiers, dotDotDotToken, questionToken, type, initializer, start, end: initializer?.end ?? type?.end ?? name.end });
173
+ if (this.at(TokenKind.Comma)) this.nextToken();
174
+ else break;
175
+ }
176
+ this.parseExpected(TokenKind.CloseParen);
177
+ return params;
178
+ },
179
+
180
+ parseReturnType(this: Parser): TypeNode {
181
+ if (this.at(TokenKind.AssertsKeyword)) {
182
+ const start = this.nextToken().start;
183
+ let paramName: Identifier | undefined;
184
+ if (this.isIdentifierLike(this.token) || this.at(TokenKind.ThisKeyword)) paramName = this.parseIdentifierName();
185
+ let predicateType: TypeNode | undefined;
186
+ if (this.at(TokenKind.IsKeyword)) {
187
+ this.nextToken();
188
+ predicateType = this.parseType();
189
+ }
190
+ const stub: Identifier = { kind: SyntaxKind.Identifier, text: paramName?.text ?? "this", start: paramName?.start ?? start, end: paramName?.end ?? start };
191
+ return { kind: SyntaxKind.TypePredicate, parameterName: stub, type: predicateType, start, end: predicateType?.end ?? start };
192
+ }
193
+ if (this.isIdentifierLike(this.token) && this.atAhead(1, TokenKind.IsKeyword)) {
194
+ const paramName = this.parseIdentifierName();
195
+ this.nextToken();
196
+ const predicateType = this.parseType();
197
+ return { kind: SyntaxKind.TypePredicate, parameterName: paramName, type: predicateType, start: paramName.start, end: predicateType.end };
198
+ }
199
+ return this.parseType();
200
+ },
201
+
202
+ // -- classes --------------------------------------------------------------
203
+
204
+ parseClassDeclaration(this: Parser, modifiers: Modifier[]): ClassDeclaration {
205
+ const start = this.parseExpected(TokenKind.ClassKeyword).start;
206
+ let name: Identifier | undefined;
207
+ if (!this.at(TokenKind.OpenBrace) && !this.at(TokenKind.ExtendsKeyword) && !this.at(TokenKind.ImplementsKeyword)) {
208
+ name = this.parseIdentifier();
209
+ }
210
+ const typeParameters = this.parseTypeParameters();
211
+ const heritage = this.parseHeritageClauses();
212
+ const members = this.parseClassMembers();
213
+ return { kind: SyntaxKind.ClassDeclaration, name, modifiers, typeParameters, heritage, members, start, end: members[members.length - 1]?.end ?? start };
214
+ },
215
+
216
+ parseHeritageClauses(this: Parser): HeritageClause[] {
217
+ const clauses: HeritageClause[] = [];
218
+ while (this.at(TokenKind.ExtendsKeyword) || this.at(TokenKind.ImplementsKeyword)) {
219
+ const token = this.nextToken();
220
+ const tokenKind: "extends" | "implements" = token.kind === TokenKind.ExtendsKeyword ? "extends" : "implements";
221
+ const types: ExpressionWithTypeArguments[] = [];
222
+ do {
223
+ const expression = this.parseLeftHandSideExpression();
224
+ const typeArguments = this.at(TokenKind.LessThan) ? this.parseTypeArguments() : [];
225
+ types.push({ kind: SyntaxKind.ExpressionWithTypeArguments, expression, typeArguments, start: expression.start, end: typeArguments[typeArguments.length - 1]?.end ?? expression.end });
226
+ } while (this.at(TokenKind.Comma) && this.nextToken());
227
+ clauses.push({ kind: SyntaxKind.HeritageClause, token: tokenKind, types, start: token.start, end: types[types.length - 1]?.end ?? token.end });
228
+ }
229
+ return clauses;
230
+ },
231
+
232
+ parseClassMembers(this: Parser): ClassElement[] {
233
+ this.parseExpected(TokenKind.OpenBrace);
234
+ const members: ClassElement[] = [];
235
+ while (!this.at(TokenKind.CloseBrace) && !this.at(TokenKind.EndOfFile)) {
236
+ const before = this.consumed;
237
+ const member = this.parseClassElement();
238
+ if (member) members.push(member);
239
+ if (this.consumed === before) this.nextToken();
240
+ }
241
+ this.parseExpected(TokenKind.CloseBrace);
242
+ return members;
243
+ },
244
+
245
+ parseClassElement(this: Parser): ClassElement | undefined {
246
+ const start = this.token.start;
247
+ const modifiers = this.tryParseModifiers();
248
+ if (this.at(TokenKind.Semicolon)) {
249
+ this.nextToken();
250
+ return undefined;
251
+ }
252
+ if (this.at(TokenKind.ConstructorKeyword)) {
253
+ const name = this.nextToken();
254
+ const parameters = this.parseParameters();
255
+ let body: Block | undefined;
256
+ if (this.at(TokenKind.OpenBrace)) body = this.parseBlock();
257
+ else this.parseSemicolon();
258
+ const ctor: ConstructorDeclaration = { kind: SyntaxKind.ConstructorDeclaration, modifiers, parameters, body, start, end: body?.end ?? name.end };
259
+ return ctor;
260
+ }
261
+ let flags = NodeFlags.None;
262
+ if (this.at(TokenKind.Asterisk)) {
263
+ this.nextToken();
264
+ flags |= NodeFlags.Generator;
265
+ }
266
+ if (this.hasModifier(modifiers, ModifierKind.Async)) flags |= NodeFlags.Async;
267
+ const name = this.parsePropertyName();
268
+ let questionToken = false;
269
+ let exclamationToken = false;
270
+ if (this.at(TokenKind.Question)) {
271
+ this.nextToken();
272
+ questionToken = true;
273
+ }
274
+ if (this.at(TokenKind.Exclamation)) {
275
+ this.nextToken();
276
+ exclamationToken = true;
277
+ }
278
+ const typeParameters = this.at(TokenKind.LessThan) ? this.parseTypeParameters() : [];
279
+ if (this.at(TokenKind.OpenParen)) {
280
+ const parameters = this.parseParameters();
281
+ let returnType: TypeNode | undefined;
282
+ if (this.at(TokenKind.Colon)) {
283
+ this.nextToken();
284
+ returnType = this.parseReturnType();
285
+ }
286
+ let body: Block | undefined;
287
+ if (this.at(TokenKind.OpenBrace)) body = this.parseBlock();
288
+ else this.parseSemicolon();
289
+ const method: MethodDeclaration = {
290
+ kind: SyntaxKind.MethodDeclaration,
291
+ name,
292
+ modifiers,
293
+ typeParameters,
294
+ parameters,
295
+ returnType,
296
+ body,
297
+ flags,
298
+ optional: questionToken,
299
+ start,
300
+ end: body?.end ?? returnType?.end ?? name.end,
301
+ };
302
+ return method;
303
+ }
304
+ let type: TypeNode | undefined;
305
+ if (this.at(TokenKind.Colon)) {
306
+ this.nextToken();
307
+ type = this.parseType();
308
+ }
309
+ let initializer: Expression | undefined;
310
+ if (this.at(TokenKind.Equals)) {
311
+ this.nextToken();
312
+ initializer = this.parseAssignmentExpression();
313
+ }
314
+ this.parseSemicolon();
315
+ const property: PropertyDeclaration = {
316
+ kind: SyntaxKind.PropertyDeclaration,
317
+ name,
318
+ modifiers,
319
+ questionToken,
320
+ exclamationToken,
321
+ type,
322
+ initializer,
323
+ start,
324
+ end: initializer?.end ?? type?.end ?? name.end,
325
+ };
326
+ return property;
327
+ },
328
+
329
+ parsePropertyName(this: Parser): PropertyName {
330
+ const token = this.token;
331
+ if (token.kind === TokenKind.StringLiteral) {
332
+ this.nextToken();
333
+ return { kind: SyntaxKind.StringLiteral, text: token.text, raw: token.text, value: String(token.value ?? ""), start: token.start, end: token.end };
334
+ }
335
+ if (token.kind === TokenKind.NumericLiteral) {
336
+ this.nextToken();
337
+ return { kind: SyntaxKind.NumericLiteral, text: token.text, value: Number(token.value ?? 0), start: token.start, end: token.end };
338
+ }
339
+ if (token.kind === TokenKind.OpenBracket) {
340
+ this.nextToken();
341
+ const expr = this.parseAssignmentExpression();
342
+ this.parseExpected(TokenKind.CloseBracket);
343
+ const name = expressionToPropertyName(expr);
344
+ if (name) return name;
345
+ this.error(DiagnosticCode.InvalidTypeSyntax, "Computed property names are not supported by xbintsc");
346
+ return { kind: SyntaxKind.Identifier, text: "<computed>", start: expr.start, end: expr.end };
347
+ }
348
+ return this.parseIdentifierName();
349
+ },
350
+
351
+ // -- interfaces / aliases / enums / namespaces ----------------------------
352
+
353
+ parseInterfaceDeclaration(this: Parser, modifiers: Modifier[]): InterfaceDeclaration {
354
+ const start = this.parseExpected(TokenKind.InterfaceKeyword).start;
355
+ const name = this.parseIdentifier();
356
+ const typeParameters = this.parseTypeParameters();
357
+ const heritage = this.parseHeritageClauses();
358
+ const members = this.parseTypeMembers();
359
+ return { kind: SyntaxKind.InterfaceDeclaration, name, modifiers, typeParameters, heritage, members, start, end: members[members.length - 1]?.end ?? name.end };
360
+ },
361
+
362
+ parseTypeAliasDeclaration(this: Parser, modifiers: Modifier[]): TypeAliasDeclaration {
363
+ const start = this.parseExpected(TokenKind.TypeKeyword).start;
364
+ const name = this.parseIdentifier();
365
+ const typeParameters = this.parseTypeParameters();
366
+ this.parseExpected(TokenKind.Equals);
367
+ const type = this.parseType();
368
+ this.parseSemicolon();
369
+ return { kind: SyntaxKind.TypeAliasDeclaration, name, modifiers, typeParameters, type, start, end: type.end };
370
+ },
371
+
372
+ parseEnumDeclaration(this: Parser, modifiers: Modifier[]): EnumDeclaration {
373
+ const start = this.parseExpected(TokenKind.EnumKeyword).start;
374
+ const name = this.parseIdentifier();
375
+ this.parseExpected(TokenKind.OpenBrace);
376
+ const members: EnumMember[] = [];
377
+ while (!this.at(TokenKind.CloseBrace) && !this.at(TokenKind.EndOfFile)) {
378
+ const memberName = this.parsePropertyName();
379
+ let initializer: Expression | undefined;
380
+ if (this.at(TokenKind.Equals)) {
381
+ this.nextToken();
382
+ initializer = this.parseAssignmentExpression();
383
+ }
384
+ members.push({ kind: SyntaxKind.EnumMember, name: memberName, initializer, start: memberName.start, end: initializer?.end ?? memberName.end });
385
+ if (this.at(TokenKind.Comma)) this.nextToken();
386
+ else break;
387
+ }
388
+ const close = this.parseExpected(TokenKind.CloseBrace);
389
+ return { kind: SyntaxKind.EnumDeclaration, name, modifiers, members, start, end: close.end };
390
+ },
391
+
392
+ parseModuleDeclaration(this: Parser, modifiers: Modifier[]): ModuleDeclaration {
393
+ const start = this.nextToken().start;
394
+ let name: Identifier | StringLiteral;
395
+ if (this.at(TokenKind.StringLiteral)) {
396
+ const token = this.nextToken();
397
+ name = { kind: SyntaxKind.StringLiteral, text: token.text, raw: token.text, value: String(token.value ?? ""), start: token.start, end: token.end };
398
+ } else {
399
+ name = this.parseIdentifierName();
400
+ }
401
+ while (this.at(TokenKind.Dot)) {
402
+ this.nextToken();
403
+ this.parseIdentifierName();
404
+ }
405
+ let body: Block | undefined;
406
+ if (this.at(TokenKind.OpenBrace)) body = this.parseBlock();
407
+ else this.parseSemicolon();
408
+ return { kind: SyntaxKind.ModuleDeclaration, name, modifiers, body, start, end: body?.end ?? name.end };
409
+ },
410
+
411
+ // -- type members ---------------------------------------------------------
412
+
413
+ parseTypeMembers(this: Parser): TypeElement[] {
414
+ this.parseExpected(TokenKind.OpenBrace);
415
+ const members: TypeElement[] = [];
416
+ while (!this.at(TokenKind.CloseBrace) && !this.at(TokenKind.EndOfFile)) {
417
+ const before = this.consumed;
418
+ const member = this.parseTypeMember();
419
+ if (member) members.push(member);
420
+ if (this.consumed === before) this.nextToken();
421
+ }
422
+ this.parseExpected(TokenKind.CloseBrace);
423
+ return members;
424
+ },
425
+
426
+ parseTypeMember(this: Parser): TypeElement | undefined {
427
+ const start = this.token.start;
428
+ const readonlyToken = this.at(TokenKind.ReadonlyKeyword);
429
+ if (readonlyToken) this.nextToken();
430
+ if (this.at(TokenKind.OpenParen) || this.at(TokenKind.LessThan)) {
431
+ const typeParameters = this.parseTypeParameters();
432
+ const parameters = this.parseParameters();
433
+ let returnType: TypeNode | undefined;
434
+ if (this.at(TokenKind.Colon)) {
435
+ this.nextToken();
436
+ returnType = this.parseType();
437
+ }
438
+ this.parseSemicolonOrComma();
439
+ const name: Identifier = { kind: SyntaxKind.Identifier, text: "__call", start, end: start };
440
+ return { kind: SyntaxKind.MethodSignature, name, questionToken: false, typeParameters, parameters, returnType, start, end: returnType?.end ?? start };
441
+ }
442
+ if (this.at(TokenKind.OpenBracket) && this.atAhead(1, TokenKind.Identifier)) {
443
+ const saveIndex = this.index;
444
+ const savePos = this.scanner.position;
445
+ const savedTokens = this.tokens.slice();
446
+ this.nextToken();
447
+ const parameters: Parameter[] = [];
448
+ let ok = true;
449
+ try {
450
+ const paramName = this.parseIdentifier();
451
+ let type: TypeNode | undefined;
452
+ if (this.at(TokenKind.Colon)) {
453
+ this.nextToken();
454
+ type = this.parseType();
455
+ } else ok = false;
456
+ this.parseExpected(TokenKind.CloseBracket);
457
+ parameters.push({ kind: SyntaxKind.Parameter, name: paramName, modifiers: [], dotDotDotToken: false, questionToken: false, type, start: paramName.start, end: type?.end ?? paramName.end });
458
+ } catch {
459
+ ok = false;
460
+ }
461
+ if (ok && this.at(TokenKind.Colon)) {
462
+ this.nextToken();
463
+ const type = this.parseType();
464
+ this.parseSemicolonOrComma();
465
+ return { kind: SyntaxKind.IndexSignature, parameters, type, start, end: type.end };
466
+ }
467
+ this.index = saveIndex;
468
+ this.tokens = savedTokens;
469
+ this.scanner.seek(savePos);
470
+ }
471
+ const name = this.parsePropertyName();
472
+ let questionToken = false;
473
+ if (this.at(TokenKind.Question)) {
474
+ this.nextToken();
475
+ questionToken = true;
476
+ }
477
+ const typeParameters = this.at(TokenKind.LessThan) ? this.parseTypeParameters() : [];
478
+ if (this.at(TokenKind.OpenParen) || typeParameters.length > 0) {
479
+ const parameters = this.parseParameters();
480
+ let returnType: TypeNode | undefined;
481
+ if (this.at(TokenKind.Colon)) {
482
+ this.nextToken();
483
+ returnType = this.parseType();
484
+ }
485
+ this.parseSemicolonOrComma();
486
+ const sig: MethodSignature = { kind: SyntaxKind.MethodSignature, name, questionToken, typeParameters, parameters, returnType, start, end: returnType?.end ?? name.end };
487
+ return sig;
488
+ }
489
+ let type: TypeNode | undefined;
490
+ if (this.at(TokenKind.Colon)) {
491
+ this.nextToken();
492
+ type = this.parseType();
493
+ }
494
+ this.parseSemicolonOrComma();
495
+ const signature: PropertySignature = { kind: SyntaxKind.PropertySignature, name, questionToken, readonlyToken, type, start, end: type?.end ?? name.end };
496
+ return signature;
497
+ },
498
+
499
+ parseSemicolonOrComma(this: Parser): void {
500
+ if (this.at(TokenKind.Semicolon) || this.at(TokenKind.Comma)) this.nextToken();
501
+ },
502
+ };