wesl 0.7.26 → 0.7.28
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 +1 -1
- package/dist/index.d.ts +283 -147
- package/dist/index.js +1765 -1143
- package/package.json +2 -2
- package/src/AbstractElems.ts +264 -82
- package/src/ClickableError.ts +8 -1
- package/src/Linker.ts +63 -67
- package/src/LinkerUtil.ts +141 -7
- package/src/LowerAndEmit.ts +660 -304
- package/src/Mangler.ts +1 -1
- package/src/ModuleResolver.ts +15 -4
- package/src/ParseWESL.ts +21 -33
- package/src/SrcMap.ts +7 -19
- package/src/StandardTypes.ts +1 -1
- package/src/WeslDevice.ts +1 -0
- package/src/debug/ASTtoString.ts +92 -76
- package/src/index.ts +1 -1
- package/src/parse/AttachComments.ts +289 -0
- package/src/parse/ExpressionUtil.ts +3 -3
- package/src/parse/Keywords.ts +1 -1
- package/src/parse/ParseAttribute.ts +49 -71
- package/src/parse/ParseCall.ts +3 -4
- package/src/parse/ParseControlFlow.ts +100 -56
- package/src/parse/ParseDirective.ts +9 -8
- package/src/parse/ParseDoBlock.ts +63 -0
- package/src/parse/ParseExpression.ts +11 -10
- package/src/parse/ParseFn.ts +11 -33
- package/src/parse/ParseGlobalVar.ts +36 -27
- package/src/parse/ParseIdent.ts +4 -5
- package/src/parse/ParseLocalVar.ts +16 -12
- package/src/parse/ParseLoop.ts +76 -39
- package/src/parse/ParseModule.ts +65 -19
- package/src/parse/ParseSimpleStatement.ts +112 -66
- package/src/parse/ParseStatement.ts +40 -67
- package/src/parse/ParseStruct.ts +8 -22
- package/src/parse/ParseType.ts +10 -13
- package/src/parse/ParseUtil.ts +26 -12
- package/src/parse/ParseValueDeclaration.ts +18 -31
- package/src/parse/ParseWesl.ts +11 -14
- package/src/parse/ParsingContext.ts +11 -9
- package/src/parse/WeslStream.ts +138 -121
- package/src/parse/stream/RegexMatchers.ts +45 -0
- package/src/parse/stream/WeslLexer.ts +249 -0
- package/src/test/BevyLink.test.ts +18 -11
- package/src/test/ConditionalElif.test.ts +4 -2
- package/src/test/DeclCommentEmit.test.ts +122 -0
- package/src/test/DoBlock.test.ts +164 -0
- package/src/test/FilterValidElements.test.ts +4 -6
- package/src/test/Linker.test.ts +23 -7
- package/src/test/Mangling.test.ts +8 -4
- package/src/test/ParseComments.test.ts +234 -6
- package/src/test/ParseConditionsV2.test.ts +47 -175
- package/src/test/ParseElifV2.test.ts +12 -33
- package/src/test/ParseErrorV2.test.ts +0 -0
- package/src/test/ParseWeslV2.test.ts +247 -626
- package/src/test/StatementEmit.test.ts +143 -0
- package/src/test/StripWesl.ts +24 -3
- package/src/test/TestLink.ts +19 -3
- package/src/test/TestUtil.ts +18 -8
- package/src/test/Tokenizer.test.ts +96 -0
- package/src/test/__snapshots__/ParseWeslV2.test.ts.snap +10 -42
- package/src/RawEmit.ts +0 -103
- package/src/Reflection.ts +0 -336
- package/src/TransformBindingStructs.ts +0 -320
- package/src/parse/ContentsHelpers.ts +0 -70
- package/src/parse/stream/CachingStream.ts +0 -48
- package/src/parse/stream/MatchersStream.ts +0 -85
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wesl",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"src"
|
|
8
8
|
],
|
|
9
|
-
"repository": "github:
|
|
9
|
+
"repository": "github:webgpu-tools/wesl-js",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
12
|
"types": "./dist/index.d.ts",
|
package/src/AbstractElems.ts
CHANGED
|
@@ -2,57 +2,65 @@ import type { DeclIdent, RefIdent, Scope, SrcModule } from "./Scope.ts";
|
|
|
2
2
|
import type { Span } from "./Span.ts";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* AST structures describing
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Uninteresting parts are 'TextElem' nodes, copied to output WGSL.
|
|
5
|
+
* AST structures describing WESL source. Each element holds its interesting
|
|
6
|
+
* parts as typed child fields (name, type, init, body, ...); emit walks those
|
|
7
|
+
* fields and reconstructs the surrounding WGSL syntax rather than copying spans.
|
|
9
8
|
*/
|
|
10
|
-
export type AbstractElem =
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
export type AbstractElem =
|
|
10
|
+
| GrammarElem
|
|
11
|
+
| SyntheticElem
|
|
12
|
+
| ExpressionElem
|
|
13
|
+
| UnknownExpressionElem;
|
|
13
14
|
|
|
14
|
-
export type
|
|
15
|
+
export type GrammarElem =
|
|
16
|
+
| ModuleElem
|
|
15
17
|
| AttributeElem
|
|
18
|
+
| Statement
|
|
19
|
+
| SwitchClauseElem
|
|
16
20
|
| AliasElem
|
|
17
|
-
| ConstAssertElem
|
|
18
|
-
| ConstElem
|
|
19
|
-
| ContinuingElem
|
|
20
|
-
| UnknownExpressionElem
|
|
21
|
-
| SimpleMemberRef
|
|
22
|
-
| FnElem
|
|
23
|
-
| TypedDeclElem
|
|
24
21
|
| GlobalVarElem
|
|
25
|
-
| LetElem
|
|
26
|
-
| ModuleElem
|
|
27
22
|
| OverrideElem
|
|
28
|
-
| FnParamElem
|
|
29
23
|
| StructElem
|
|
30
24
|
| StructMemberElem
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
25
|
+
| FnElem
|
|
26
|
+
| FnParamElem
|
|
27
|
+
| TypedDeclElem
|
|
28
|
+
| TerminalElem
|
|
29
|
+
| DoBlockElem;
|
|
36
30
|
|
|
37
31
|
/** Map from element kind string to element type, for type-safe element construction. */
|
|
38
32
|
export type ElemKindMap = {
|
|
39
33
|
alias: AliasElem;
|
|
40
34
|
assert: ConstAssertElem;
|
|
35
|
+
block: BlockElem;
|
|
41
36
|
const: ConstElem;
|
|
42
37
|
continuing: ContinuingElem;
|
|
38
|
+
if: IfElem;
|
|
39
|
+
for: ForElem;
|
|
40
|
+
while: WhileElem;
|
|
41
|
+
loop: LoopElem;
|
|
42
|
+
switch: SwitchElem;
|
|
43
|
+
return: ReturnElem;
|
|
44
|
+
break: BreakElem;
|
|
45
|
+
continue: ContinueElem;
|
|
46
|
+
discard: DiscardElem;
|
|
47
|
+
assign: AssignElem;
|
|
48
|
+
increment: IncrementElem;
|
|
49
|
+
decrement: DecrementElem;
|
|
50
|
+
call: CallElem;
|
|
51
|
+
empty: EmptyElem;
|
|
43
52
|
gvar: GlobalVarElem;
|
|
44
53
|
let: LetElem;
|
|
45
54
|
member: StructMemberElem;
|
|
46
55
|
override: OverrideElem;
|
|
47
56
|
param: FnParamElem;
|
|
48
|
-
statement: StatementElem;
|
|
49
57
|
struct: StructElem;
|
|
50
58
|
"switch-clause": SwitchClauseElem;
|
|
51
59
|
type: TypeRefElem;
|
|
52
60
|
var: VarElem;
|
|
53
61
|
};
|
|
54
62
|
|
|
55
|
-
/** Inspired by https://github.com/
|
|
63
|
+
/** Inspired by https://github.com/webgpu-tools/wesl-rs/blob/3b2434eac1b2ebda9eb8bfb25f43d8600d819872/crates/wgsl-parse/src/syntax.rs#L364 */
|
|
56
64
|
export type ExpressionElem =
|
|
57
65
|
| Literal
|
|
58
66
|
| RefIdentElem
|
|
@@ -69,12 +77,12 @@ export type TerminalElem =
|
|
|
69
77
|
| DeclIdentElem //
|
|
70
78
|
| NameElem
|
|
71
79
|
| RefIdentElem
|
|
72
|
-
| TextElem
|
|
73
80
|
| ImportElem;
|
|
74
81
|
|
|
75
82
|
export type GlobalDeclarationElem =
|
|
76
83
|
| AliasElem
|
|
77
84
|
| ConstElem
|
|
85
|
+
| DoBlockElem
|
|
78
86
|
| FnElem
|
|
79
87
|
| GlobalVarElem
|
|
80
88
|
| OverrideElem
|
|
@@ -92,10 +100,25 @@ export interface AbstractElemBase {
|
|
|
92
100
|
kind: AbstractElem["kind"];
|
|
93
101
|
start: number;
|
|
94
102
|
end: number;
|
|
103
|
+
/** Comments leading this element (on their own line above it). */
|
|
104
|
+
commentsBefore?: CommentElem[];
|
|
105
|
+
/** Comments trailing this element (on the same line after it). */
|
|
106
|
+
commentsAfter?: CommentElem[];
|
|
95
107
|
}
|
|
96
108
|
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
/**
|
|
110
|
+
* A source comment attached to an element as leading or trailing trivia.
|
|
111
|
+
* Not part of the {@link AbstractElem} union: comments are node metadata
|
|
112
|
+
* (in `commentsBefore` / `commentsAfter`), never `contents` children.
|
|
113
|
+
*/
|
|
114
|
+
export interface CommentElem {
|
|
115
|
+
kind: "comment";
|
|
116
|
+
style: "line" | "block";
|
|
117
|
+
start: number;
|
|
118
|
+
end: number;
|
|
119
|
+
srcModule: SrcModule;
|
|
120
|
+
/** Preserve one blank line above this comment (leading comments only). */
|
|
121
|
+
blankBefore?: boolean;
|
|
99
122
|
}
|
|
100
123
|
|
|
101
124
|
export interface HasAttributes {
|
|
@@ -104,12 +127,6 @@ export interface HasAttributes {
|
|
|
104
127
|
|
|
105
128
|
/* ------ Terminal Elements (don't contain other elements) ------ */
|
|
106
129
|
|
|
107
|
-
/** Raw text copied to linked WGSL (e.g., 'var' or '@diagnostic(off,derivative_uniformity)'). */
|
|
108
|
-
export interface TextElem extends AbstractElemBase {
|
|
109
|
-
kind: "text";
|
|
110
|
-
srcModule: SrcModule;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
130
|
/** A name that doesn't need to be an Ident (e.g., struct member, diagnostic rule). */
|
|
114
131
|
export interface NameElem extends AbstractElemBase {
|
|
115
132
|
kind: "name";
|
|
@@ -170,10 +187,10 @@ export interface SyntheticElem {
|
|
|
170
187
|
text: string;
|
|
171
188
|
}
|
|
172
189
|
|
|
173
|
-
/* ------
|
|
190
|
+
/* ------ Composite Elements (hold child elements in typed fields) ------ */
|
|
174
191
|
|
|
175
192
|
/** A declaration identifier with an optional type. */
|
|
176
|
-
export interface TypedDeclElem extends
|
|
193
|
+
export interface TypedDeclElem extends AbstractElemBase {
|
|
177
194
|
kind: "typeDecl";
|
|
178
195
|
decl: DeclIdentElem;
|
|
179
196
|
typeRef?: TypeRefElem; // LATER Consider a variant for fn params and alias where typeRef is required
|
|
@@ -181,14 +198,14 @@ export interface TypedDeclElem extends ElemWithContentsBase {
|
|
|
181
198
|
}
|
|
182
199
|
|
|
183
200
|
/** An alias statement. */
|
|
184
|
-
export interface AliasElem extends
|
|
201
|
+
export interface AliasElem extends AbstractElemBase, HasAttributes {
|
|
185
202
|
kind: "alias";
|
|
186
203
|
name: DeclIdentElem;
|
|
187
204
|
typeRef: TypeRefElem;
|
|
188
205
|
}
|
|
189
206
|
|
|
190
207
|
/** An attribute like '@compute' or '@binding(0)'. */
|
|
191
|
-
export interface AttributeElem extends
|
|
208
|
+
export interface AttributeElem extends AbstractElemBase {
|
|
192
209
|
kind: "attribute";
|
|
193
210
|
attribute: Attribute;
|
|
194
211
|
}
|
|
@@ -243,26 +260,30 @@ export interface ElseAttribute {
|
|
|
243
260
|
export type ConditionalAttribute = IfAttribute | ElifAttribute | ElseAttribute;
|
|
244
261
|
|
|
245
262
|
/** A const_assert statement. */
|
|
246
|
-
export interface ConstAssertElem extends
|
|
263
|
+
export interface ConstAssertElem extends AbstractElemBase, HasAttributes {
|
|
247
264
|
kind: "assert";
|
|
265
|
+
expression: ExpressionElem;
|
|
248
266
|
}
|
|
249
267
|
|
|
250
268
|
/** A const declaration. */
|
|
251
|
-
export interface ConstElem extends
|
|
269
|
+
export interface ConstElem extends AbstractElemBase, HasAttributes {
|
|
252
270
|
kind: "const";
|
|
253
271
|
name: TypedDeclElem;
|
|
272
|
+
init?: ExpressionElem;
|
|
254
273
|
}
|
|
255
274
|
|
|
256
275
|
/** An expression without special handling, used in attribute parameters. */
|
|
257
|
-
export interface UnknownExpressionElem extends
|
|
276
|
+
export interface UnknownExpressionElem extends AbstractElemBase {
|
|
258
277
|
kind: "expression";
|
|
278
|
+
expression: ExpressionElem;
|
|
259
279
|
}
|
|
260
280
|
|
|
261
281
|
/** An expression that can be safely evaluated at compile time. */
|
|
262
282
|
export interface TranslateTimeExpressionElem {
|
|
263
283
|
kind: "translate-time-expression";
|
|
264
284
|
expression: ExpressionElem;
|
|
265
|
-
|
|
285
|
+
start: number;
|
|
286
|
+
end: number;
|
|
266
287
|
}
|
|
267
288
|
|
|
268
289
|
/** A literal value (boolean or number) in WESL source. */
|
|
@@ -310,15 +331,23 @@ export interface BinaryExpression extends AbstractElemBase {
|
|
|
310
331
|
export interface FunctionCallExpression extends AbstractElemBase {
|
|
311
332
|
kind: "call-expression";
|
|
312
333
|
function: RefIdentElem | TypeRefElem; // template_elaborated_ident
|
|
334
|
+
/** Only populated for function calls; constructor calls carry templates on `function`. */
|
|
313
335
|
templateArgs?: TypeTemplateParameter[];
|
|
314
336
|
arguments: ExpressionElem[];
|
|
315
337
|
}
|
|
316
338
|
|
|
317
339
|
export interface UnaryOperator {
|
|
318
340
|
value: "!" | "&" | "*" | "-" | "~";
|
|
319
|
-
|
|
341
|
+
start: number;
|
|
342
|
+
end: number;
|
|
320
343
|
}
|
|
321
344
|
|
|
345
|
+
/** Uses span (not inline start/end) so each operator object stays in a smaller
|
|
346
|
+
* V8 size class. Inline start/end uses slightly less memory overall (no separate
|
|
347
|
+
* span tuple) but each object is bigger and more likely to be promoted to old
|
|
348
|
+
* gen under sustained allocation pressure, triggering more major GCs and
|
|
349
|
+
* ~5% slower wall time on math-heavy parse workloads (bevy_env_map/parse).
|
|
350
|
+
* A rare case where allocating more bytes wins on GC. */
|
|
322
351
|
export interface BinaryOperator {
|
|
323
352
|
value:
|
|
324
353
|
| ("||" | "&&" | "+" | "-" | "*" | "/" | "%" | "==")
|
|
@@ -353,106 +382,259 @@ export interface RequiresDirective {
|
|
|
353
382
|
extensions: NameElem[];
|
|
354
383
|
}
|
|
355
384
|
|
|
385
|
+
/**
|
|
386
|
+
* A `do` block: a CPU-side dispatch script (`do name(params) { ... }`).
|
|
387
|
+
*
|
|
388
|
+
* Module-local: its name and body idents never enter bindIdents/the scope
|
|
389
|
+
* tree, and the linker drops it entirely from emitted WGSL. The parsed body
|
|
390
|
+
* is retained for the interpreter, which resolves names by AST match.
|
|
391
|
+
*/
|
|
392
|
+
export interface DoBlockElem extends AbstractElemBase, HasAttributes {
|
|
393
|
+
kind: "do";
|
|
394
|
+
name: NameElem;
|
|
395
|
+
params: FnParamElem[];
|
|
396
|
+
body: BlockElem;
|
|
397
|
+
}
|
|
398
|
+
|
|
356
399
|
/** A function declaration. */
|
|
357
|
-
export interface FnElem extends
|
|
358
|
-
// LATER doesn't need contents
|
|
400
|
+
export interface FnElem extends AbstractElemBase, HasAttributes {
|
|
359
401
|
kind: "fn";
|
|
360
402
|
name: DeclIdentElem;
|
|
361
403
|
params: FnParamElem[];
|
|
362
|
-
body:
|
|
404
|
+
body: BlockElem;
|
|
363
405
|
returnAttributes?: AttributeElem[];
|
|
364
406
|
returnType?: TypeRefElem;
|
|
365
407
|
}
|
|
366
408
|
|
|
367
409
|
/** A global variable declaration (at the root level). */
|
|
368
|
-
export interface GlobalVarElem extends
|
|
410
|
+
export interface GlobalVarElem extends AbstractElemBase, HasAttributes {
|
|
369
411
|
kind: "gvar";
|
|
370
412
|
name: TypedDeclElem;
|
|
413
|
+
/** Address-space / access-mode enumerants, e.g. `<storage, read_write>`. */
|
|
414
|
+
template?: NameElem[];
|
|
415
|
+
init?: ExpressionElem;
|
|
371
416
|
}
|
|
372
417
|
|
|
373
418
|
/** An entire file. */
|
|
374
|
-
export interface ModuleElem extends
|
|
419
|
+
export interface ModuleElem extends AbstractElemBase {
|
|
375
420
|
kind: "module";
|
|
421
|
+
/** Top-level children (imports, directives, declarations, and any synthetic
|
|
422
|
+
* vars added by transforms) in source order. */
|
|
423
|
+
decls: AbstractElem[];
|
|
376
424
|
}
|
|
377
425
|
|
|
378
426
|
/** An override declaration. */
|
|
379
|
-
export interface OverrideElem extends
|
|
427
|
+
export interface OverrideElem extends AbstractElemBase, HasAttributes {
|
|
380
428
|
kind: "override";
|
|
381
429
|
name: TypedDeclElem;
|
|
430
|
+
init?: ExpressionElem;
|
|
382
431
|
}
|
|
383
432
|
|
|
384
433
|
/** A parameter in a function declaration. */
|
|
385
|
-
export interface FnParamElem extends
|
|
434
|
+
export interface FnParamElem extends AbstractElemBase, HasAttributes {
|
|
386
435
|
kind: "param";
|
|
387
436
|
name: TypedDeclElem;
|
|
388
437
|
}
|
|
389
438
|
|
|
390
|
-
/** Simple struct references like `myStruct.bar` (for binding struct transforms). */
|
|
391
|
-
export interface SimpleMemberRef extends ElemWithContentsBase {
|
|
392
|
-
kind: "memberRef";
|
|
393
|
-
name: RefIdentElem;
|
|
394
|
-
member: NameElem;
|
|
395
|
-
extraComponents?: StuffElem;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
439
|
/** A struct declaration. */
|
|
399
|
-
export interface StructElem extends
|
|
440
|
+
export interface StructElem extends AbstractElemBase, HasAttributes {
|
|
400
441
|
kind: "struct";
|
|
401
442
|
name: DeclIdentElem;
|
|
402
443
|
members: StructMemberElem[];
|
|
403
|
-
bindingStruct?: true; // used later during binding struct transformation
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/** Generic container of other elements. */
|
|
407
|
-
export interface StuffElem extends ElemWithContentsBase {
|
|
408
|
-
kind: "stuff";
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/** A struct declaration marked as a binding struct. */
|
|
412
|
-
export interface BindingStructElem extends StructElem {
|
|
413
|
-
bindingStruct: true;
|
|
414
|
-
entryFn?: FnElem;
|
|
415
444
|
}
|
|
416
445
|
|
|
417
446
|
/** A member of a struct declaration. */
|
|
418
|
-
export interface StructMemberElem extends
|
|
447
|
+
export interface StructMemberElem extends AbstractElemBase, HasAttributes {
|
|
419
448
|
kind: "member";
|
|
420
449
|
name: NameElem;
|
|
421
450
|
typeRef: TypeRefElem;
|
|
422
|
-
mangledVarName?: string; // root name if transformed to a var (for binding struct transformation)
|
|
423
451
|
}
|
|
424
452
|
|
|
425
453
|
export type TypeTemplateParameter = ExpressionElem;
|
|
426
454
|
|
|
427
455
|
/** A type reference like 'f32', 'MyStruct', or 'ptr<storage, array<f32>, read_only>'. */
|
|
428
|
-
export interface TypeRefElem extends
|
|
456
|
+
export interface TypeRefElem extends AbstractElemBase {
|
|
429
457
|
kind: "type";
|
|
430
458
|
name: RefIdent;
|
|
431
459
|
templateParams?: TypeTemplateParameter[];
|
|
432
460
|
}
|
|
433
461
|
|
|
434
462
|
/** A variable declaration. */
|
|
435
|
-
export interface VarElem extends
|
|
463
|
+
export interface VarElem extends AbstractElemBase, HasAttributes {
|
|
436
464
|
kind: "var";
|
|
437
465
|
name: TypedDeclElem;
|
|
466
|
+
/** Address-space / access-mode enumerants, e.g. `<storage, read_write>`. */
|
|
467
|
+
template?: NameElem[];
|
|
468
|
+
init?: ExpressionElem;
|
|
438
469
|
}
|
|
439
470
|
|
|
440
|
-
export interface LetElem extends
|
|
471
|
+
export interface LetElem extends AbstractElemBase, HasAttributes {
|
|
441
472
|
kind: "let";
|
|
442
473
|
name: TypedDeclElem;
|
|
474
|
+
init?: ExpressionElem;
|
|
443
475
|
}
|
|
444
476
|
|
|
445
|
-
|
|
446
|
-
|
|
477
|
+
/* ------ Statement Elements ------ */
|
|
478
|
+
|
|
479
|
+
/** Any WGSL statement inside a function or block body. */
|
|
480
|
+
export type Statement =
|
|
481
|
+
| BlockElem
|
|
482
|
+
| IfElem
|
|
483
|
+
| ForElem
|
|
484
|
+
| WhileElem
|
|
485
|
+
| LoopElem
|
|
486
|
+
| ContinuingElem
|
|
487
|
+
| SwitchElem
|
|
488
|
+
| ReturnElem
|
|
489
|
+
| BreakElem
|
|
490
|
+
| ContinueElem
|
|
491
|
+
| DiscardElem
|
|
492
|
+
| AssignElem
|
|
493
|
+
| IncrementElem
|
|
494
|
+
| DecrementElem
|
|
495
|
+
| CallElem
|
|
496
|
+
| ConstAssertElem
|
|
497
|
+
| EmptyElem
|
|
498
|
+
| VarElem
|
|
499
|
+
| LetElem
|
|
500
|
+
| ConstElem;
|
|
501
|
+
|
|
502
|
+
/** A bare `;` statement. Emits nothing, but kept in the AST as a statement node. */
|
|
503
|
+
export interface EmptyElem extends AbstractElemBase, HasAttributes {
|
|
504
|
+
kind: "empty";
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** A `{ ... }` compound statement. */
|
|
508
|
+
export interface BlockElem extends AbstractElemBase, HasAttributes {
|
|
509
|
+
kind: "block";
|
|
510
|
+
body: Statement[];
|
|
511
|
+
/** Comments inside an otherwise empty block, with no statement to attach to. */
|
|
512
|
+
innerComments?: CommentElem[];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** An if / else-if / else chain. `else` nests: else-if is an IfElem, plain else a BlockElem. */
|
|
516
|
+
export interface IfElem extends AbstractElemBase, HasAttributes {
|
|
517
|
+
kind: "if";
|
|
518
|
+
condition: ExpressionElem;
|
|
519
|
+
body: BlockElem;
|
|
520
|
+
else?: IfElem | BlockElem;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/** A for loop. */
|
|
524
|
+
export interface ForElem extends AbstractElemBase, HasAttributes {
|
|
525
|
+
kind: "for";
|
|
526
|
+
init?: ForInit;
|
|
527
|
+
condition?: ExpressionElem;
|
|
528
|
+
update?: ForUpdate;
|
|
529
|
+
body: BlockElem;
|
|
447
530
|
}
|
|
448
531
|
|
|
449
|
-
export
|
|
532
|
+
export type ForInit =
|
|
533
|
+
| VarElem
|
|
534
|
+
| LetElem
|
|
535
|
+
| ConstElem
|
|
536
|
+
| AssignElem
|
|
537
|
+
| IncrementElem
|
|
538
|
+
| DecrementElem
|
|
539
|
+
| CallElem;
|
|
540
|
+
export type ForUpdate = AssignElem | IncrementElem | DecrementElem | CallElem;
|
|
541
|
+
|
|
542
|
+
/** A while loop. */
|
|
543
|
+
export interface WhileElem extends AbstractElemBase, HasAttributes {
|
|
544
|
+
kind: "while";
|
|
545
|
+
condition: ExpressionElem;
|
|
546
|
+
body: BlockElem;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/** A loop, optionally ending with a continuing block. */
|
|
550
|
+
export interface LoopElem extends AbstractElemBase, HasAttributes {
|
|
551
|
+
kind: "loop";
|
|
552
|
+
body: BlockElem;
|
|
553
|
+
continuing?: ContinuingElem;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/** A continuing block, optionally ending with `break if expr`. */
|
|
557
|
+
export interface ContinuingElem extends AbstractElemBase, HasAttributes {
|
|
450
558
|
kind: "continuing";
|
|
559
|
+
body: BlockElem;
|
|
560
|
+
breakIf?: ExpressionElem;
|
|
451
561
|
}
|
|
452
562
|
|
|
453
|
-
/**
|
|
454
|
-
export
|
|
563
|
+
/** A switch statement. */
|
|
564
|
+
export interface SwitchElem extends AbstractElemBase, HasAttributes {
|
|
565
|
+
kind: "switch";
|
|
566
|
+
selector: ExpressionElem;
|
|
567
|
+
clauses: SwitchClauseElem[];
|
|
568
|
+
/** Attributes on the switch body, between the selector and `{`. */
|
|
569
|
+
bodyAttributes?: AttributeElem[];
|
|
570
|
+
}
|
|
455
571
|
|
|
456
|
-
|
|
572
|
+
/** A case or default clause. `"default"` sentinel marks the default selector. */
|
|
573
|
+
export interface SwitchClauseElem extends AbstractElemBase, HasAttributes {
|
|
457
574
|
kind: "switch-clause";
|
|
575
|
+
selectors: (ExpressionElem | "default")[];
|
|
576
|
+
body: BlockElem;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/** A return statement, with an optional value. */
|
|
580
|
+
export interface ReturnElem extends AbstractElemBase, HasAttributes {
|
|
581
|
+
kind: "return";
|
|
582
|
+
value?: ExpressionElem;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/** A break statement, or `break if expr`. */
|
|
586
|
+
export interface BreakElem extends AbstractElemBase, HasAttributes {
|
|
587
|
+
kind: "break";
|
|
588
|
+
condition?: ExpressionElem;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** A continue statement. */
|
|
592
|
+
export interface ContinueElem extends AbstractElemBase, HasAttributes {
|
|
593
|
+
kind: "continue";
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/** A discard statement. */
|
|
597
|
+
export interface DiscardElem extends AbstractElemBase, HasAttributes {
|
|
598
|
+
kind: "discard";
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/** Assignment, compound assignment, or phony `_ = expr`. */
|
|
602
|
+
export interface AssignElem extends AbstractElemBase, HasAttributes {
|
|
603
|
+
kind: "assign";
|
|
604
|
+
lhs: ExpressionElem | PhonyTarget;
|
|
605
|
+
op: AssignOp;
|
|
606
|
+
rhs: ExpressionElem;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/** `i++` */
|
|
610
|
+
export interface IncrementElem extends AbstractElemBase, HasAttributes {
|
|
611
|
+
kind: "increment";
|
|
612
|
+
target: ExpressionElem;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/** `i--` */
|
|
616
|
+
export interface DecrementElem extends AbstractElemBase, HasAttributes {
|
|
617
|
+
kind: "decrement";
|
|
618
|
+
target: ExpressionElem;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/** A bare function call statement. */
|
|
622
|
+
export interface CallElem extends AbstractElemBase, HasAttributes {
|
|
623
|
+
kind: "call";
|
|
624
|
+
call: FunctionCallExpression;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/** The `_` discard target of a phony assignment; never enters the ident system. */
|
|
628
|
+
export interface PhonyTarget {
|
|
629
|
+
kind: "phony";
|
|
630
|
+
span: Span;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/** An assignment operator. Uses a span tuple (not inline start/end) to match
|
|
634
|
+
* BinaryOperator's smaller V8 size class; see the note there. */
|
|
635
|
+
export interface AssignOp {
|
|
636
|
+
value:
|
|
637
|
+
| ("=" | "+=" | "-=" | "*=" | "/=" | "%=")
|
|
638
|
+
| ("&=" | "|=" | "^=" | "<<=" | ">>=");
|
|
639
|
+
span: Span;
|
|
458
640
|
}
|
package/src/ClickableError.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface WeslErrorLocation {
|
|
|
9
9
|
line: number;
|
|
10
10
|
column: number;
|
|
11
11
|
length: number;
|
|
12
|
+
/** byte offset into the source file */
|
|
13
|
+
offset: number;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface ClickableErrorParams {
|
|
@@ -27,6 +29,9 @@ export interface ClickableErrorParams {
|
|
|
27
29
|
/** number of characters in the error section */
|
|
28
30
|
length: number;
|
|
29
31
|
|
|
32
|
+
/** byte offset of the error section within the source text */
|
|
33
|
+
offset: number;
|
|
34
|
+
|
|
30
35
|
/** the original error */
|
|
31
36
|
error: Error;
|
|
32
37
|
}
|
|
@@ -36,12 +41,13 @@ const isBrowser = "document" in globalThis;
|
|
|
36
41
|
/** Throw an error with an embedded source map so that browser users can
|
|
37
42
|
* click on the error in the browser debug console and see the wesl source code. */
|
|
38
43
|
export function throwClickableError(params: ClickableErrorParams): void {
|
|
39
|
-
const { url, text, lineNumber, lineColumn, length, error } = params;
|
|
44
|
+
const { url, text, lineNumber, lineColumn, length, offset, error } = params;
|
|
40
45
|
const weslLocation: WeslErrorLocation = {
|
|
41
46
|
file: url,
|
|
42
47
|
line: lineNumber,
|
|
43
48
|
column: lineColumn,
|
|
44
49
|
length,
|
|
50
|
+
offset,
|
|
45
51
|
};
|
|
46
52
|
(error as any).weslLocation = weslLocation;
|
|
47
53
|
if (!debug || !isBrowser) throw error;
|
|
@@ -142,6 +148,7 @@ export function failIdentElem(
|
|
|
142
148
|
lineNumber,
|
|
143
149
|
lineColumn,
|
|
144
150
|
length,
|
|
151
|
+
offset: start,
|
|
145
152
|
error: new Error(detailedMessage),
|
|
146
153
|
});
|
|
147
154
|
}
|