@luma.gl/shadertools 9.0.15 → 9.0.17

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 (67) hide show
  1. package/dist/dist.dev.js +787 -195
  2. package/dist/dist.min.js +79 -79
  3. package/dist/index.cjs +18 -2854
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/lib/shader-module/shader-module.d.ts +22 -13
  6. package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
  7. package/dist/lib/shader-module/shader-pass.d.ts +4 -2
  8. package/dist/lib/shader-module/shader-pass.d.ts.map +1 -1
  9. package/dist/lib/utils/uniform-types.d.ts +49 -0
  10. package/dist/lib/utils/uniform-types.d.ts.map +1 -0
  11. package/dist/lib/utils/uniform-types.js +1 -0
  12. package/dist/lib/wgsl/get-shader-layout-wgsl.js +5 -5
  13. package/dist/modules/engine/picking/picking.d.ts +5 -5
  14. package/dist/modules/engine/picking/picking.d.ts.map +1 -1
  15. package/dist/modules/engine/picking/picking.js +2 -2
  16. package/dist/modules/engine/project/project.d.ts +9 -8
  17. package/dist/modules/engine/project/project.d.ts.map +1 -1
  18. package/dist/modules/lighting/lights/lighting-uniforms.d.ts +13 -13
  19. package/dist/modules/lighting/lights/lighting-uniforms.d.ts.map +1 -1
  20. package/dist/modules/lighting/no-material/dirlight.d.ts +2 -2
  21. package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
  22. package/dist/modules/lighting/no-material/dirlight.js +1 -1
  23. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +14 -13
  24. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  25. package/dist/modules/lighting/pbr-material/pbr-material.js +0 -11
  26. package/dist/modules/postprocessing/image-blur-filters/tiltshift.d.ts +2 -2
  27. package/dist/modules/postprocessing/image-blur-filters/tiltshift.d.ts.map +1 -1
  28. package/dist/modules/postprocessing/image-blur-filters/triangleblur.d.ts +1 -1
  29. package/dist/modules/postprocessing/image-blur-filters/triangleblur.d.ts.map +1 -1
  30. package/dist/modules/postprocessing/image-blur-filters/zoomblur.d.ts +1 -1
  31. package/dist/modules/postprocessing/image-blur-filters/zoomblur.d.ts.map +1 -1
  32. package/dist/modules/postprocessing/image-fun-filters/colorhalftone.d.ts +1 -1
  33. package/dist/modules/postprocessing/image-fun-filters/colorhalftone.d.ts.map +1 -1
  34. package/dist/modules/postprocessing/image-fun-filters/dotscreen.d.ts +1 -1
  35. package/dist/modules/postprocessing/image-fun-filters/dotscreen.d.ts.map +1 -1
  36. package/dist/modules/postprocessing/image-fun-filters/hexagonalpixelate.d.ts +1 -1
  37. package/dist/modules/postprocessing/image-fun-filters/hexagonalpixelate.d.ts.map +1 -1
  38. package/dist/modules/postprocessing/image-fun-filters/magnify.d.ts +2 -2
  39. package/dist/modules/postprocessing/image-fun-filters/magnify.d.ts.map +1 -1
  40. package/dist/modules/postprocessing/image-warp-filters/bulgepinch.d.ts +1 -1
  41. package/dist/modules/postprocessing/image-warp-filters/bulgepinch.d.ts.map +1 -1
  42. package/dist/modules-webgl1/project/project.d.ts +6 -4
  43. package/dist/modules-webgl1/project/project.d.ts.map +1 -1
  44. package/package.json +4 -3
  45. package/src/lib/shader-module/shader-module.ts +24 -12
  46. package/src/lib/shader-module/shader-pass.ts +7 -4
  47. package/src/lib/utils/uniform-types.ts +91 -0
  48. package/src/lib/wgsl/get-shader-layout-wgsl.ts +5 -5
  49. package/src/modules/engine/picking/picking.ts +9 -9
  50. package/src/modules/engine/project/project.ts +10 -9
  51. package/src/modules/lighting/lights/lighting-uniforms.ts +16 -16
  52. package/src/modules/lighting/no-material/dirlight.ts +3 -3
  53. package/src/modules/lighting/pbr-material/pbr-material.ts +14 -24
  54. package/src/modules/postprocessing/image-blur-filters/tiltshift.ts +2 -2
  55. package/src/modules/postprocessing/image-blur-filters/triangleblur.ts +1 -1
  56. package/src/modules/postprocessing/image-blur-filters/zoomblur.ts +1 -1
  57. package/src/modules/postprocessing/image-fun-filters/colorhalftone.ts +1 -1
  58. package/src/modules/postprocessing/image-fun-filters/dotscreen.ts +1 -1
  59. package/src/modules/postprocessing/image-fun-filters/hexagonalpixelate.ts +1 -1
  60. package/src/modules/postprocessing/image-fun-filters/magnify.ts +2 -2
  61. package/src/modules/postprocessing/image-warp-filters/bulgepinch.ts +1 -1
  62. package/src/modules-webgl1/project/project.ts +8 -7
  63. package/dist/libs/wgsl-reflect/wgsl_reflect.module.d.ts +0 -1112
  64. package/dist/libs/wgsl-reflect/wgsl_reflect.module.d.ts.map +0 -1
  65. package/dist/libs/wgsl-reflect/wgsl_reflect.module.js +0 -3389
  66. package/src/libs/wgsl-reflect/wgsl_reflect.module.js +0 -3394
  67. package/src/libs/wgsl-reflect/wgsl_reflect.module.js.map +0 -1
@@ -1,3394 +0,0 @@
1
- // This file is copied from Brendan Duncan's https://github.com/brendan-duncan/wgsl_reflect
2
- // under MIT license.
3
- // @ts-nocheck
4
- /* eslint-disable */
5
-
6
- class ParseContext {
7
- constructor() {
8
- this.constants = new Map();
9
- this.aliases = new Map();
10
- this.structs = new Map();
11
- }
12
- }
13
- /**
14
- * @class Node
15
- * @category AST
16
- * Base class for AST nodes parsed from a WGSL shader.
17
- */
18
- class Node {
19
- constructor() { }
20
- get isAstNode() {
21
- return true;
22
- }
23
- get astNodeType() {
24
- return "";
25
- }
26
- evaluate(context) {
27
- throw new Error("Cannot evaluate node");
28
- }
29
- evaluateString(context) {
30
- return this.evaluate(context).toString();
31
- }
32
- }
33
- /**
34
- * @class Statement
35
- * @extends Node
36
- * @category AST
37
- */
38
- class Statement extends Node {
39
- constructor() {
40
- super();
41
- }
42
- }
43
- /**
44
- * @class Function
45
- * @extends Statement
46
- * @category AST
47
- */
48
- class Function extends Statement {
49
- constructor(name, args, returnType, body) {
50
- super();
51
- this.name = name;
52
- this.args = args;
53
- this.returnType = returnType;
54
- this.body = body;
55
- }
56
- get astNodeType() {
57
- return "function";
58
- }
59
- }
60
- /**
61
- * @class StaticAssert
62
- * @extends Statement
63
- * @category AST
64
- */
65
- class StaticAssert extends Statement {
66
- constructor(expression) {
67
- super();
68
- this.expression = expression;
69
- }
70
- get astNodeType() {
71
- return "staticAssert";
72
- }
73
- }
74
- /**
75
- * @class While
76
- * @extends Statement
77
- * @category AST
78
- */
79
- class While extends Statement {
80
- constructor(condition, body) {
81
- super();
82
- this.condition = condition;
83
- this.body = body;
84
- }
85
- get astNodeType() {
86
- return "while";
87
- }
88
- }
89
- /**
90
- * @class Continuing
91
- * @extends Statement
92
- * @category AST
93
- */
94
- class Continuing extends Statement {
95
- constructor(body) {
96
- super();
97
- this.body = body;
98
- }
99
- get astNodeType() {
100
- return "continuing";
101
- }
102
- }
103
- /**
104
- * @class For
105
- * @extends Statement
106
- * @category AST
107
- */
108
- class For extends Statement {
109
- constructor(init, condition, increment, body) {
110
- super();
111
- this.init = init;
112
- this.condition = condition;
113
- this.increment = increment;
114
- this.body = body;
115
- }
116
- get astNodeType() {
117
- return "for";
118
- }
119
- }
120
- /**
121
- * @class Var
122
- * @extends Statement
123
- * @category AST
124
- */
125
- class Var extends Statement {
126
- constructor(name, type, storage, access, value) {
127
- super();
128
- this.name = name;
129
- this.type = type;
130
- this.storage = storage;
131
- this.access = access;
132
- this.value = value;
133
- }
134
- get astNodeType() {
135
- return "var";
136
- }
137
- }
138
- /**
139
- * @class Override
140
- * @extends Statement
141
- * @category AST
142
- */
143
- class Override extends Statement {
144
- constructor(name, type, value) {
145
- super();
146
- this.name = name;
147
- this.type = type;
148
- this.value = value;
149
- }
150
- get astNodeType() {
151
- return "override";
152
- }
153
- }
154
- /**
155
- * @class Let
156
- * @extends Statement
157
- * @category AST
158
- */
159
- class Let extends Statement {
160
- constructor(name, type, storage, access, value) {
161
- super();
162
- this.name = name;
163
- this.type = type;
164
- this.storage = storage;
165
- this.access = access;
166
- this.value = value;
167
- }
168
- get astNodeType() {
169
- return "let";
170
- }
171
- }
172
- /**
173
- * @class Const
174
- * @extends Statement
175
- * @category AST
176
- */
177
- class Const extends Statement {
178
- constructor(name, type, storage, access, value) {
179
- super();
180
- this.name = name;
181
- this.type = type;
182
- this.storage = storage;
183
- this.access = access;
184
- this.value = value;
185
- }
186
- get astNodeType() {
187
- return "const";
188
- }
189
- evaluate(context) {
190
- return this.value.evaluate(context);
191
- }
192
- }
193
- var IncrementOperator;
194
- (function (IncrementOperator) {
195
- IncrementOperator["increment"] = "++";
196
- IncrementOperator["decrement"] = "--";
197
- })(IncrementOperator || (IncrementOperator = {}));
198
- (function (IncrementOperator) {
199
- function parse(val) {
200
- const key = val;
201
- if (key == "parse")
202
- throw new Error("Invalid value for IncrementOperator");
203
- return IncrementOperator[key];
204
- }
205
- IncrementOperator.parse = parse;
206
- })(IncrementOperator || (IncrementOperator = {}));
207
- /**
208
- * @class Increment
209
- * @extends Statement
210
- * @category AST
211
- */
212
- class Increment extends Statement {
213
- constructor(operator, variable) {
214
- super();
215
- this.operator = operator;
216
- this.variable = variable;
217
- }
218
- get astNodeType() {
219
- return "increment";
220
- }
221
- }
222
- var AssignOperator;
223
- (function (AssignOperator) {
224
- AssignOperator["assign"] = "=";
225
- AssignOperator["addAssign"] = "+=";
226
- AssignOperator["subtractAssin"] = "-=";
227
- AssignOperator["multiplyAssign"] = "*=";
228
- AssignOperator["divideAssign"] = "/=";
229
- AssignOperator["moduloAssign"] = "%=";
230
- AssignOperator["andAssign"] = "&=";
231
- AssignOperator["orAssign"] = "|=";
232
- AssignOperator["xorAssign"] = "^=";
233
- AssignOperator["shiftLeftAssign"] = "<<=";
234
- AssignOperator["shiftRightAssign"] = ">>=";
235
- })(AssignOperator || (AssignOperator = {}));
236
- (function (AssignOperator) {
237
- function parse(val) {
238
- const key = val;
239
- if (key == "parse")
240
- throw new Error("Invalid value for AssignOperator");
241
- return AssignOperator[key];
242
- }
243
- AssignOperator.parse = parse;
244
- })(AssignOperator || (AssignOperator = {}));
245
- /**
246
- * @class Assign
247
- * @extends Statement
248
- * @category AST
249
- */
250
- class Assign extends Statement {
251
- constructor(operator, variable, value) {
252
- super();
253
- this.operator = operator;
254
- this.variable = variable;
255
- this.value = value;
256
- }
257
- get astNodeType() {
258
- return "assign";
259
- }
260
- }
261
- /**
262
- * @class Call
263
- * @extends Statement
264
- * @category AST
265
- */
266
- class Call extends Statement {
267
- constructor(name, args) {
268
- super();
269
- this.name = name;
270
- this.args = args;
271
- }
272
- get astNodeType() {
273
- return "call";
274
- }
275
- }
276
- /**
277
- * @class Loop
278
- * @extends Statement
279
- * @category AST
280
- */
281
- class Loop extends Statement {
282
- constructor(body, continuing) {
283
- super();
284
- this.body = body;
285
- this.continuing = continuing;
286
- }
287
- get astNodeType() {
288
- return "loop";
289
- }
290
- }
291
- /**
292
- * @class Switch
293
- * @extends Statement
294
- * @category AST
295
- */
296
- class Switch extends Statement {
297
- constructor(condition, body) {
298
- super();
299
- this.condition = condition;
300
- this.body = body;
301
- }
302
- get astNodeType() {
303
- return "body";
304
- }
305
- }
306
- /**
307
- * @class If
308
- * @extends Statement
309
- * @category AST
310
- */
311
- class If extends Statement {
312
- constructor(condition, body, elseif, _else) {
313
- super();
314
- this.condition = condition;
315
- this.body = body;
316
- this.elseif = elseif;
317
- this.else = _else;
318
- }
319
- get astNodeType() {
320
- return "if";
321
- }
322
- }
323
- /**
324
- * @class Return
325
- * @extends Statement
326
- * @category AST
327
- */
328
- class Return extends Statement {
329
- constructor(value) {
330
- super();
331
- this.value = value;
332
- }
333
- get astNodeType() {
334
- return "return";
335
- }
336
- }
337
- /**
338
- * @class Enable
339
- * @extends Statement
340
- * @category AST
341
- */
342
- class Enable extends Statement {
343
- constructor(name) {
344
- super();
345
- this.name = name;
346
- }
347
- get astNodeType() {
348
- return "enable";
349
- }
350
- }
351
- /**
352
- * @class Alias
353
- * @extends Statement
354
- * @category AST
355
- */
356
- class Alias extends Statement {
357
- constructor(name, type) {
358
- super();
359
- this.name = name;
360
- this.type = type;
361
- }
362
- get astNodeType() {
363
- return "alias";
364
- }
365
- }
366
- /**
367
- * @class Discard
368
- * @extends Statement
369
- * @category AST
370
- */
371
- class Discard extends Statement {
372
- constructor() {
373
- super();
374
- }
375
- get astNodeType() {
376
- return "discard";
377
- }
378
- }
379
- /**
380
- * @class Break
381
- * @extends Statement
382
- * @category AST
383
- */
384
- class Break extends Statement {
385
- constructor() {
386
- super();
387
- }
388
- get astNodeType() {
389
- return "break";
390
- }
391
- }
392
- /**
393
- * @class Continue
394
- * @extends Statement
395
- * @category AST
396
- */
397
- class Continue extends Statement {
398
- constructor() {
399
- super();
400
- }
401
- get astNodeType() {
402
- return "continue";
403
- }
404
- }
405
- /**
406
- * @class Type
407
- * @extends Statement
408
- * @category AST
409
- */
410
- class Type extends Statement {
411
- constructor(name) {
412
- super();
413
- this.name = name;
414
- }
415
- get astNodeType() {
416
- return "type";
417
- }
418
- get isStruct() {
419
- return false;
420
- }
421
- get isArray() {
422
- return false;
423
- }
424
- }
425
- /**
426
- * @class StructType
427
- * @extends Type
428
- * @category AST
429
- */
430
- class Struct extends Type {
431
- constructor(name, members) {
432
- super(name);
433
- this.members = members;
434
- }
435
- get astNodeType() {
436
- return "struct";
437
- }
438
- get isStruct() {
439
- return true;
440
- }
441
- /// Return the index of the member with the given name, or -1 if not found.
442
- getMemberIndex(name) {
443
- for (let i = 0; i < this.members.length; i++) {
444
- if (this.members[i].name == name)
445
- return i;
446
- }
447
- return -1;
448
- }
449
- }
450
- /**
451
- * @class TemplateType
452
- * @extends Type
453
- * @category AST
454
- */
455
- class TemplateType extends Type {
456
- constructor(name, format, access) {
457
- super(name);
458
- this.format = format;
459
- this.access = access;
460
- }
461
- get astNodeType() {
462
- return "template";
463
- }
464
- }
465
- /**
466
- * @class PointerType
467
- * @extends Type
468
- * @category AST
469
- */
470
- class PointerType extends Type {
471
- constructor(name, storage, type, access) {
472
- super(name);
473
- this.storage = storage;
474
- this.type = type;
475
- this.access = access;
476
- }
477
- get astNodeType() {
478
- return "pointer";
479
- }
480
- }
481
- /**
482
- * @class ArrayType
483
- * @extends Type
484
- * @category AST
485
- */
486
- class ArrayType extends Type {
487
- constructor(name, attributes, format, count) {
488
- super(name);
489
- this.attributes = attributes;
490
- this.format = format;
491
- this.count = count;
492
- }
493
- get astNodeType() {
494
- return "array";
495
- }
496
- get isArray() {
497
- return true;
498
- }
499
- }
500
- /**
501
- * @class SamplerType
502
- * @extends Type
503
- * @category AST
504
- */
505
- class SamplerType extends Type {
506
- constructor(name, format, access) {
507
- super(name);
508
- this.format = format;
509
- this.access = access;
510
- }
511
- get astNodeType() {
512
- return "sampler";
513
- }
514
- }
515
- /**
516
- * @class Expression
517
- * @extends Node
518
- * @category AST
519
- */
520
- class Expression extends Node {
521
- constructor() {
522
- super();
523
- }
524
- }
525
- /**
526
- * @class StringExpr
527
- * @extends Expression
528
- * @category AST
529
- */
530
- class StringExpr extends Expression {
531
- constructor(value) {
532
- super();
533
- this.value = value;
534
- }
535
- get astNodeType() {
536
- return "stringExpr";
537
- }
538
- toString() {
539
- return this.value;
540
- }
541
- evaluateString() {
542
- return this.value;
543
- }
544
- }
545
- /**
546
- * @class CreateExpr
547
- * @extends Expression
548
- * @category AST
549
- */
550
- class CreateExpr extends Expression {
551
- constructor(type, args) {
552
- super();
553
- this.type = type;
554
- this.args = args;
555
- }
556
- get astNodeType() {
557
- return "createExpr";
558
- }
559
- }
560
- /**
561
- * @class CallExpr
562
- * @extends Expression
563
- * @category AST
564
- */
565
- class CallExpr extends Expression {
566
- constructor(name, args) {
567
- super();
568
- this.name = name;
569
- this.args = args;
570
- }
571
- get astNodeType() {
572
- return "callExpr";
573
- }
574
- evaluate(context) {
575
- switch (this.name) {
576
- case "abs":
577
- return Math.abs(this.args[0].evaluate(context));
578
- case "acos":
579
- return Math.acos(this.args[0].evaluate(context));
580
- case "acosh":
581
- return Math.acosh(this.args[0].evaluate(context));
582
- case "asin":
583
- return Math.asin(this.args[0].evaluate(context));
584
- case "asinh":
585
- return Math.asinh(this.args[0].evaluate(context));
586
- case "atan":
587
- return Math.atan(this.args[0].evaluate(context));
588
- case "atan2":
589
- return Math.atan2(this.args[0].evaluate(context), this.args[1].evaluate(context));
590
- case "atanh":
591
- return Math.atanh(this.args[0].evaluate(context));
592
- case "ceil":
593
- return Math.ceil(this.args[0].evaluate(context));
594
- case "clamp":
595
- return Math.min(Math.max(this.args[0].evaluate(context), this.args[1].evaluate(context)), this.args[2].evaluate(context));
596
- case "cos":
597
- return Math.cos(this.args[0].evaluate(context));
598
- //case "cross":
599
- //TODO: (x[i] * y[j] - x[j] * y[i])
600
- case "degrees":
601
- return (this.args[0].evaluate(context) * 180) / Math.PI;
602
- //case "determinant":
603
- //TODO implement
604
- case "distance":
605
- return Math.sqrt(Math.pow(this.args[0].evaluate(context) - this.args[1].evaluate(context), 2));
606
- case "dot":
607
- //TODO: (x[i] * y[i])
608
- case "exp":
609
- return Math.exp(this.args[0].evaluate(context));
610
- case "exp2":
611
- return Math.pow(2, this.args[0].evaluate(context));
612
- //case "extractBits":
613
- //TODO: implement
614
- //case "firstLeadingBit":
615
- //TODO: implement
616
- case "floor":
617
- return Math.floor(this.args[0].evaluate(context));
618
- case "fma":
619
- return (this.args[0].evaluate(context) * this.args[1].evaluate(context) +
620
- this.args[2].evaluate(context));
621
- case "fract":
622
- return (this.args[0].evaluate(context) -
623
- Math.floor(this.args[0].evaluate(context)));
624
- //case "frexp":
625
- //TODO: implement
626
- case "inverseSqrt":
627
- return 1 / Math.sqrt(this.args[0].evaluate(context));
628
- //case "length":
629
- //TODO: implement
630
- case "log":
631
- return Math.log(this.args[0].evaluate(context));
632
- case "log2":
633
- return Math.log2(this.args[0].evaluate(context));
634
- case "max":
635
- return Math.max(this.args[0].evaluate(context), this.args[1].evaluate(context));
636
- case "min":
637
- return Math.min(this.args[0].evaluate(context), this.args[1].evaluate(context));
638
- case "mix":
639
- return (this.args[0].evaluate(context) *
640
- (1 - this.args[2].evaluate(context)) +
641
- this.args[1].evaluate(context) * this.args[2].evaluate(context));
642
- case "modf":
643
- return (this.args[0].evaluate(context) -
644
- Math.floor(this.args[0].evaluate(context)));
645
- case "pow":
646
- return Math.pow(this.args[0].evaluate(context), this.args[1].evaluate(context));
647
- case "radians":
648
- return (this.args[0].evaluate(context) * Math.PI) / 180;
649
- case "round":
650
- return Math.round(this.args[0].evaluate(context));
651
- case "sign":
652
- return Math.sign(this.args[0].evaluate(context));
653
- case "sin":
654
- return Math.sin(this.args[0].evaluate(context));
655
- case "sinh":
656
- return Math.sinh(this.args[0].evaluate(context));
657
- case "saturate":
658
- return Math.min(Math.max(this.args[0].evaluate(context), 0), 1);
659
- case "smoothstep":
660
- return (this.args[0].evaluate(context) *
661
- this.args[0].evaluate(context) *
662
- (3 - 2 * this.args[0].evaluate(context)));
663
- case "sqrt":
664
- return Math.sqrt(this.args[0].evaluate(context));
665
- case "step":
666
- return this.args[0].evaluate(context) < this.args[1].evaluate(context)
667
- ? 0
668
- : 1;
669
- case "tan":
670
- return Math.tan(this.args[0].evaluate(context));
671
- case "tanh":
672
- return Math.tanh(this.args[0].evaluate(context));
673
- case "trunc":
674
- return Math.trunc(this.args[0].evaluate(context));
675
- default:
676
- throw new Error("Non const function: " + this.name);
677
- }
678
- }
679
- }
680
- /**
681
- * @class VariableExpr
682
- * @extends Expression
683
- * @category AST
684
- */
685
- class VariableExpr extends Expression {
686
- constructor(name) {
687
- super();
688
- this.name = name;
689
- }
690
- get astNodeType() {
691
- return "varExpr";
692
- }
693
- }
694
- /**
695
- * @class ConstExpr
696
- * @extends Expression
697
- * @category AST
698
- */
699
- class ConstExpr extends Expression {
700
- constructor(name, initializer) {
701
- super();
702
- this.name = name;
703
- this.initializer = initializer;
704
- }
705
- get astNodeType() {
706
- return "constExpr";
707
- }
708
- evaluate(context) {
709
- var _a, _b;
710
- if (this.initializer instanceof CreateExpr) {
711
- // This is a struct constant
712
- const property = (_a = this.postfix) === null || _a === void 0 ? void 0 : _a.evaluateString(context);
713
- const type = (_b = this.initializer.type) === null || _b === void 0 ? void 0 : _b.name;
714
- const struct = context.structs.get(type);
715
- const memberIndex = struct === null || struct === void 0 ? void 0 : struct.getMemberIndex(property);
716
- if (memberIndex != -1) {
717
- const value = this.initializer.args[memberIndex].evaluate(context);
718
- return value;
719
- }
720
- console.log(memberIndex);
721
- }
722
- return this.initializer.evaluate(context);
723
- }
724
- }
725
- /**
726
- * @class LiteralExpr
727
- * @extends Expression
728
- * @category AST
729
- */
730
- class LiteralExpr extends Expression {
731
- constructor(value) {
732
- super();
733
- this.value = value;
734
- }
735
- get astNodeType() {
736
- return "literalExpr";
737
- }
738
- evaluate() {
739
- return this.value;
740
- }
741
- }
742
- /**
743
- * @class BitcastExpr
744
- * @extends Expression
745
- * @category AST
746
- */
747
- class BitcastExpr extends Expression {
748
- constructor(type, value) {
749
- super();
750
- this.type = type;
751
- this.value = value;
752
- }
753
- get astNodeType() {
754
- return "bitcastExpr";
755
- }
756
- }
757
- /**
758
- * @class TypecastExpr
759
- * @extends Expression
760
- * @category AST
761
- */
762
- class TypecastExpr extends Expression {
763
- constructor(type, args) {
764
- super();
765
- this.type = type;
766
- this.args = args;
767
- }
768
- get astNodeType() {
769
- return "typecastExpr";
770
- }
771
- evaluate(context) {
772
- return this.args[0].evaluate(context);
773
- }
774
- }
775
- /**
776
- * @class GroupingExpr
777
- * @extends Expression
778
- * @category AST
779
- */
780
- class GroupingExpr extends Expression {
781
- constructor(contents) {
782
- super();
783
- this.contents = contents;
784
- }
785
- get astNodeType() {
786
- return "groupExpr";
787
- }
788
- evaluate(context) {
789
- return this.contents[0].evaluate(context);
790
- }
791
- }
792
- /**
793
- * @class Operator
794
- * @extends Expression
795
- * @category AST
796
- */
797
- class Operator extends Expression {
798
- constructor() {
799
- super();
800
- }
801
- }
802
- /**
803
- * @class UnaryOperator
804
- * @extends Operator
805
- * @category AST
806
- * @property {string} operator +, -, !, ~
807
- */
808
- class UnaryOperator extends Operator {
809
- constructor(operator, right) {
810
- super();
811
- this.operator = operator;
812
- this.right = right;
813
- }
814
- get astNodeType() {
815
- return "unaryOp";
816
- }
817
- evaluate(context) {
818
- switch (this.operator) {
819
- case "+":
820
- return this.right.evaluate(context);
821
- case "-":
822
- return -this.right.evaluate(context);
823
- case "!":
824
- return this.right.evaluate(context) ? 0 : 1;
825
- case "~":
826
- return ~this.right.evaluate(context);
827
- default:
828
- throw new Error("Unknown unary operator: " + this.operator);
829
- }
830
- }
831
- }
832
- /**
833
- * @class BinaryOperator
834
- * @extends Operator
835
- * @category AST
836
- * @property {string} operator +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||
837
- */
838
- class BinaryOperator extends Operator {
839
- constructor(operator, left, right) {
840
- super();
841
- this.operator = operator;
842
- this.left = left;
843
- this.right = right;
844
- }
845
- get astNodeType() {
846
- return "binaryOp";
847
- }
848
- evaluate(context) {
849
- switch (this.operator) {
850
- case "+":
851
- return this.left.evaluate(context) + this.right.evaluate(context);
852
- case "-":
853
- return this.left.evaluate(context) - this.right.evaluate(context);
854
- case "*":
855
- return this.left.evaluate(context) * this.right.evaluate(context);
856
- case "/":
857
- return this.left.evaluate(context) / this.right.evaluate(context);
858
- case "%":
859
- return this.left.evaluate(context) % this.right.evaluate(context);
860
- case "==":
861
- return this.left.evaluate(context) == this.right.evaluate(context)
862
- ? 1
863
- : 0;
864
- case "!=":
865
- return this.left.evaluate(context) != this.right.evaluate(context)
866
- ? 1
867
- : 0;
868
- case "<":
869
- return this.left.evaluate(context) < this.right.evaluate(context)
870
- ? 1
871
- : 0;
872
- case ">":
873
- return this.left.evaluate(context) > this.right.evaluate(context)
874
- ? 1
875
- : 0;
876
- case "<=":
877
- return this.left.evaluate(context) <= this.right.evaluate(context)
878
- ? 1
879
- : 0;
880
- case ">=":
881
- return this.left.evaluate(context) >= this.right.evaluate(context)
882
- ? 1
883
- : 0;
884
- case "&&":
885
- return this.left.evaluate(context) && this.right.evaluate(context)
886
- ? 1
887
- : 0;
888
- case "||":
889
- return this.left.evaluate(context) || this.right.evaluate(context)
890
- ? 1
891
- : 0;
892
- default:
893
- throw new Error(`Unknown operator ${this.operator}`);
894
- }
895
- }
896
- }
897
- /**
898
- * @class SwitchCase
899
- * @extends Node
900
- * @category AST
901
- */
902
- class SwitchCase extends Node {
903
- constructor() {
904
- super();
905
- }
906
- }
907
- /**
908
- * @class Case
909
- * @extends SwitchCase
910
- * @category AST
911
- */
912
- class Case extends SwitchCase {
913
- constructor(selector, body) {
914
- super();
915
- this.selector = selector;
916
- this.body = body;
917
- }
918
- get astNodeType() {
919
- return "case";
920
- }
921
- }
922
- /**
923
- * @class Default
924
- * @extends SwitchCase
925
- * @category AST
926
- */
927
- class Default extends SwitchCase {
928
- constructor(body) {
929
- super();
930
- this.body = body;
931
- }
932
- get astNodeType() {
933
- return "default";
934
- }
935
- }
936
- /**
937
- * @class Argument
938
- * @extends Node
939
- * @category AST
940
- */
941
- class Argument extends Node {
942
- constructor(name, type, attributes) {
943
- super();
944
- this.name = name;
945
- this.type = type;
946
- this.attributes = attributes;
947
- }
948
- get astNodeType() {
949
- return "argument";
950
- }
951
- }
952
- /**
953
- * @class ElseIf
954
- * @extends Node
955
- * @category AST
956
- */
957
- class ElseIf extends Node {
958
- constructor(condition, body) {
959
- super();
960
- this.condition = condition;
961
- this.body = body;
962
- }
963
- get astNodeType() {
964
- return "elseif";
965
- }
966
- }
967
- /**
968
- * @class Member
969
- * @extends Node
970
- * @category AST
971
- */
972
- class Member extends Node {
973
- constructor(name, type, attributes) {
974
- super();
975
- this.name = name;
976
- this.type = type;
977
- this.attributes = attributes;
978
- }
979
- get astNodeType() {
980
- return "member";
981
- }
982
- }
983
- /**
984
- * @class Attribute
985
- * @extends Node
986
- * @category AST
987
- */
988
- class Attribute extends Node {
989
- constructor(name, value) {
990
- super();
991
- this.name = name;
992
- this.value = value;
993
- }
994
- get astNodeType() {
995
- return "attribute";
996
- }
997
- }
998
-
999
- var _a;
1000
- var TokenClass;
1001
- (function (TokenClass) {
1002
- TokenClass[TokenClass["token"] = 0] = "token";
1003
- TokenClass[TokenClass["keyword"] = 1] = "keyword";
1004
- TokenClass[TokenClass["reserved"] = 2] = "reserved";
1005
- })(TokenClass || (TokenClass = {}));
1006
- class TokenType {
1007
- constructor(name, type, rule) {
1008
- this.name = name;
1009
- this.type = type;
1010
- this.rule = rule;
1011
- }
1012
- toString() {
1013
- return this.name;
1014
- }
1015
- }
1016
- /// Catalog of defined token types, keywords, and reserved words.
1017
- class TokenTypes {
1018
- }
1019
- _a = TokenTypes;
1020
- TokenTypes.none = new TokenType("", TokenClass.reserved, "");
1021
- TokenTypes.eof = new TokenType("EOF", TokenClass.token, "");
1022
- TokenTypes.reserved = {
1023
- asm: new TokenType("asm", TokenClass.reserved, "asm"),
1024
- bf16: new TokenType("bf16", TokenClass.reserved, "bf16"),
1025
- do: new TokenType("do", TokenClass.reserved, "do"),
1026
- enum: new TokenType("enum", TokenClass.reserved, "enum"),
1027
- f16: new TokenType("f16", TokenClass.reserved, "f16"),
1028
- f64: new TokenType("f64", TokenClass.reserved, "f64"),
1029
- handle: new TokenType("handle", TokenClass.reserved, "handle"),
1030
- i8: new TokenType("i8", TokenClass.reserved, "i8"),
1031
- i16: new TokenType("i16", TokenClass.reserved, "i16"),
1032
- i64: new TokenType("i64", TokenClass.reserved, "i64"),
1033
- mat: new TokenType("mat", TokenClass.reserved, "mat"),
1034
- premerge: new TokenType("premerge", TokenClass.reserved, "premerge"),
1035
- regardless: new TokenType("regardless", TokenClass.reserved, "regardless"),
1036
- typedef: new TokenType("typedef", TokenClass.reserved, "typedef"),
1037
- u8: new TokenType("u8", TokenClass.reserved, "u8"),
1038
- u16: new TokenType("u16", TokenClass.reserved, "u16"),
1039
- u64: new TokenType("u64", TokenClass.reserved, "u64"),
1040
- unless: new TokenType("unless", TokenClass.reserved, "unless"),
1041
- using: new TokenType("using", TokenClass.reserved, "using"),
1042
- vec: new TokenType("vec", TokenClass.reserved, "vec"),
1043
- void: new TokenType("void", TokenClass.reserved, "void"),
1044
- };
1045
- TokenTypes.keywords = {
1046
- array: new TokenType("array", TokenClass.keyword, "array"),
1047
- atomic: new TokenType("atomic", TokenClass.keyword, "atomic"),
1048
- bool: new TokenType("bool", TokenClass.keyword, "bool"),
1049
- f32: new TokenType("f32", TokenClass.keyword, "f32"),
1050
- i32: new TokenType("i32", TokenClass.keyword, "i32"),
1051
- mat2x2: new TokenType("mat2x2", TokenClass.keyword, "mat2x2"),
1052
- mat2x3: new TokenType("mat2x3", TokenClass.keyword, "mat2x3"),
1053
- mat2x4: new TokenType("mat2x4", TokenClass.keyword, "mat2x4"),
1054
- mat3x2: new TokenType("mat3x2", TokenClass.keyword, "mat3x2"),
1055
- mat3x3: new TokenType("mat3x3", TokenClass.keyword, "mat3x3"),
1056
- mat3x4: new TokenType("mat3x4", TokenClass.keyword, "mat3x4"),
1057
- mat4x2: new TokenType("mat4x2", TokenClass.keyword, "mat4x2"),
1058
- mat4x3: new TokenType("mat4x3", TokenClass.keyword, "mat4x3"),
1059
- mat4x4: new TokenType("mat4x4", TokenClass.keyword, "mat4x4"),
1060
- ptr: new TokenType("ptr", TokenClass.keyword, "ptr"),
1061
- sampler: new TokenType("sampler", TokenClass.keyword, "sampler"),
1062
- sampler_comparison: new TokenType("sampler_comparison", TokenClass.keyword, "sampler_comparison"),
1063
- struct: new TokenType("struct", TokenClass.keyword, "struct"),
1064
- texture_1d: new TokenType("texture_1d", TokenClass.keyword, "texture_1d"),
1065
- texture_2d: new TokenType("texture_2d", TokenClass.keyword, "texture_2d"),
1066
- texture_2d_array: new TokenType("texture_2d_array", TokenClass.keyword, "texture_2d_array"),
1067
- texture_3d: new TokenType("texture_3d", TokenClass.keyword, "texture_3d"),
1068
- texture_cube: new TokenType("texture_cube", TokenClass.keyword, "texture_cube"),
1069
- texture_cube_array: new TokenType("texture_cube_array", TokenClass.keyword, "texture_cube_array"),
1070
- texture_multisampled_2d: new TokenType("texture_multisampled_2d", TokenClass.keyword, "texture_multisampled_2d"),
1071
- texture_storage_1d: new TokenType("texture_storage_1d", TokenClass.keyword, "texture_storage_1d"),
1072
- texture_storage_2d: new TokenType("texture_storage_2d", TokenClass.keyword, "texture_storage_2d"),
1073
- texture_storage_2d_array: new TokenType("texture_storage_2d_array", TokenClass.keyword, "texture_storage_2d_array"),
1074
- texture_storage_3d: new TokenType("texture_storage_3d", TokenClass.keyword, "texture_storage_3d"),
1075
- texture_depth_2d: new TokenType("texture_depth_2d", TokenClass.keyword, "texture_depth_2d"),
1076
- texture_depth_2d_array: new TokenType("texture_depth_2d_array", TokenClass.keyword, "texture_depth_2d_array"),
1077
- texture_depth_cube: new TokenType("texture_depth_cube", TokenClass.keyword, "texture_depth_cube"),
1078
- texture_depth_cube_array: new TokenType("texture_depth_cube_array", TokenClass.keyword, "texture_depth_cube_array"),
1079
- texture_depth_multisampled_2d: new TokenType("texture_depth_multisampled_2d", TokenClass.keyword, "texture_depth_multisampled_2d"),
1080
- texture_external: new TokenType("texture_external", TokenClass.keyword, "texture_external"),
1081
- u32: new TokenType("u32", TokenClass.keyword, "u32"),
1082
- vec2: new TokenType("vec2", TokenClass.keyword, "vec2"),
1083
- vec3: new TokenType("vec3", TokenClass.keyword, "vec3"),
1084
- vec4: new TokenType("vec4", TokenClass.keyword, "vec4"),
1085
- bitcast: new TokenType("bitcast", TokenClass.keyword, "bitcast"),
1086
- block: new TokenType("block", TokenClass.keyword, "block"),
1087
- break: new TokenType("break", TokenClass.keyword, "break"),
1088
- case: new TokenType("case", TokenClass.keyword, "case"),
1089
- continue: new TokenType("continue", TokenClass.keyword, "continue"),
1090
- continuing: new TokenType("continuing", TokenClass.keyword, "continuing"),
1091
- default: new TokenType("default", TokenClass.keyword, "default"),
1092
- discard: new TokenType("discard", TokenClass.keyword, "discard"),
1093
- else: new TokenType("else", TokenClass.keyword, "else"),
1094
- enable: new TokenType("enable", TokenClass.keyword, "enable"),
1095
- fallthrough: new TokenType("fallthrough", TokenClass.keyword, "fallthrough"),
1096
- false: new TokenType("false", TokenClass.keyword, "false"),
1097
- fn: new TokenType("fn", TokenClass.keyword, "fn"),
1098
- for: new TokenType("for", TokenClass.keyword, "for"),
1099
- function: new TokenType("function", TokenClass.keyword, "function"),
1100
- if: new TokenType("if", TokenClass.keyword, "if"),
1101
- let: new TokenType("let", TokenClass.keyword, "let"),
1102
- const: new TokenType("const", TokenClass.keyword, "const"),
1103
- loop: new TokenType("loop", TokenClass.keyword, "loop"),
1104
- while: new TokenType("while", TokenClass.keyword, "while"),
1105
- private: new TokenType("private", TokenClass.keyword, "private"),
1106
- read: new TokenType("read", TokenClass.keyword, "read"),
1107
- read_write: new TokenType("read_write", TokenClass.keyword, "read_write"),
1108
- return: new TokenType("return", TokenClass.keyword, "return"),
1109
- storage: new TokenType("storage", TokenClass.keyword, "storage"),
1110
- switch: new TokenType("switch", TokenClass.keyword, "switch"),
1111
- true: new TokenType("true", TokenClass.keyword, "true"),
1112
- alias: new TokenType("alias", TokenClass.keyword, "alias"),
1113
- type: new TokenType("type", TokenClass.keyword, "type"),
1114
- uniform: new TokenType("uniform", TokenClass.keyword, "uniform"),
1115
- var: new TokenType("var", TokenClass.keyword, "var"),
1116
- override: new TokenType("override", TokenClass.keyword, "override"),
1117
- workgroup: new TokenType("workgroup", TokenClass.keyword, "workgroup"),
1118
- write: new TokenType("write", TokenClass.keyword, "write"),
1119
- r8unorm: new TokenType("r8unorm", TokenClass.keyword, "r8unorm"),
1120
- r8snorm: new TokenType("r8snorm", TokenClass.keyword, "r8snorm"),
1121
- r8uint: new TokenType("r8uint", TokenClass.keyword, "r8uint"),
1122
- r8sint: new TokenType("r8sint", TokenClass.keyword, "r8sint"),
1123
- r16uint: new TokenType("r16uint", TokenClass.keyword, "r16uint"),
1124
- r16sint: new TokenType("r16sint", TokenClass.keyword, "r16sint"),
1125
- r16float: new TokenType("r16float", TokenClass.keyword, "r16float"),
1126
- rg8unorm: new TokenType("rg8unorm", TokenClass.keyword, "rg8unorm"),
1127
- rg8snorm: new TokenType("rg8snorm", TokenClass.keyword, "rg8snorm"),
1128
- rg8uint: new TokenType("rg8uint", TokenClass.keyword, "rg8uint"),
1129
- rg8sint: new TokenType("rg8sint", TokenClass.keyword, "rg8sint"),
1130
- r32uint: new TokenType("r32uint", TokenClass.keyword, "r32uint"),
1131
- r32sint: new TokenType("r32sint", TokenClass.keyword, "r32sint"),
1132
- r32float: new TokenType("r32float", TokenClass.keyword, "r32float"),
1133
- rg16uint: new TokenType("rg16uint", TokenClass.keyword, "rg16uint"),
1134
- rg16sint: new TokenType("rg16sint", TokenClass.keyword, "rg16sint"),
1135
- rg16float: new TokenType("rg16float", TokenClass.keyword, "rg16float"),
1136
- rgba8unorm: new TokenType("rgba8unorm", TokenClass.keyword, "rgba8unorm"),
1137
- rgba8unorm_srgb: new TokenType("rgba8unorm_srgb", TokenClass.keyword, "rgba8unorm_srgb"),
1138
- rgba8snorm: new TokenType("rgba8snorm", TokenClass.keyword, "rgba8snorm"),
1139
- rgba8uint: new TokenType("rgba8uint", TokenClass.keyword, "rgba8uint"),
1140
- rgba8sint: new TokenType("rgba8sint", TokenClass.keyword, "rgba8sint"),
1141
- bgra8unorm: new TokenType("bgra8unorm", TokenClass.keyword, "bgra8unorm"),
1142
- bgra8unorm_srgb: new TokenType("bgra8unorm_srgb", TokenClass.keyword, "bgra8unorm_srgb"),
1143
- rgb10a2unorm: new TokenType("rgb10a2unorm", TokenClass.keyword, "rgb10a2unorm"),
1144
- rg11b10float: new TokenType("rg11b10float", TokenClass.keyword, "rg11b10float"),
1145
- rg32uint: new TokenType("rg32uint", TokenClass.keyword, "rg32uint"),
1146
- rg32sint: new TokenType("rg32sint", TokenClass.keyword, "rg32sint"),
1147
- rg32float: new TokenType("rg32float", TokenClass.keyword, "rg32float"),
1148
- rgba16uint: new TokenType("rgba16uint", TokenClass.keyword, "rgba16uint"),
1149
- rgba16sint: new TokenType("rgba16sint", TokenClass.keyword, "rgba16sint"),
1150
- rgba16float: new TokenType("rgba16float", TokenClass.keyword, "rgba16float"),
1151
- rgba32uint: new TokenType("rgba32uint", TokenClass.keyword, "rgba32uint"),
1152
- rgba32sint: new TokenType("rgba32sint", TokenClass.keyword, "rgba32sint"),
1153
- rgba32float: new TokenType("rgba32float", TokenClass.keyword, "rgba32float"),
1154
- static_assert: new TokenType("static_assert", TokenClass.keyword, "static_assert"),
1155
- // WGSL grammar has a few keywords that have different token names than the strings they
1156
- // represent. Aliasing them here.
1157
- /*int32: new TokenType("i32", TokenClass.keyword, "i32"),
1158
- uint32: new TokenType("u32", TokenClass.keyword, "u32"),
1159
- float32: new TokenType("f32", TokenClass.keyword, "f32"),
1160
- pointer: new TokenType("ptr", TokenClass.keyword, "ptr"),*/
1161
- };
1162
- TokenTypes.tokens = {
1163
- decimal_float_literal: new TokenType("decimal_float_literal", TokenClass.token, /((-?[0-9]*\.[0-9]+|-?[0-9]+\.[0-9]*)((e|E)(\+|-)?[0-9]+)?f?)|(-?[0-9]+(e|E)(\+|-)?[0-9]+f?)|([0-9]+f)/),
1164
- hex_float_literal: new TokenType("hex_float_literal", TokenClass.token, /-?0x((([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.[0-9a-fA-F]*)((p|P)(\+|-)?[0-9]+f?)?)|([0-9a-fA-F]+(p|P)(\+|-)?[0-9]+f?))/),
1165
- int_literal: new TokenType("int_literal", TokenClass.token, /-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/),
1166
- uint_literal: new TokenType("uint_literal", TokenClass.token, /0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/),
1167
- ident: new TokenType("ident", TokenClass.token, /[a-zA-Z][0-9a-zA-Z_]*/),
1168
- and: new TokenType("and", TokenClass.token, "&"),
1169
- and_and: new TokenType("and_and", TokenClass.token, "&&"),
1170
- arrow: new TokenType("arrow ", TokenClass.token, "->"),
1171
- attr: new TokenType("attr", TokenClass.token, "@"),
1172
- attr_left: new TokenType("attr_left", TokenClass.token, "[["),
1173
- attr_right: new TokenType("attr_right", TokenClass.token, "]]"),
1174
- forward_slash: new TokenType("forward_slash", TokenClass.token, "/"),
1175
- bang: new TokenType("bang", TokenClass.token, "!"),
1176
- bracket_left: new TokenType("bracket_left", TokenClass.token, "["),
1177
- bracket_right: new TokenType("bracket_right", TokenClass.token, "]"),
1178
- brace_left: new TokenType("brace_left", TokenClass.token, "{"),
1179
- brace_right: new TokenType("brace_right", TokenClass.token, "}"),
1180
- colon: new TokenType("colon", TokenClass.token, ":"),
1181
- comma: new TokenType("comma", TokenClass.token, ","),
1182
- equal: new TokenType("equal", TokenClass.token, "="),
1183
- equal_equal: new TokenType("equal_equal", TokenClass.token, "=="),
1184
- not_equal: new TokenType("not_equal", TokenClass.token, "!="),
1185
- greater_than: new TokenType("greater_than", TokenClass.token, ">"),
1186
- greater_than_equal: new TokenType("greater_than_equal", TokenClass.token, ">="),
1187
- shift_right: new TokenType("shift_right", TokenClass.token, ">>"),
1188
- less_than: new TokenType("less_than", TokenClass.token, "<"),
1189
- less_than_equal: new TokenType("less_than_equal", TokenClass.token, "<="),
1190
- shift_left: new TokenType("shift_left", TokenClass.token, "<<"),
1191
- modulo: new TokenType("modulo", TokenClass.token, "%"),
1192
- minus: new TokenType("minus", TokenClass.token, "-"),
1193
- minus_minus: new TokenType("minus_minus", TokenClass.token, "--"),
1194
- period: new TokenType("period", TokenClass.token, "."),
1195
- plus: new TokenType("plus", TokenClass.token, "+"),
1196
- plus_plus: new TokenType("plus_plus", TokenClass.token, "++"),
1197
- or: new TokenType("or", TokenClass.token, "|"),
1198
- or_or: new TokenType("or_or", TokenClass.token, "||"),
1199
- paren_left: new TokenType("paren_left", TokenClass.token, "("),
1200
- paren_right: new TokenType("paren_right", TokenClass.token, ")"),
1201
- semicolon: new TokenType("semicolon", TokenClass.token, ";"),
1202
- star: new TokenType("star", TokenClass.token, "*"),
1203
- tilde: new TokenType("tilde", TokenClass.token, "~"),
1204
- underscore: new TokenType("underscore", TokenClass.token, "_"),
1205
- xor: new TokenType("xor", TokenClass.token, "^"),
1206
- plus_equal: new TokenType("plus_equal", TokenClass.token, "+="),
1207
- minus_equal: new TokenType("minus_equal", TokenClass.token, "-="),
1208
- times_equal: new TokenType("times_equal", TokenClass.token, "*="),
1209
- division_equal: new TokenType("division_equal", TokenClass.token, "/="),
1210
- modulo_equal: new TokenType("modulo_equal", TokenClass.token, "%="),
1211
- and_equal: new TokenType("and_equal", TokenClass.token, "&="),
1212
- or_equal: new TokenType("or_equal", TokenClass.token, "|="),
1213
- xor_equal: new TokenType("xor_equal", TokenClass.token, "^="),
1214
- shift_right_equal: new TokenType("shift_right_equal", TokenClass.token, ">>="),
1215
- shift_left_equal: new TokenType("shift_left_equal", TokenClass.token, "<<="),
1216
- };
1217
- TokenTypes.storage_class = [
1218
- _a.keywords.function,
1219
- _a.keywords.private,
1220
- _a.keywords.workgroup,
1221
- _a.keywords.uniform,
1222
- _a.keywords.storage,
1223
- ];
1224
- TokenTypes.access_mode = [
1225
- _a.keywords.read,
1226
- _a.keywords.write,
1227
- _a.keywords.read_write,
1228
- ];
1229
- TokenTypes.sampler_type = [
1230
- _a.keywords.sampler,
1231
- _a.keywords.sampler_comparison,
1232
- ];
1233
- TokenTypes.sampled_texture_type = [
1234
- _a.keywords.texture_1d,
1235
- _a.keywords.texture_2d,
1236
- _a.keywords.texture_2d_array,
1237
- _a.keywords.texture_3d,
1238
- _a.keywords.texture_cube,
1239
- _a.keywords.texture_cube_array,
1240
- ];
1241
- TokenTypes.multisampled_texture_type = [
1242
- _a.keywords.texture_multisampled_2d,
1243
- ];
1244
- TokenTypes.storage_texture_type = [
1245
- _a.keywords.texture_storage_1d,
1246
- _a.keywords.texture_storage_2d,
1247
- _a.keywords.texture_storage_2d_array,
1248
- _a.keywords.texture_storage_3d,
1249
- ];
1250
- TokenTypes.depth_texture_type = [
1251
- _a.keywords.texture_depth_2d,
1252
- _a.keywords.texture_depth_2d_array,
1253
- _a.keywords.texture_depth_cube,
1254
- _a.keywords.texture_depth_cube_array,
1255
- _a.keywords.texture_depth_multisampled_2d,
1256
- ];
1257
- TokenTypes.texture_external_type = [_a.keywords.texture_external];
1258
- TokenTypes.any_texture_type = [
1259
- ..._a.sampled_texture_type,
1260
- ..._a.multisampled_texture_type,
1261
- ..._a.storage_texture_type,
1262
- ..._a.depth_texture_type,
1263
- ..._a.texture_external_type,
1264
- ];
1265
- TokenTypes.texel_format = [
1266
- _a.keywords.r8unorm,
1267
- _a.keywords.r8snorm,
1268
- _a.keywords.r8uint,
1269
- _a.keywords.r8sint,
1270
- _a.keywords.r16uint,
1271
- _a.keywords.r16sint,
1272
- _a.keywords.r16float,
1273
- _a.keywords.rg8unorm,
1274
- _a.keywords.rg8snorm,
1275
- _a.keywords.rg8uint,
1276
- _a.keywords.rg8sint,
1277
- _a.keywords.r32uint,
1278
- _a.keywords.r32sint,
1279
- _a.keywords.r32float,
1280
- _a.keywords.rg16uint,
1281
- _a.keywords.rg16sint,
1282
- _a.keywords.rg16float,
1283
- _a.keywords.rgba8unorm,
1284
- _a.keywords.rgba8unorm_srgb,
1285
- _a.keywords.rgba8snorm,
1286
- _a.keywords.rgba8uint,
1287
- _a.keywords.rgba8sint,
1288
- _a.keywords.bgra8unorm,
1289
- _a.keywords.bgra8unorm_srgb,
1290
- _a.keywords.rgb10a2unorm,
1291
- _a.keywords.rg11b10float,
1292
- _a.keywords.rg32uint,
1293
- _a.keywords.rg32sint,
1294
- _a.keywords.rg32float,
1295
- _a.keywords.rgba16uint,
1296
- _a.keywords.rgba16sint,
1297
- _a.keywords.rgba16float,
1298
- _a.keywords.rgba32uint,
1299
- _a.keywords.rgba32sint,
1300
- _a.keywords.rgba32float,
1301
- ];
1302
- TokenTypes.const_literal = [
1303
- _a.tokens.int_literal,
1304
- _a.tokens.uint_literal,
1305
- _a.tokens.decimal_float_literal,
1306
- _a.tokens.hex_float_literal,
1307
- _a.keywords.true,
1308
- _a.keywords.false,
1309
- ];
1310
- TokenTypes.literal_or_ident = [
1311
- _a.tokens.ident,
1312
- _a.tokens.int_literal,
1313
- _a.tokens.uint_literal,
1314
- _a.tokens.decimal_float_literal,
1315
- _a.tokens.hex_float_literal,
1316
- ];
1317
- TokenTypes.element_count_expression = [
1318
- _a.tokens.int_literal,
1319
- _a.tokens.uint_literal,
1320
- _a.tokens.ident,
1321
- ];
1322
- TokenTypes.template_types = [
1323
- _a.keywords.vec2,
1324
- _a.keywords.vec3,
1325
- _a.keywords.vec4,
1326
- _a.keywords.mat2x2,
1327
- _a.keywords.mat2x3,
1328
- _a.keywords.mat2x4,
1329
- _a.keywords.mat3x2,
1330
- _a.keywords.mat3x3,
1331
- _a.keywords.mat3x4,
1332
- _a.keywords.mat4x2,
1333
- _a.keywords.mat4x3,
1334
- _a.keywords.mat4x4,
1335
- _a.keywords.atomic,
1336
- _a.keywords.bitcast,
1337
- ..._a.any_texture_type,
1338
- ];
1339
- // The grammar calls out 'block', but attribute grammar is defined to use a 'ident'.
1340
- // The attribute grammar should be ident | block.
1341
- TokenTypes.attribute_name = [_a.tokens.ident, _a.keywords.block];
1342
- TokenTypes.assignment_operators = [
1343
- _a.tokens.equal,
1344
- _a.tokens.plus_equal,
1345
- _a.tokens.minus_equal,
1346
- _a.tokens.times_equal,
1347
- _a.tokens.division_equal,
1348
- _a.tokens.modulo_equal,
1349
- _a.tokens.and_equal,
1350
- _a.tokens.or_equal,
1351
- _a.tokens.xor_equal,
1352
- _a.tokens.shift_right_equal,
1353
- _a.tokens.shift_left_equal,
1354
- ];
1355
- TokenTypes.increment_operators = [
1356
- _a.tokens.plus_plus,
1357
- _a.tokens.minus_minus,
1358
- ];
1359
- /// A token parsed by the WgslScanner.
1360
- class Token {
1361
- constructor(type, lexeme, line) {
1362
- this.type = type;
1363
- this.lexeme = lexeme;
1364
- this.line = line;
1365
- }
1366
- toString() {
1367
- return this.lexeme;
1368
- }
1369
- isTemplateType() {
1370
- return TokenTypes.template_types.indexOf(this.type) != -1;
1371
- }
1372
- isArrayType() {
1373
- return this.type == TokenTypes.keywords.array;
1374
- }
1375
- isArrayOrTemplateType() {
1376
- return this.isArrayType() || this.isTemplateType();
1377
- }
1378
- }
1379
- /// Lexical scanner for the WGSL language. This takes an input source text and generates a list
1380
- /// of Token objects, which can then be fed into the WgslParser to generate an AST.
1381
- class WgslScanner {
1382
- constructor(source) {
1383
- this._tokens = [];
1384
- this._start = 0;
1385
- this._current = 0;
1386
- this._line = 1;
1387
- this._source = source !== null && source !== void 0 ? source : "";
1388
- }
1389
- /// Scan all tokens from the source.
1390
- scanTokens() {
1391
- while (!this._isAtEnd()) {
1392
- this._start = this._current;
1393
- if (!this.scanToken())
1394
- throw `Invalid syntax at line ${this._line}`;
1395
- }
1396
- this._tokens.push(new Token(TokenTypes.eof, "", this._line));
1397
- return this._tokens;
1398
- }
1399
- /// Scan a single token from the source.
1400
- scanToken() {
1401
- // Find the longest consecutive set of characters that match a rule.
1402
- let lexeme = this._advance();
1403
- // Skip line-feed, adding to the line counter.
1404
- if (lexeme == "\n") {
1405
- this._line++;
1406
- return true;
1407
- }
1408
- // Skip whitespace
1409
- if (this._isWhitespace(lexeme)) {
1410
- return true;
1411
- }
1412
- if (lexeme == "/") {
1413
- // If it's a // comment, skip everything until the next line-feed.
1414
- if (this._peekAhead() == "/") {
1415
- while (lexeme != "\n") {
1416
- if (this._isAtEnd())
1417
- return true;
1418
- lexeme = this._advance();
1419
- }
1420
- // skip the linefeed
1421
- this._line++;
1422
- return true;
1423
- }
1424
- else if (this._peekAhead() == "*") {
1425
- // If it's a / * block comment, skip everything until the matching * /,
1426
- // allowing for nested block comments.
1427
- this._advance();
1428
- let commentLevel = 1;
1429
- while (commentLevel > 0) {
1430
- if (this._isAtEnd())
1431
- return true;
1432
- lexeme = this._advance();
1433
- if (lexeme == "\n") {
1434
- this._line++;
1435
- }
1436
- else if (lexeme == "*") {
1437
- if (this._peekAhead() == "/") {
1438
- this._advance();
1439
- commentLevel--;
1440
- if (commentLevel == 0) {
1441
- return true;
1442
- }
1443
- }
1444
- }
1445
- else if (lexeme == "/") {
1446
- if (this._peekAhead() == "*") {
1447
- this._advance();
1448
- commentLevel++;
1449
- }
1450
- }
1451
- }
1452
- return true;
1453
- }
1454
- }
1455
- let matchType = TokenTypes.none;
1456
- for (;;) {
1457
- let matchedType = this._findType(lexeme);
1458
- // An exception to "longest lexeme" rule is '>>'. In the case of 1>>2, it's a
1459
- // shift_right.
1460
- // In the case of array<vec4<f32>>, it's two greater_than's (one to close the vec4,
1461
- // and one to close the array).
1462
- // Another ambiguity is '>='. In the case of vec2<i32>=vec2(1,2),
1463
- // it's a greather_than and an equal, not a greater_than_equal.
1464
- // WGSL requires context sensitive parsing to resolve these ambiguities. Both of these cases
1465
- // are predicated on it the > either closing a template, or being part of an operator.
1466
- // The solution here is to check if there was a less_than up to some number of tokens
1467
- // previously, and the token prior to that is a keyword that requires a '<', then it will be
1468
- // split into two operators; otherwise it's a single operator.
1469
- const nextLexeme = this._peekAhead();
1470
- if (lexeme == ">" && (nextLexeme == ">" || nextLexeme == "=")) {
1471
- let foundLessThan = false;
1472
- let ti = this._tokens.length - 1;
1473
- for (let count = 0; count < 5 && ti >= 0; ++count, --ti) {
1474
- if (this._tokens[ti].type === TokenTypes.tokens.less_than) {
1475
- if (ti > 0 && this._tokens[ti - 1].isArrayOrTemplateType()) {
1476
- foundLessThan = true;
1477
- }
1478
- break;
1479
- }
1480
- }
1481
- // If there was a less_than in the recent token history, then this is probably a
1482
- // greater_than.
1483
- if (foundLessThan) {
1484
- this._addToken(matchedType);
1485
- return true;
1486
- }
1487
- }
1488
- // The current lexeme may not match any rule, but some token types may be invalid for
1489
- // part of the string but valid after a few more characters.
1490
- // For example, 0x.5 is a hex_float_literal. But as it's being scanned,
1491
- // "0" is a int_literal, then "0x" is invalid. If we stopped there, it would return
1492
- // the int_literal "0", but that's incorrect. So if we look forward a few characters,
1493
- // we'd get "0x.", which is still invalid, followed by "0x.5" which is the correct
1494
- // hex_float_literal. So that means if we hit an non-matching string, we should look
1495
- // ahead up to two characters to see if the string starts matching a valid rule again.
1496
- if (matchedType === TokenTypes.none) {
1497
- let lookAheadLexeme = lexeme;
1498
- let lookAhead = 0;
1499
- const maxLookAhead = 2;
1500
- for (let li = 0; li < maxLookAhead; ++li) {
1501
- lookAheadLexeme += this._peekAhead(li);
1502
- matchedType = this._findType(lookAheadLexeme);
1503
- if (matchedType !== TokenTypes.none) {
1504
- lookAhead = li;
1505
- break;
1506
- }
1507
- }
1508
- if (matchedType === TokenTypes.none) {
1509
- if (matchType === TokenTypes.none)
1510
- return false;
1511
- this._current--;
1512
- this._addToken(matchType);
1513
- return true;
1514
- }
1515
- lexeme = lookAheadLexeme;
1516
- this._current += lookAhead + 1;
1517
- }
1518
- matchType = matchedType;
1519
- if (this._isAtEnd())
1520
- break;
1521
- lexeme += this._advance();
1522
- }
1523
- // We got to the end of the input stream. Then the token we've ready so far is it.
1524
- if (matchType === TokenTypes.none)
1525
- return false;
1526
- this._addToken(matchType);
1527
- return true;
1528
- }
1529
- _findType(lexeme) {
1530
- for (const name in TokenTypes.keywords) {
1531
- const type = TokenTypes.keywords[name];
1532
- if (this._match(lexeme, type.rule)) {
1533
- return type;
1534
- }
1535
- }
1536
- for (const name in TokenTypes.tokens) {
1537
- const type = TokenTypes.tokens[name];
1538
- if (this._match(lexeme, type.rule)) {
1539
- return type;
1540
- }
1541
- }
1542
- return TokenTypes.none;
1543
- }
1544
- _match(lexeme, rule) {
1545
- if (typeof rule === "string") {
1546
- if (rule == lexeme) {
1547
- return true;
1548
- }
1549
- }
1550
- else {
1551
- // regex
1552
- const match = rule.exec(lexeme);
1553
- if (match && match.index == 0 && match[0] == lexeme)
1554
- return true;
1555
- }
1556
- return false;
1557
- }
1558
- _isAtEnd() {
1559
- return this._current >= this._source.length;
1560
- }
1561
- _isWhitespace(c) {
1562
- return c == " " || c == "\t" || c == "\r";
1563
- }
1564
- _advance(amount = 0) {
1565
- let c = this._source[this._current];
1566
- amount = amount || 0;
1567
- amount++;
1568
- this._current += amount;
1569
- return c;
1570
- }
1571
- _peekAhead(offset = 0) {
1572
- offset = offset || 0;
1573
- if (this._current + offset >= this._source.length)
1574
- return "\0";
1575
- return this._source[this._current + offset];
1576
- }
1577
- _addToken(type) {
1578
- const text = this._source.substring(this._start, this._current);
1579
- this._tokens.push(new Token(type, text, this._line));
1580
- }
1581
- }
1582
-
1583
- /**
1584
- * @author Brendan Duncan / https://github.com/brendan-duncan
1585
- */
1586
- /// Parse a sequence of tokens from the WgslScanner into an Abstract Syntax Tree (AST).
1587
- class WgslParser {
1588
- constructor() {
1589
- this._tokens = [];
1590
- this._current = 0;
1591
- this._context = new ParseContext();
1592
- }
1593
- parse(tokensOrCode) {
1594
- this._initialize(tokensOrCode);
1595
- let statements = [];
1596
- while (!this._isAtEnd()) {
1597
- const statement = this._global_decl_or_directive();
1598
- if (!statement)
1599
- break;
1600
- statements.push(statement);
1601
- }
1602
- return statements;
1603
- }
1604
- _initialize(tokensOrCode) {
1605
- if (tokensOrCode) {
1606
- if (typeof tokensOrCode == "string") {
1607
- const scanner = new WgslScanner(tokensOrCode);
1608
- this._tokens = scanner.scanTokens();
1609
- }
1610
- else {
1611
- this._tokens = tokensOrCode;
1612
- }
1613
- }
1614
- else {
1615
- this._tokens = [];
1616
- }
1617
- this._current = 0;
1618
- }
1619
- _error(token, message) {
1620
- console.error(token, message);
1621
- return {
1622
- token,
1623
- message,
1624
- toString: function () {
1625
- return `${message}`;
1626
- },
1627
- };
1628
- }
1629
- _isAtEnd() {
1630
- return (this._current >= this._tokens.length ||
1631
- this._peek().type == TokenTypes.eof);
1632
- }
1633
- _match(types) {
1634
- if (types instanceof TokenType) {
1635
- if (this._check(types)) {
1636
- this._advance();
1637
- return true;
1638
- }
1639
- return false;
1640
- }
1641
- for (let i = 0, l = types.length; i < l; ++i) {
1642
- const type = types[i];
1643
- if (this._check(type)) {
1644
- this._advance();
1645
- return true;
1646
- }
1647
- }
1648
- return false;
1649
- }
1650
- _consume(types, message) {
1651
- if (this._check(types))
1652
- return this._advance();
1653
- throw this._error(this._peek(), message);
1654
- }
1655
- _check(types) {
1656
- if (this._isAtEnd())
1657
- return false;
1658
- const tk = this._peek();
1659
- if (types instanceof Array) {
1660
- let t = tk.type;
1661
- let index = types.indexOf(t);
1662
- return index != -1;
1663
- }
1664
- return tk.type == types;
1665
- }
1666
- _advance() {
1667
- if (!this._isAtEnd())
1668
- this._current++;
1669
- return this._previous();
1670
- }
1671
- _peek() {
1672
- return this._tokens[this._current];
1673
- }
1674
- _previous() {
1675
- return this._tokens[this._current - 1];
1676
- }
1677
- _global_decl_or_directive() {
1678
- // semicolon
1679
- // global_variable_decl semicolon
1680
- // global_constant_decl semicolon
1681
- // type_alias semicolon
1682
- // struct_decl
1683
- // function_decl
1684
- // enable_directive
1685
- // Ignore any stand-alone semicolons
1686
- while (this._match(TokenTypes.tokens.semicolon) && !this._isAtEnd())
1687
- ;
1688
- if (this._match(TokenTypes.keywords.alias)) {
1689
- const type = this._type_alias();
1690
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
1691
- return type;
1692
- }
1693
- if (this._match(TokenTypes.keywords.enable)) {
1694
- const enable = this._enable_directive();
1695
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
1696
- return enable;
1697
- }
1698
- // The following statements have an optional attribute*
1699
- const attrs = this._attribute();
1700
- if (this._check(TokenTypes.keywords.var)) {
1701
- const _var = this._global_variable_decl();
1702
- if (_var != null)
1703
- _var.attributes = attrs;
1704
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
1705
- return _var;
1706
- }
1707
- if (this._check(TokenTypes.keywords.override)) {
1708
- const _override = this._override_variable_decl();
1709
- if (_override != null)
1710
- _override.attributes = attrs;
1711
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
1712
- return _override;
1713
- }
1714
- if (this._check(TokenTypes.keywords.let)) {
1715
- const _let = this._global_let_decl();
1716
- if (_let != null)
1717
- _let.attributes = attrs;
1718
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
1719
- return _let;
1720
- }
1721
- if (this._check(TokenTypes.keywords.const)) {
1722
- const _const = this._global_const_decl();
1723
- if (_const != null)
1724
- _const.attributes = attrs;
1725
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
1726
- return _const;
1727
- }
1728
- if (this._check(TokenTypes.keywords.struct)) {
1729
- const _struct = this._struct_decl();
1730
- if (_struct != null)
1731
- _struct.attributes = attrs;
1732
- return _struct;
1733
- }
1734
- if (this._check(TokenTypes.keywords.fn)) {
1735
- const _fn = this._function_decl();
1736
- if (_fn != null)
1737
- _fn.attributes = attrs;
1738
- return _fn;
1739
- }
1740
- return null;
1741
- }
1742
- _function_decl() {
1743
- // attribute* function_header compound_statement
1744
- // function_header: fn ident paren_left param_list? paren_right (arrow attribute* type_decl)?
1745
- if (!this._match(TokenTypes.keywords.fn))
1746
- return null;
1747
- const name = this._consume(TokenTypes.tokens.ident, "Expected function name.").toString();
1748
- this._consume(TokenTypes.tokens.paren_left, "Expected '(' for function arguments.");
1749
- const args = [];
1750
- if (!this._check(TokenTypes.tokens.paren_right)) {
1751
- do {
1752
- if (this._check(TokenTypes.tokens.paren_right))
1753
- break;
1754
- const argAttrs = this._attribute();
1755
- const name = this._consume(TokenTypes.tokens.ident, "Expected argument name.").toString();
1756
- this._consume(TokenTypes.tokens.colon, "Expected ':' for argument type.");
1757
- const typeAttrs = this._attribute();
1758
- const type = this._type_decl();
1759
- if (type != null) {
1760
- type.attributes = typeAttrs;
1761
- args.push(new Argument(name, type, argAttrs));
1762
- }
1763
- } while (this._match(TokenTypes.tokens.comma));
1764
- }
1765
- this._consume(TokenTypes.tokens.paren_right, "Expected ')' after function arguments.");
1766
- let _return = null;
1767
- if (this._match(TokenTypes.tokens.arrow)) {
1768
- const attrs = this._attribute();
1769
- _return = this._type_decl();
1770
- if (_return != null)
1771
- _return.attributes = attrs;
1772
- }
1773
- const body = this._compound_statement();
1774
- return new Function(name, args, _return, body);
1775
- }
1776
- _compound_statement() {
1777
- // brace_left statement* brace_right
1778
- const statements = [];
1779
- this._consume(TokenTypes.tokens.brace_left, "Expected '{' for block.");
1780
- while (!this._check(TokenTypes.tokens.brace_right)) {
1781
- const statement = this._statement();
1782
- if (statement !== null)
1783
- statements.push(statement);
1784
- }
1785
- this._consume(TokenTypes.tokens.brace_right, "Expected '}' for block.");
1786
- return statements;
1787
- }
1788
- _statement() {
1789
- // semicolon
1790
- // return_statement semicolon
1791
- // if_statement
1792
- // switch_statement
1793
- // loop_statement
1794
- // for_statement
1795
- // func_call_statement semicolon
1796
- // variable_statement semicolon
1797
- // break_statement semicolon
1798
- // continue_statement semicolon
1799
- // continuing_statement compound_statement
1800
- // discard semicolon
1801
- // assignment_statement semicolon
1802
- // compound_statement
1803
- // increment_statement semicolon
1804
- // decrement_statement semicolon
1805
- // static_assert_statement semicolon
1806
- // Ignore any stand-alone semicolons
1807
- while (this._match(TokenTypes.tokens.semicolon) && !this._isAtEnd())
1808
- ;
1809
- if (this._check(TokenTypes.keywords.if))
1810
- return this._if_statement();
1811
- if (this._check(TokenTypes.keywords.switch))
1812
- return this._switch_statement();
1813
- if (this._check(TokenTypes.keywords.loop))
1814
- return this._loop_statement();
1815
- if (this._check(TokenTypes.keywords.for))
1816
- return this._for_statement();
1817
- if (this._check(TokenTypes.keywords.while))
1818
- return this._while_statement();
1819
- if (this._check(TokenTypes.keywords.continuing))
1820
- return this._continuing_statement();
1821
- if (this._check(TokenTypes.keywords.static_assert))
1822
- return this._static_assert_statement();
1823
- if (this._check(TokenTypes.tokens.brace_left))
1824
- return this._compound_statement();
1825
- let result = null;
1826
- if (this._check(TokenTypes.keywords.return))
1827
- result = this._return_statement();
1828
- else if (this._check([
1829
- TokenTypes.keywords.var,
1830
- TokenTypes.keywords.let,
1831
- TokenTypes.keywords.const,
1832
- ]))
1833
- result = this._variable_statement();
1834
- else if (this._match(TokenTypes.keywords.discard))
1835
- result = new Discard();
1836
- else if (this._match(TokenTypes.keywords.break))
1837
- result = new Break();
1838
- else if (this._match(TokenTypes.keywords.continue))
1839
- result = new Continue();
1840
- else
1841
- result =
1842
- this._increment_decrement_statement() ||
1843
- this._func_call_statement() ||
1844
- this._assignment_statement();
1845
- if (result != null)
1846
- this._consume(TokenTypes.tokens.semicolon, "Expected ';' after statement.");
1847
- return result;
1848
- }
1849
- _static_assert_statement() {
1850
- if (!this._match(TokenTypes.keywords.static_assert))
1851
- return null;
1852
- let expression = this._optional_paren_expression();
1853
- return new StaticAssert(expression);
1854
- }
1855
- _while_statement() {
1856
- if (!this._match(TokenTypes.keywords.while))
1857
- return null;
1858
- let condition = this._optional_paren_expression();
1859
- const block = this._compound_statement();
1860
- return new While(condition, block);
1861
- }
1862
- _continuing_statement() {
1863
- if (!this._match(TokenTypes.keywords.continuing))
1864
- return null;
1865
- const block = this._compound_statement();
1866
- return new Continuing(block);
1867
- }
1868
- _for_statement() {
1869
- // for paren_left for_header paren_right compound_statement
1870
- if (!this._match(TokenTypes.keywords.for))
1871
- return null;
1872
- this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
1873
- // for_header: (variable_statement assignment_statement func_call_statement)? semicolon short_circuit_or_expression? semicolon (assignment_statement func_call_statement)?
1874
- const init = !this._check(TokenTypes.tokens.semicolon)
1875
- ? this._for_init()
1876
- : null;
1877
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
1878
- const condition = !this._check(TokenTypes.tokens.semicolon)
1879
- ? this._short_circuit_or_expression()
1880
- : null;
1881
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
1882
- const increment = !this._check(TokenTypes.tokens.paren_right)
1883
- ? this._for_increment()
1884
- : null;
1885
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
1886
- const body = this._compound_statement();
1887
- return new For(init, condition, increment, body);
1888
- }
1889
- _for_init() {
1890
- // (variable_statement assignment_statement func_call_statement)?
1891
- return (this._variable_statement() ||
1892
- this._func_call_statement() ||
1893
- this._assignment_statement());
1894
- }
1895
- _for_increment() {
1896
- // (assignment_statement func_call_statement increment_statement)?
1897
- return (this._func_call_statement() ||
1898
- this._increment_decrement_statement() ||
1899
- this._assignment_statement());
1900
- }
1901
- _variable_statement() {
1902
- // variable_decl
1903
- // variable_decl equal short_circuit_or_expression
1904
- // let (ident variable_ident_decl) equal short_circuit_or_expression
1905
- // const (ident variable_ident_decl) equal short_circuit_or_expression
1906
- if (this._check(TokenTypes.keywords.var)) {
1907
- const _var = this._variable_decl();
1908
- if (_var === null)
1909
- throw this._error(this._peek(), "Variable declaration expected.");
1910
- let value = null;
1911
- if (this._match(TokenTypes.tokens.equal))
1912
- value = this._short_circuit_or_expression();
1913
- return new Var(_var.name, _var.type, _var.storage, _var.access, value);
1914
- }
1915
- if (this._match(TokenTypes.keywords.let)) {
1916
- const name = this._consume(TokenTypes.tokens.ident, "Expected name for let.").toString();
1917
- let type = null;
1918
- if (this._match(TokenTypes.tokens.colon)) {
1919
- const typeAttrs = this._attribute();
1920
- type = this._type_decl();
1921
- if (type != null)
1922
- type.attributes = typeAttrs;
1923
- }
1924
- this._consume(TokenTypes.tokens.equal, "Expected '=' for let.");
1925
- const value = this._short_circuit_or_expression();
1926
- return new Let(name, type, null, null, value);
1927
- }
1928
- if (this._match(TokenTypes.keywords.const)) {
1929
- const name = this._consume(TokenTypes.tokens.ident, "Expected name for const.").toString();
1930
- let type = null;
1931
- if (this._match(TokenTypes.tokens.colon)) {
1932
- const typeAttrs = this._attribute();
1933
- type = this._type_decl();
1934
- if (type != null)
1935
- type.attributes = typeAttrs;
1936
- }
1937
- this._consume(TokenTypes.tokens.equal, "Expected '=' for const.");
1938
- const value = this._short_circuit_or_expression();
1939
- return new Const(name, type, null, null, value);
1940
- }
1941
- return null;
1942
- }
1943
- _increment_decrement_statement() {
1944
- const savedPos = this._current;
1945
- const _var = this._unary_expression();
1946
- if (_var == null)
1947
- return null;
1948
- if (!this._check(TokenTypes.increment_operators)) {
1949
- this._current = savedPos;
1950
- return null;
1951
- }
1952
- const token = this._consume(TokenTypes.increment_operators, "Expected increment operator");
1953
- return new Increment(token.type === TokenTypes.tokens.plus_plus
1954
- ? IncrementOperator.increment
1955
- : IncrementOperator.decrement, _var);
1956
- }
1957
- _assignment_statement() {
1958
- // (unary_expression underscore) equal short_circuit_or_expression
1959
- let _var = null;
1960
- if (this._check(TokenTypes.tokens.brace_right))
1961
- return null;
1962
- let isUnderscore = this._match(TokenTypes.tokens.underscore);
1963
- if (!isUnderscore)
1964
- _var = this._unary_expression();
1965
- if (!isUnderscore && _var == null)
1966
- return null;
1967
- const type = this._consume(TokenTypes.assignment_operators, "Expected assignment operator.");
1968
- const value = this._short_circuit_or_expression();
1969
- return new Assign(AssignOperator.parse(type.lexeme), _var, value);
1970
- }
1971
- _func_call_statement() {
1972
- // ident argument_expression_list
1973
- if (!this._check(TokenTypes.tokens.ident))
1974
- return null;
1975
- const savedPos = this._current;
1976
- const name = this._consume(TokenTypes.tokens.ident, "Expected function name.");
1977
- const args = this._argument_expression_list();
1978
- if (args === null) {
1979
- this._current = savedPos;
1980
- return null;
1981
- }
1982
- return new Call(name.lexeme, args);
1983
- }
1984
- _loop_statement() {
1985
- // loop brace_left statement* continuing_statement? brace_right
1986
- if (!this._match(TokenTypes.keywords.loop))
1987
- return null;
1988
- this._consume(TokenTypes.tokens.brace_left, "Expected '{' for loop.");
1989
- // statement*
1990
- const statements = [];
1991
- let statement = this._statement();
1992
- while (statement !== null) {
1993
- if (Array.isArray(statement)) {
1994
- for (let s of statement) {
1995
- statements.push(s);
1996
- }
1997
- }
1998
- else {
1999
- statements.push(statement);
2000
- }
2001
- statement = this._statement();
2002
- }
2003
- // continuing_statement: continuing compound_statement
2004
- let continuing = null;
2005
- if (this._match(TokenTypes.keywords.continuing))
2006
- continuing = this._compound_statement();
2007
- this._consume(TokenTypes.tokens.brace_right, "Expected '}' for loop.");
2008
- return new Loop(statements, continuing);
2009
- }
2010
- _switch_statement() {
2011
- // switch optional_paren_expression brace_left switch_body+ brace_right
2012
- if (!this._match(TokenTypes.keywords.switch))
2013
- return null;
2014
- const condition = this._optional_paren_expression();
2015
- this._consume(TokenTypes.tokens.brace_left, "Expected '{' for switch.");
2016
- const body = this._switch_body();
2017
- if (body == null || body.length == 0)
2018
- throw this._error(this._previous(), "Expected 'case' or 'default'.");
2019
- this._consume(TokenTypes.tokens.brace_right, "Expected '}' for switch.");
2020
- return new Switch(condition, body);
2021
- }
2022
- _switch_body() {
2023
- // case case_selectors colon brace_left case_body? brace_right
2024
- // default colon brace_left case_body? brace_right
2025
- const cases = [];
2026
- if (this._match(TokenTypes.keywords.case)) {
2027
- const selector = this._case_selectors();
2028
- this._match(TokenTypes.tokens.colon); // colon is optional
2029
- this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch case.");
2030
- const body = this._case_body();
2031
- this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch case.");
2032
- cases.push(new Case(selector, body));
2033
- }
2034
- if (this._match(TokenTypes.keywords.default)) {
2035
- this._match(TokenTypes.tokens.colon); // colon is optional
2036
- this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch default.");
2037
- const body = this._case_body();
2038
- this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch default.");
2039
- cases.push(new Default(body));
2040
- }
2041
- if (this._check([TokenTypes.keywords.default, TokenTypes.keywords.case])) {
2042
- const _cases = this._switch_body();
2043
- cases.push(_cases[0]);
2044
- }
2045
- return cases;
2046
- }
2047
- _case_selectors() {
2048
- var _a, _b, _c, _d;
2049
- // const_literal (comma const_literal)* comma?
2050
- const selectors = [
2051
- (_b = (_a = this._shift_expression()) === null || _a === void 0 ? void 0 : _a.evaluate(this._context).toString()) !== null && _b !== void 0 ? _b : "",
2052
- ];
2053
- while (this._match(TokenTypes.tokens.comma)) {
2054
- selectors.push((_d = (_c = this._shift_expression()) === null || _c === void 0 ? void 0 : _c.evaluate(this._context).toString()) !== null && _d !== void 0 ? _d : "");
2055
- }
2056
- return selectors;
2057
- }
2058
- _case_body() {
2059
- // statement case_body?
2060
- // fallthrough semicolon
2061
- if (this._match(TokenTypes.keywords.fallthrough)) {
2062
- this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
2063
- return [];
2064
- }
2065
- let statement = this._statement();
2066
- if (statement == null)
2067
- return [];
2068
- if (!(statement instanceof Array)) {
2069
- statement = [statement];
2070
- }
2071
- const nextStatement = this._case_body();
2072
- if (nextStatement.length == 0)
2073
- return statement;
2074
- return [...statement, nextStatement[0]];
2075
- }
2076
- _if_statement() {
2077
- // if optional_paren_expression compound_statement elseif_statement? else_statement?
2078
- if (!this._match(TokenTypes.keywords.if))
2079
- return null;
2080
- const condition = this._optional_paren_expression();
2081
- const block = this._compound_statement();
2082
- let elseif = [];
2083
- if (this._match_elseif()) {
2084
- elseif = this._elseif_statement(elseif);
2085
- }
2086
- let _else = null;
2087
- if (this._match(TokenTypes.keywords.else))
2088
- _else = this._compound_statement();
2089
- return new If(condition, block, elseif, _else);
2090
- }
2091
- _match_elseif() {
2092
- if (this._tokens[this._current].type === TokenTypes.keywords.else &&
2093
- this._tokens[this._current + 1].type === TokenTypes.keywords.if) {
2094
- this._advance();
2095
- this._advance();
2096
- return true;
2097
- }
2098
- return false;
2099
- }
2100
- _elseif_statement(elseif = []) {
2101
- // else_if optional_paren_expression compound_statement elseif_statement?
2102
- const condition = this._optional_paren_expression();
2103
- const block = this._compound_statement();
2104
- elseif.push(new ElseIf(condition, block));
2105
- if (this._match_elseif()) {
2106
- this._elseif_statement(elseif);
2107
- }
2108
- return elseif;
2109
- }
2110
- _return_statement() {
2111
- // return short_circuit_or_expression?
2112
- if (!this._match(TokenTypes.keywords.return))
2113
- return null;
2114
- const value = this._short_circuit_or_expression();
2115
- return new Return(value);
2116
- }
2117
- _short_circuit_or_expression() {
2118
- // short_circuit_and_expression
2119
- // short_circuit_or_expression or_or short_circuit_and_expression
2120
- let expr = this._short_circuit_and_expr();
2121
- while (this._match(TokenTypes.tokens.or_or)) {
2122
- expr = new BinaryOperator(this._previous().toString(), expr, this._short_circuit_and_expr());
2123
- }
2124
- return expr;
2125
- }
2126
- _short_circuit_and_expr() {
2127
- // inclusive_or_expression
2128
- // short_circuit_and_expression and_and inclusive_or_expression
2129
- let expr = this._inclusive_or_expression();
2130
- while (this._match(TokenTypes.tokens.and_and)) {
2131
- expr = new BinaryOperator(this._previous().toString(), expr, this._inclusive_or_expression());
2132
- }
2133
- return expr;
2134
- }
2135
- _inclusive_or_expression() {
2136
- // exclusive_or_expression
2137
- // inclusive_or_expression or exclusive_or_expression
2138
- let expr = this._exclusive_or_expression();
2139
- while (this._match(TokenTypes.tokens.or)) {
2140
- expr = new BinaryOperator(this._previous().toString(), expr, this._exclusive_or_expression());
2141
- }
2142
- return expr;
2143
- }
2144
- _exclusive_or_expression() {
2145
- // and_expression
2146
- // exclusive_or_expression xor and_expression
2147
- let expr = this._and_expression();
2148
- while (this._match(TokenTypes.tokens.xor)) {
2149
- expr = new BinaryOperator(this._previous().toString(), expr, this._and_expression());
2150
- }
2151
- return expr;
2152
- }
2153
- _and_expression() {
2154
- // equality_expression
2155
- // and_expression and equality_expression
2156
- let expr = this._equality_expression();
2157
- while (this._match(TokenTypes.tokens.and)) {
2158
- expr = new BinaryOperator(this._previous().toString(), expr, this._equality_expression());
2159
- }
2160
- return expr;
2161
- }
2162
- _equality_expression() {
2163
- // relational_expression
2164
- // relational_expression equal_equal relational_expression
2165
- // relational_expression not_equal relational_expression
2166
- const expr = this._relational_expression();
2167
- if (this._match([TokenTypes.tokens.equal_equal, TokenTypes.tokens.not_equal])) {
2168
- return new BinaryOperator(this._previous().toString(), expr, this._relational_expression());
2169
- }
2170
- return expr;
2171
- }
2172
- _relational_expression() {
2173
- // shift_expression
2174
- // relational_expression less_than shift_expression
2175
- // relational_expression greater_than shift_expression
2176
- // relational_expression less_than_equal shift_expression
2177
- // relational_expression greater_than_equal shift_expression
2178
- let expr = this._shift_expression();
2179
- while (this._match([
2180
- TokenTypes.tokens.less_than,
2181
- TokenTypes.tokens.greater_than,
2182
- TokenTypes.tokens.less_than_equal,
2183
- TokenTypes.tokens.greater_than_equal,
2184
- ])) {
2185
- expr = new BinaryOperator(this._previous().toString(), expr, this._shift_expression());
2186
- }
2187
- return expr;
2188
- }
2189
- _shift_expression() {
2190
- // additive_expression
2191
- // shift_expression shift_left additive_expression
2192
- // shift_expression shift_right additive_expression
2193
- let expr = this._additive_expression();
2194
- while (this._match([TokenTypes.tokens.shift_left, TokenTypes.tokens.shift_right])) {
2195
- expr = new BinaryOperator(this._previous().toString(), expr, this._additive_expression());
2196
- }
2197
- return expr;
2198
- }
2199
- _additive_expression() {
2200
- // multiplicative_expression
2201
- // additive_expression plus multiplicative_expression
2202
- // additive_expression minus multiplicative_expression
2203
- let expr = this._multiplicative_expression();
2204
- while (this._match([TokenTypes.tokens.plus, TokenTypes.tokens.minus])) {
2205
- expr = new BinaryOperator(this._previous().toString(), expr, this._multiplicative_expression());
2206
- }
2207
- return expr;
2208
- }
2209
- _multiplicative_expression() {
2210
- // unary_expression
2211
- // multiplicative_expression star unary_expression
2212
- // multiplicative_expression forward_slash unary_expression
2213
- // multiplicative_expression modulo unary_expression
2214
- let expr = this._unary_expression();
2215
- while (this._match([
2216
- TokenTypes.tokens.star,
2217
- TokenTypes.tokens.forward_slash,
2218
- TokenTypes.tokens.modulo,
2219
- ])) {
2220
- expr = new BinaryOperator(this._previous().toString(), expr, this._unary_expression());
2221
- }
2222
- return expr;
2223
- }
2224
- _unary_expression() {
2225
- // singular_expression
2226
- // minus unary_expression
2227
- // bang unary_expression
2228
- // tilde unary_expression
2229
- // star unary_expression
2230
- // and unary_expression
2231
- if (this._match([
2232
- TokenTypes.tokens.minus,
2233
- TokenTypes.tokens.bang,
2234
- TokenTypes.tokens.tilde,
2235
- TokenTypes.tokens.star,
2236
- TokenTypes.tokens.and,
2237
- ])) {
2238
- return new UnaryOperator(this._previous().toString(), this._unary_expression());
2239
- }
2240
- return this._singular_expression();
2241
- }
2242
- _singular_expression() {
2243
- // primary_expression postfix_expression ?
2244
- const expr = this._primary_expression();
2245
- const p = this._postfix_expression();
2246
- if (p)
2247
- expr.postfix = p;
2248
- return expr;
2249
- }
2250
- _postfix_expression() {
2251
- // bracket_left short_circuit_or_expression bracket_right postfix_expression?
2252
- if (this._match(TokenTypes.tokens.bracket_left)) {
2253
- const expr = this._short_circuit_or_expression();
2254
- this._consume(TokenTypes.tokens.bracket_right, "Expected ']'.");
2255
- const p = this._postfix_expression();
2256
- if (p)
2257
- expr.postfix = p;
2258
- return expr;
2259
- }
2260
- // period ident postfix_expression?
2261
- if (this._match(TokenTypes.tokens.period)) {
2262
- const name = this._consume(TokenTypes.tokens.ident, "Expected member name.");
2263
- const p = this._postfix_expression();
2264
- const expr = new StringExpr(name.lexeme);
2265
- if (p)
2266
- expr.postfix = p;
2267
- return expr;
2268
- }
2269
- return null;
2270
- }
2271
- _getStruct(name) {
2272
- if (this._context.aliases.has(name)) {
2273
- const alias = this._context.aliases.get(name).type;
2274
- return alias;
2275
- }
2276
- if (this._context.structs.has(name)) {
2277
- const struct = this._context.structs.get(name);
2278
- return struct;
2279
- }
2280
- return null;
2281
- }
2282
- _primary_expression() {
2283
- // ident argument_expression_list?
2284
- if (this._match(TokenTypes.tokens.ident)) {
2285
- const name = this._previous().toString();
2286
- if (this._check(TokenTypes.tokens.paren_left)) {
2287
- const args = this._argument_expression_list();
2288
- const struct = this._getStruct(name);
2289
- if (struct != null) {
2290
- return new CreateExpr(struct, args);
2291
- }
2292
- return new CallExpr(name, args);
2293
- }
2294
- if (this._context.constants.has(name)) {
2295
- const c = this._context.constants.get(name);
2296
- return new ConstExpr(name, c.value);
2297
- }
2298
- return new VariableExpr(name);
2299
- }
2300
- // const_literal
2301
- if (this._match(TokenTypes.const_literal)) {
2302
- return new LiteralExpr(parseFloat(this._previous().toString()));
2303
- }
2304
- // paren_expression
2305
- if (this._check(TokenTypes.tokens.paren_left)) {
2306
- return this._paren_expression();
2307
- }
2308
- // bitcast less_than type_decl greater_than paren_expression
2309
- if (this._match(TokenTypes.keywords.bitcast)) {
2310
- this._consume(TokenTypes.tokens.less_than, "Expected '<'.");
2311
- const type = this._type_decl();
2312
- this._consume(TokenTypes.tokens.greater_than, "Expected '>'.");
2313
- const value = this._paren_expression();
2314
- return new BitcastExpr(type, value);
2315
- }
2316
- // type_decl argument_expression_list
2317
- const type = this._type_decl();
2318
- const args = this._argument_expression_list();
2319
- return new TypecastExpr(type, args);
2320
- }
2321
- _argument_expression_list() {
2322
- // paren_left ((short_circuit_or_expression comma)* short_circuit_or_expression comma?)? paren_right
2323
- if (!this._match(TokenTypes.tokens.paren_left))
2324
- return null;
2325
- const args = [];
2326
- do {
2327
- if (this._check(TokenTypes.tokens.paren_right))
2328
- break;
2329
- const arg = this._short_circuit_or_expression();
2330
- args.push(arg);
2331
- } while (this._match(TokenTypes.tokens.comma));
2332
- this._consume(TokenTypes.tokens.paren_right, "Expected ')' for agument list");
2333
- return args;
2334
- }
2335
- _optional_paren_expression() {
2336
- // [paren_left] short_circuit_or_expression [paren_right]
2337
- this._match(TokenTypes.tokens.paren_left);
2338
- const expr = this._short_circuit_or_expression();
2339
- this._match(TokenTypes.tokens.paren_right);
2340
- return new GroupingExpr([expr]);
2341
- }
2342
- _paren_expression() {
2343
- // paren_left short_circuit_or_expression paren_right
2344
- this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
2345
- const expr = this._short_circuit_or_expression();
2346
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
2347
- return new GroupingExpr([expr]);
2348
- }
2349
- _struct_decl() {
2350
- // attribute* struct ident struct_body_decl
2351
- if (!this._match(TokenTypes.keywords.struct))
2352
- return null;
2353
- const name = this._consume(TokenTypes.tokens.ident, "Expected name for struct.").toString();
2354
- // struct_body_decl: brace_left (struct_member comma)* struct_member comma? brace_right
2355
- this._consume(TokenTypes.tokens.brace_left, "Expected '{' for struct body.");
2356
- const members = [];
2357
- while (!this._check(TokenTypes.tokens.brace_right)) {
2358
- // struct_member: attribute* variable_ident_decl
2359
- const memberAttrs = this._attribute();
2360
- const memberName = this._consume(TokenTypes.tokens.ident, "Expected variable name.").toString();
2361
- this._consume(TokenTypes.tokens.colon, "Expected ':' for struct member type.");
2362
- const typeAttrs = this._attribute();
2363
- const memberType = this._type_decl();
2364
- if (memberType != null)
2365
- memberType.attributes = typeAttrs;
2366
- if (!this._check(TokenTypes.tokens.brace_right))
2367
- this._consume(TokenTypes.tokens.comma, "Expected ',' for struct member.");
2368
- else
2369
- this._match(TokenTypes.tokens.comma); // trailing comma optional.
2370
- members.push(new Member(memberName, memberType, memberAttrs));
2371
- }
2372
- this._consume(TokenTypes.tokens.brace_right, "Expected '}' after struct body.");
2373
- const structNode = new Struct(name, members);
2374
- this._context.structs.set(name, structNode);
2375
- return structNode;
2376
- }
2377
- _global_variable_decl() {
2378
- // attribute* variable_decl (equal const_expression)?
2379
- const _var = this._variable_decl();
2380
- if (_var && this._match(TokenTypes.tokens.equal))
2381
- _var.value = this._const_expression();
2382
- return _var;
2383
- }
2384
- _override_variable_decl() {
2385
- // attribute* override_decl (equal const_expression)?
2386
- const _override = this._override_decl();
2387
- if (_override && this._match(TokenTypes.tokens.equal))
2388
- _override.value = this._const_expression();
2389
- return _override;
2390
- }
2391
- _global_const_decl() {
2392
- // attribute* const (ident variable_ident_decl) global_const_initializer?
2393
- if (!this._match(TokenTypes.keywords.const))
2394
- return null;
2395
- const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
2396
- let type = null;
2397
- if (this._match(TokenTypes.tokens.colon)) {
2398
- const attrs = this._attribute();
2399
- type = this._type_decl();
2400
- if (type != null)
2401
- type.attributes = attrs;
2402
- }
2403
- let value = null;
2404
- if (this._match(TokenTypes.tokens.equal)) {
2405
- const valueExpr = this._short_circuit_or_expression();
2406
- if (valueExpr instanceof CreateExpr) {
2407
- value = valueExpr;
2408
- }
2409
- else if (valueExpr instanceof ConstExpr &&
2410
- valueExpr.initializer instanceof CreateExpr) {
2411
- value = valueExpr.initializer;
2412
- }
2413
- else {
2414
- try {
2415
- const constValue = valueExpr.evaluate(this._context);
2416
- value = new LiteralExpr(constValue);
2417
- }
2418
- catch (_a) {
2419
- value = valueExpr;
2420
- }
2421
- }
2422
- }
2423
- const c = new Const(name.toString(), type, "", "", value);
2424
- this._context.constants.set(c.name, c);
2425
- return c;
2426
- }
2427
- _global_let_decl() {
2428
- // attribute* let (ident variable_ident_decl) global_const_initializer?
2429
- if (!this._match(TokenTypes.keywords.let))
2430
- return null;
2431
- const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
2432
- let type = null;
2433
- if (this._match(TokenTypes.tokens.colon)) {
2434
- const attrs = this._attribute();
2435
- type = this._type_decl();
2436
- if (type != null)
2437
- type.attributes = attrs;
2438
- }
2439
- let value = null;
2440
- if (this._match(TokenTypes.tokens.equal)) {
2441
- value = this._const_expression();
2442
- }
2443
- return new Let(name.toString(), type, "", "", value);
2444
- }
2445
- _const_expression() {
2446
- // type_decl paren_left ((const_expression comma)* const_expression comma?)? paren_right
2447
- // const_literal
2448
- if (this._match(TokenTypes.const_literal))
2449
- return new StringExpr(this._previous().toString());
2450
- const type = this._type_decl();
2451
- this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
2452
- let args = [];
2453
- while (!this._check(TokenTypes.tokens.paren_right)) {
2454
- args.push(this._const_expression());
2455
- if (!this._check(TokenTypes.tokens.comma))
2456
- break;
2457
- this._advance();
2458
- }
2459
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
2460
- return new CreateExpr(type, args);
2461
- }
2462
- _variable_decl() {
2463
- // var variable_qualifier? (ident variable_ident_decl)
2464
- if (!this._match(TokenTypes.keywords.var))
2465
- return null;
2466
- // variable_qualifier: less_than storage_class (comma access_mode)? greater_than
2467
- let storage = "";
2468
- let access = "";
2469
- if (this._match(TokenTypes.tokens.less_than)) {
2470
- storage = this._consume(TokenTypes.storage_class, "Expected storage_class.").toString();
2471
- if (this._match(TokenTypes.tokens.comma))
2472
- access = this._consume(TokenTypes.access_mode, "Expected access_mode.").toString();
2473
- this._consume(TokenTypes.tokens.greater_than, "Expected '>'.");
2474
- }
2475
- const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
2476
- let type = null;
2477
- if (this._match(TokenTypes.tokens.colon)) {
2478
- const attrs = this._attribute();
2479
- type = this._type_decl();
2480
- if (type != null)
2481
- type.attributes = attrs;
2482
- }
2483
- return new Var(name.toString(), type, storage, access, null);
2484
- }
2485
- _override_decl() {
2486
- // override (ident variable_ident_decl)
2487
- if (!this._match(TokenTypes.keywords.override))
2488
- return null;
2489
- const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
2490
- let type = null;
2491
- if (this._match(TokenTypes.tokens.colon)) {
2492
- const attrs = this._attribute();
2493
- type = this._type_decl();
2494
- if (type != null)
2495
- type.attributes = attrs;
2496
- }
2497
- return new Override(name.toString(), type, null);
2498
- }
2499
- _enable_directive() {
2500
- // enable ident semicolon
2501
- const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
2502
- return new Enable(name.toString());
2503
- }
2504
- _type_alias() {
2505
- // type ident equal type_decl
2506
- const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
2507
- this._consume(TokenTypes.tokens.equal, "Expected '=' for type alias.");
2508
- let aliasType = this._type_decl();
2509
- if (aliasType === null) {
2510
- throw this._error(this._peek(), "Expected Type for Alias.");
2511
- }
2512
- if (this._context.aliases.has(aliasType.name)) {
2513
- aliasType = this._context.aliases.get(aliasType.name).type;
2514
- }
2515
- const aliasNode = new Alias(name.toString(), aliasType);
2516
- this._context.aliases.set(aliasNode.name, aliasNode);
2517
- return aliasNode;
2518
- }
2519
- _type_decl() {
2520
- // ident
2521
- // bool
2522
- // float32
2523
- // int32
2524
- // uint32
2525
- // vec2 less_than type_decl greater_than
2526
- // vec3 less_than type_decl greater_than
2527
- // vec4 less_than type_decl greater_than
2528
- // mat2x2 less_than type_decl greater_than
2529
- // mat2x3 less_than type_decl greater_than
2530
- // mat2x4 less_than type_decl greater_than
2531
- // mat3x2 less_than type_decl greater_than
2532
- // mat3x3 less_than type_decl greater_than
2533
- // mat3x4 less_than type_decl greater_than
2534
- // mat4x2 less_than type_decl greater_than
2535
- // mat4x3 less_than type_decl greater_than
2536
- // mat4x4 less_than type_decl greater_than
2537
- // atomic less_than type_decl greater_than
2538
- // pointer less_than storage_class comma type_decl (comma access_mode)? greater_than
2539
- // array_type_decl
2540
- // texture_sampler_types
2541
- if (this._check([
2542
- TokenTypes.tokens.ident,
2543
- ...TokenTypes.texel_format,
2544
- TokenTypes.keywords.bool,
2545
- TokenTypes.keywords.f32,
2546
- TokenTypes.keywords.i32,
2547
- TokenTypes.keywords.u32,
2548
- ])) {
2549
- const type = this._advance();
2550
- const typeName = type.toString();
2551
- if (this._context.structs.has(typeName)) {
2552
- return this._context.structs.get(typeName);
2553
- }
2554
- if (this._context.aliases.has(typeName)) {
2555
- return this._context.aliases.get(typeName).type;
2556
- }
2557
- return new Type(type.toString());
2558
- }
2559
- // texture_sampler_types
2560
- let type = this._texture_sampler_types();
2561
- if (type)
2562
- return type;
2563
- if (this._check(TokenTypes.template_types)) {
2564
- let type = this._advance().toString();
2565
- let format = null;
2566
- let access = null;
2567
- if (this._match(TokenTypes.tokens.less_than)) {
2568
- format = this._type_decl();
2569
- access = null;
2570
- if (this._match(TokenTypes.tokens.comma))
2571
- access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString();
2572
- this._consume(TokenTypes.tokens.greater_than, "Expected '>' for type.");
2573
- }
2574
- return new TemplateType(type, format, access);
2575
- }
2576
- // pointer less_than storage_class comma type_decl (comma access_mode)? greater_than
2577
- if (this._match(TokenTypes.keywords.ptr)) {
2578
- let pointer = this._previous().toString();
2579
- this._consume(TokenTypes.tokens.less_than, "Expected '<' for pointer.");
2580
- const storage = this._consume(TokenTypes.storage_class, "Expected storage_class for pointer");
2581
- this._consume(TokenTypes.tokens.comma, "Expected ',' for pointer.");
2582
- const decl = this._type_decl();
2583
- let access = null;
2584
- if (this._match(TokenTypes.tokens.comma))
2585
- access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString();
2586
- this._consume(TokenTypes.tokens.greater_than, "Expected '>' for pointer.");
2587
- return new PointerType(pointer, storage.toString(), decl, access);
2588
- }
2589
- // The following type_decl's have an optional attribyte_list*
2590
- const attrs = this._attribute();
2591
- // attribute* array
2592
- // attribute* array less_than type_decl (comma element_count_expression)? greater_than
2593
- if (this._match(TokenTypes.keywords.array)) {
2594
- let format = null;
2595
- let countInt = -1;
2596
- const array = this._previous();
2597
- if (this._match(TokenTypes.tokens.less_than)) {
2598
- format = this._type_decl();
2599
- if (this._context.aliases.has(format.name)) {
2600
- format = this._context.aliases.get(format.name).type;
2601
- }
2602
- let count = "";
2603
- if (this._match(TokenTypes.tokens.comma)) {
2604
- let c = this._shift_expression();
2605
- count = c.evaluate(this._context).toString();
2606
- }
2607
- this._consume(TokenTypes.tokens.greater_than, "Expected '>' for array.");
2608
- countInt = count ? parseInt(count) : 0;
2609
- }
2610
- return new ArrayType(array.toString(), attrs, format, countInt);
2611
- }
2612
- return null;
2613
- }
2614
- _texture_sampler_types() {
2615
- // sampler_type
2616
- if (this._match(TokenTypes.sampler_type))
2617
- return new SamplerType(this._previous().toString(), null, null);
2618
- // depth_texture_type
2619
- if (this._match(TokenTypes.depth_texture_type))
2620
- return new SamplerType(this._previous().toString(), null, null);
2621
- // sampled_texture_type less_than type_decl greater_than
2622
- // multisampled_texture_type less_than type_decl greater_than
2623
- if (this._match(TokenTypes.sampled_texture_type) ||
2624
- this._match(TokenTypes.multisampled_texture_type)) {
2625
- const sampler = this._previous();
2626
- this._consume(TokenTypes.tokens.less_than, "Expected '<' for sampler type.");
2627
- const format = this._type_decl();
2628
- this._consume(TokenTypes.tokens.greater_than, "Expected '>' for sampler type.");
2629
- return new SamplerType(sampler.toString(), format, null);
2630
- }
2631
- // storage_texture_type less_than texel_format comma access_mode greater_than
2632
- if (this._match(TokenTypes.storage_texture_type)) {
2633
- const sampler = this._previous();
2634
- this._consume(TokenTypes.tokens.less_than, "Expected '<' for sampler type.");
2635
- const format = this._consume(TokenTypes.texel_format, "Invalid texel format.").toString();
2636
- this._consume(TokenTypes.tokens.comma, "Expected ',' after texel format.");
2637
- const access = this._consume(TokenTypes.access_mode, "Expected access mode for storage texture type.").toString();
2638
- this._consume(TokenTypes.tokens.greater_than, "Expected '>' for sampler type.");
2639
- return new SamplerType(sampler.toString(), format, access);
2640
- }
2641
- return null;
2642
- }
2643
- _attribute() {
2644
- // attr ident paren_left (literal_or_ident comma)* literal_or_ident paren_right
2645
- // attr ident
2646
- let attributes = [];
2647
- while (this._match(TokenTypes.tokens.attr)) {
2648
- const name = this._consume(TokenTypes.attribute_name, "Expected attribute name");
2649
- const attr = new Attribute(name.toString(), null);
2650
- if (this._match(TokenTypes.tokens.paren_left)) {
2651
- // literal_or_ident
2652
- attr.value = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString();
2653
- if (this._check(TokenTypes.tokens.comma)) {
2654
- this._advance();
2655
- do {
2656
- const v = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString();
2657
- if (!(attr.value instanceof Array)) {
2658
- attr.value = [attr.value];
2659
- }
2660
- attr.value.push(v);
2661
- } while (this._match(TokenTypes.tokens.comma));
2662
- }
2663
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'");
2664
- }
2665
- attributes.push(attr);
2666
- }
2667
- // Deprecated:
2668
- // attr_left (attribute comma)* attribute attr_right
2669
- while (this._match(TokenTypes.tokens.attr_left)) {
2670
- if (!this._check(TokenTypes.tokens.attr_right)) {
2671
- do {
2672
- const name = this._consume(TokenTypes.attribute_name, "Expected attribute name");
2673
- const attr = new Attribute(name.toString(), null);
2674
- if (this._match(TokenTypes.tokens.paren_left)) {
2675
- // literal_or_ident
2676
- attr.value = [
2677
- this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString(),
2678
- ];
2679
- if (this._check(TokenTypes.tokens.comma)) {
2680
- this._advance();
2681
- do {
2682
- const v = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString();
2683
- attr.value.push(v);
2684
- } while (this._match(TokenTypes.tokens.comma));
2685
- }
2686
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'");
2687
- }
2688
- attributes.push(attr);
2689
- } while (this._match(TokenTypes.tokens.comma));
2690
- }
2691
- // Consume ]]
2692
- this._consume(TokenTypes.tokens.attr_right, "Expected ']]' after attribute declarations");
2693
- }
2694
- if (attributes.length == 0)
2695
- return null;
2696
- return attributes;
2697
- }
2698
- }
2699
-
2700
- /**
2701
- * @author Brendan Duncan / https://github.com/brendan-duncan
2702
- */
2703
- class TypeInfo {
2704
- constructor(name, attributes) {
2705
- this.name = name;
2706
- this.attributes = attributes;
2707
- this.size = 0;
2708
- }
2709
- get isArray() {
2710
- return false;
2711
- }
2712
- get isStruct() {
2713
- return false;
2714
- }
2715
- get isTemplate() {
2716
- return false;
2717
- }
2718
- }
2719
- class MemberInfo {
2720
- constructor(name, type, attributes) {
2721
- this.name = name;
2722
- this.type = type;
2723
- this.attributes = attributes;
2724
- this.offset = 0;
2725
- this.size = 0;
2726
- }
2727
- get isArray() {
2728
- return this.type.isArray;
2729
- }
2730
- get isStruct() {
2731
- return this.type.isStruct;
2732
- }
2733
- get isTemplate() {
2734
- return this.type.isTemplate;
2735
- }
2736
- get align() {
2737
- return this.type.isStruct ? this.type.align : 0;
2738
- }
2739
- get members() {
2740
- return this.type.isStruct ? this.type.members : null;
2741
- }
2742
- get format() {
2743
- return this.type.isArray
2744
- ? this.type.format
2745
- : this.type.isTemplate
2746
- ? this.type.format
2747
- : null;
2748
- }
2749
- get count() {
2750
- return this.type.isArray ? this.type.count : 0;
2751
- }
2752
- get stride() {
2753
- return this.type.isArray ? this.type.stride : this.size;
2754
- }
2755
- }
2756
- class StructInfo extends TypeInfo {
2757
- constructor(name, attributes) {
2758
- super(name, attributes);
2759
- this.members = [];
2760
- this.align = 0;
2761
- }
2762
- get isStruct() {
2763
- return true;
2764
- }
2765
- }
2766
- class ArrayInfo extends TypeInfo {
2767
- constructor(name, attributes) {
2768
- super(name, attributes);
2769
- this.count = 0;
2770
- this.stride = 0;
2771
- }
2772
- get isArray() {
2773
- return true;
2774
- }
2775
- }
2776
- class TemplateInfo extends TypeInfo {
2777
- constructor(name, format, attributes, access) {
2778
- super(name, attributes);
2779
- this.format = format;
2780
- this.access = access;
2781
- }
2782
- get isTemplate() {
2783
- return true;
2784
- }
2785
- }
2786
- var ResourceType;
2787
- (function (ResourceType) {
2788
- ResourceType[ResourceType["Uniform"] = 0] = "Uniform";
2789
- ResourceType[ResourceType["Storage"] = 1] = "Storage";
2790
- ResourceType[ResourceType["Texture"] = 2] = "Texture";
2791
- ResourceType[ResourceType["Sampler"] = 3] = "Sampler";
2792
- ResourceType[ResourceType["StorageTexture"] = 4] = "StorageTexture";
2793
- })(ResourceType || (ResourceType = {}));
2794
- class VariableInfo {
2795
- constructor(name, type, group, binding, attributes, resourceType, access) {
2796
- this.name = name;
2797
- this.type = type;
2798
- this.group = group;
2799
- this.binding = binding;
2800
- this.attributes = attributes;
2801
- this.resourceType = resourceType;
2802
- this.access = access;
2803
- }
2804
- get isArray() {
2805
- return this.type.isArray;
2806
- }
2807
- get isStruct() {
2808
- return this.type.isStruct;
2809
- }
2810
- get isTemplate() {
2811
- return this.type.isTemplate;
2812
- }
2813
- get size() {
2814
- return this.type.size;
2815
- }
2816
- get align() {
2817
- return this.type.isStruct ? this.type.align : 0;
2818
- }
2819
- get members() {
2820
- return this.type.isStruct ? this.type.members : null;
2821
- }
2822
- get format() {
2823
- return this.type.isArray
2824
- ? this.type.format
2825
- : this.type.isTemplate
2826
- ? this.type.format
2827
- : null;
2828
- }
2829
- get count() {
2830
- return this.type.isArray ? this.type.count : 0;
2831
- }
2832
- get stride() {
2833
- return this.type.isArray ? this.type.stride : this.size;
2834
- }
2835
- }
2836
- class AliasInfo {
2837
- constructor(name, type) {
2838
- this.name = name;
2839
- this.type = type;
2840
- }
2841
- }
2842
- class _TypeSize {
2843
- constructor(align, size) {
2844
- this.align = align;
2845
- this.size = size;
2846
- }
2847
- }
2848
- class InputInfo {
2849
- constructor(name, type, locationType, location) {
2850
- this.name = name;
2851
- this.type = type;
2852
- this.locationType = locationType;
2853
- this.location = location;
2854
- this.interpolation = null;
2855
- }
2856
- }
2857
- class OutputInfo {
2858
- constructor(name, type, locationType, location) {
2859
- this.name = name;
2860
- this.type = type;
2861
- this.locationType = locationType;
2862
- this.location = location;
2863
- }
2864
- }
2865
- class FunctionInfo {
2866
- constructor(name, stage = null) {
2867
- this.stage = null;
2868
- this.inputs = [];
2869
- this.outputs = [];
2870
- this.name = name;
2871
- this.stage = stage;
2872
- }
2873
- }
2874
- class EntryFunctions {
2875
- constructor() {
2876
- this.vertex = [];
2877
- this.fragment = [];
2878
- this.compute = [];
2879
- }
2880
- }
2881
- class OverrideInfo {
2882
- constructor(name, type, attributes, id) {
2883
- this.name = name;
2884
- this.type = type;
2885
- this.attributes = attributes;
2886
- this.id = id;
2887
- }
2888
- }
2889
- class WgslReflect {
2890
- constructor(code) {
2891
- /// All top-level uniform vars in the shader.
2892
- this.uniforms = [];
2893
- /// All top-level storage vars in the shader.
2894
- this.storage = [];
2895
- /// All top-level texture vars in the shader;
2896
- this.textures = [];
2897
- // All top-level sampler vars in the shader.
2898
- this.samplers = [];
2899
- /// All top-level type aliases in the shader.
2900
- this.aliases = [];
2901
- /// All top-level overrides in the shader.
2902
- this.overrides = [];
2903
- /// All top-level structs in the shader.
2904
- this.structs = [];
2905
- /// All entry functions in the shader: vertex, fragment, and/or compute.
2906
- this.entry = new EntryFunctions();
2907
- this._types = new Map();
2908
- if (code) {
2909
- this.update(code);
2910
- }
2911
- }
2912
- _isStorageTexture(type) {
2913
- return (type.name == "texture_storage_1d" ||
2914
- type.name == "texture_storage_2d" ||
2915
- type.name == "texture_storage_2d_array" ||
2916
- type.name == "texture_storage_3d");
2917
- }
2918
- update(code) {
2919
- const parser = new WgslParser();
2920
- const ast = parser.parse(code);
2921
- for (const node of ast) {
2922
- if (node instanceof Struct) {
2923
- const info = this._getTypeInfo(node, null);
2924
- if (info instanceof StructInfo) {
2925
- this.structs.push(info);
2926
- }
2927
- continue;
2928
- }
2929
- if (node instanceof Alias) {
2930
- this.aliases.push(this._getAliasInfo(node));
2931
- continue;
2932
- }
2933
- if (node instanceof Override) {
2934
- const v = node;
2935
- const id = this._getAttributeNum(v.attributes, "id", 0);
2936
- const type = v.type != null ? this._getTypeInfo(v.type, v.attributes) : null;
2937
- this.overrides.push(new OverrideInfo(v.name, type, v.attributes, id));
2938
- continue;
2939
- }
2940
- if (this._isUniformVar(node)) {
2941
- const v = node;
2942
- const g = this._getAttributeNum(v.attributes, "group", 0);
2943
- const b = this._getAttributeNum(v.attributes, "binding", 0);
2944
- const type = this._getTypeInfo(v.type, v.attributes);
2945
- const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, ResourceType.Uniform, v.access);
2946
- this.uniforms.push(varInfo);
2947
- continue;
2948
- }
2949
- if (this._isStorageVar(node)) {
2950
- const v = node;
2951
- const g = this._getAttributeNum(v.attributes, "group", 0);
2952
- const b = this._getAttributeNum(v.attributes, "binding", 0);
2953
- const type = this._getTypeInfo(v.type, v.attributes);
2954
- const isStorageTexture = this._isStorageTexture(type);
2955
- const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, isStorageTexture ? ResourceType.StorageTexture : ResourceType.Storage, v.access);
2956
- this.storage.push(varInfo);
2957
- continue;
2958
- }
2959
- if (this._isTextureVar(node)) {
2960
- const v = node;
2961
- const g = this._getAttributeNum(v.attributes, "group", 0);
2962
- const b = this._getAttributeNum(v.attributes, "binding", 0);
2963
- const type = this._getTypeInfo(v.type, v.attributes);
2964
- const isStorageTexture = this._isStorageTexture(type);
2965
- const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, isStorageTexture ? ResourceType.StorageTexture : ResourceType.Texture, v.access);
2966
- if (isStorageTexture) {
2967
- this.storage.push(varInfo);
2968
- }
2969
- else {
2970
- this.textures.push(varInfo);
2971
- }
2972
- continue;
2973
- }
2974
- if (this._isSamplerVar(node)) {
2975
- const v = node;
2976
- const g = this._getAttributeNum(v.attributes, "group", 0);
2977
- const b = this._getAttributeNum(v.attributes, "binding", 0);
2978
- const type = this._getTypeInfo(v.type, v.attributes);
2979
- const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, ResourceType.Sampler, v.access);
2980
- this.samplers.push(varInfo);
2981
- continue;
2982
- }
2983
- if (node instanceof Function) {
2984
- const vertexStage = this._getAttribute(node, "vertex");
2985
- const fragmentStage = this._getAttribute(node, "fragment");
2986
- const computeStage = this._getAttribute(node, "compute");
2987
- const stage = vertexStage || fragmentStage || computeStage;
2988
- if (stage) {
2989
- const fn = new FunctionInfo(node.name, stage.name);
2990
- fn.inputs = this._getInputs(node.args);
2991
- fn.outputs = this._getOutputs(node.returnType);
2992
- this.entry[stage.name].push(fn);
2993
- }
2994
- continue;
2995
- }
2996
- }
2997
- }
2998
- getBindGroups() {
2999
- const groups = [];
3000
- function _makeRoom(group, binding) {
3001
- if (group >= groups.length)
3002
- groups.length = group + 1;
3003
- if (groups[group] === undefined)
3004
- groups[group] = [];
3005
- if (binding >= groups[group].length)
3006
- groups[group].length = binding + 1;
3007
- }
3008
- for (const u of this.uniforms) {
3009
- _makeRoom(u.group, u.binding);
3010
- const group = groups[u.group];
3011
- group[u.binding] = u;
3012
- }
3013
- for (const u of this.storage) {
3014
- _makeRoom(u.group, u.binding);
3015
- const group = groups[u.group];
3016
- group[u.binding] = u;
3017
- }
3018
- for (const t of this.textures) {
3019
- _makeRoom(t.group, t.binding);
3020
- const group = groups[t.group];
3021
- group[t.binding] = t;
3022
- }
3023
- for (const t of this.samplers) {
3024
- _makeRoom(t.group, t.binding);
3025
- const group = groups[t.group];
3026
- group[t.binding] = t;
3027
- }
3028
- return groups;
3029
- }
3030
- _getOutputs(type, outputs = undefined) {
3031
- if (outputs === undefined)
3032
- outputs = [];
3033
- if (type instanceof Struct) {
3034
- this._getStructOutputs(type, outputs);
3035
- }
3036
- else {
3037
- const output = this._getOutputInfo(type);
3038
- if (output !== null)
3039
- outputs.push(output);
3040
- }
3041
- return outputs;
3042
- }
3043
- _getStructOutputs(struct, outputs) {
3044
- for (const m of struct.members) {
3045
- if (m.type instanceof Struct) {
3046
- this._getStructOutputs(m.type, outputs);
3047
- }
3048
- else {
3049
- const location = this._getAttribute(m, "location") || this._getAttribute(m, "builtin");
3050
- if (location !== null) {
3051
- const typeInfo = this._getTypeInfo(m.type, m.type.attributes);
3052
- const locationValue = this._parseInt(location.value);
3053
- const info = new OutputInfo(m.name, typeInfo, location.name, locationValue);
3054
- outputs.push(info);
3055
- }
3056
- }
3057
- }
3058
- }
3059
- _getOutputInfo(type) {
3060
- const location = this._getAttribute(type, "location") ||
3061
- this._getAttribute(type, "builtin");
3062
- if (location !== null) {
3063
- const typeInfo = this._getTypeInfo(type, type.attributes);
3064
- const locationValue = this._parseInt(location.value);
3065
- const info = new OutputInfo("", typeInfo, location.name, locationValue);
3066
- return info;
3067
- }
3068
- return null;
3069
- }
3070
- _getInputs(args, inputs = undefined) {
3071
- if (inputs === undefined)
3072
- inputs = [];
3073
- for (const arg of args) {
3074
- if (arg.type instanceof Struct) {
3075
- this._getStructInputs(arg.type, inputs);
3076
- }
3077
- else {
3078
- const input = this._getInputInfo(arg);
3079
- if (input !== null)
3080
- inputs.push(input);
3081
- }
3082
- }
3083
- return inputs;
3084
- }
3085
- _getStructInputs(struct, inputs) {
3086
- for (const m of struct.members) {
3087
- if (m.type instanceof Struct) {
3088
- this._getStructInputs(m.type, inputs);
3089
- }
3090
- else {
3091
- const input = this._getInputInfo(m);
3092
- if (input !== null)
3093
- inputs.push(input);
3094
- }
3095
- }
3096
- }
3097
- _getInputInfo(node) {
3098
- const location = this._getAttribute(node, "location") ||
3099
- this._getAttribute(node, "builtin");
3100
- if (location !== null) {
3101
- const interpolation = this._getAttribute(node, "interpolation");
3102
- const type = this._getTypeInfo(node.type, node.attributes);
3103
- const locationValue = this._parseInt(location.value);
3104
- const info = new InputInfo(node.name, type, location.name, locationValue);
3105
- if (interpolation !== null) {
3106
- info.interpolation = this._parseString(interpolation.value);
3107
- }
3108
- return info;
3109
- }
3110
- return null;
3111
- }
3112
- _parseString(s) {
3113
- if (s instanceof Array) {
3114
- s = s[0];
3115
- }
3116
- return s;
3117
- }
3118
- _parseInt(s) {
3119
- if (s instanceof Array) {
3120
- s = s[0];
3121
- }
3122
- const n = parseInt(s);
3123
- return isNaN(n) ? s : n;
3124
- }
3125
- _getAlias(name) {
3126
- for (const a of this.aliases) {
3127
- if (a.name == name)
3128
- return a.type;
3129
- }
3130
- return null;
3131
- }
3132
- _getAliasInfo(node) {
3133
- return new AliasInfo(node.name, this._getTypeInfo(node.type, null));
3134
- }
3135
- _getTypeInfo(type, attributes) {
3136
- if (this._types.has(type)) {
3137
- return this._types.get(type);
3138
- }
3139
- if (type instanceof ArrayType) {
3140
- const a = type;
3141
- const t = this._getTypeInfo(a.format, a.attributes);
3142
- const info = new ArrayInfo(a.name, attributes);
3143
- info.format = t;
3144
- info.count = a.count;
3145
- this._types.set(type, info);
3146
- this._updateTypeInfo(info);
3147
- return info;
3148
- }
3149
- if (type instanceof Struct) {
3150
- const s = type;
3151
- const info = new StructInfo(s.name, attributes);
3152
- for (const m of s.members) {
3153
- const t = this._getTypeInfo(m.type, m.attributes);
3154
- info.members.push(new MemberInfo(m.name, t, m.attributes));
3155
- }
3156
- this._types.set(type, info);
3157
- this._updateTypeInfo(info);
3158
- return info;
3159
- }
3160
- if (type instanceof SamplerType) {
3161
- const s = type;
3162
- const formatIsType = s.format instanceof Type;
3163
- const format = s.format
3164
- ? formatIsType
3165
- ? this._getTypeInfo(s.format, null)
3166
- : new TypeInfo(s.format, null)
3167
- : null;
3168
- const info = new TemplateInfo(s.name, format, attributes, s.access);
3169
- this._types.set(type, info);
3170
- this._updateTypeInfo(info);
3171
- return info;
3172
- }
3173
- if (type instanceof TemplateType) {
3174
- const t = type;
3175
- const format = t.format ? this._getTypeInfo(t.format, null) : null;
3176
- const info = new TemplateInfo(t.name, format, attributes, t.access);
3177
- this._types.set(type, info);
3178
- this._updateTypeInfo(info);
3179
- return info;
3180
- }
3181
- const info = new TypeInfo(type.name, attributes);
3182
- this._types.set(type, info);
3183
- this._updateTypeInfo(info);
3184
- return info;
3185
- }
3186
- _updateTypeInfo(type) {
3187
- var _a, _b;
3188
- const typeSize = this._getTypeSize(type);
3189
- type.size = (_a = typeSize === null || typeSize === void 0 ? void 0 : typeSize.size) !== null && _a !== void 0 ? _a : 0;
3190
- if (type instanceof ArrayInfo) {
3191
- const formatInfo = this._getTypeSize(type["format"]);
3192
- type.stride = (_b = formatInfo === null || formatInfo === void 0 ? void 0 : formatInfo.size) !== null && _b !== void 0 ? _b : 0;
3193
- this._updateTypeInfo(type["format"]);
3194
- }
3195
- if (type instanceof StructInfo) {
3196
- this._updateStructInfo(type);
3197
- }
3198
- }
3199
- _updateStructInfo(struct) {
3200
- var _a;
3201
- let offset = 0;
3202
- let lastSize = 0;
3203
- let lastOffset = 0;
3204
- let structAlign = 0;
3205
- for (let mi = 0, ml = struct.members.length; mi < ml; ++mi) {
3206
- const member = struct.members[mi];
3207
- const sizeInfo = this._getTypeSize(member);
3208
- if (!sizeInfo)
3209
- continue;
3210
- (_a = this._getAlias(member.type.name)) !== null && _a !== void 0 ? _a : member.type;
3211
- const align = sizeInfo.align;
3212
- const size = sizeInfo.size;
3213
- offset = this._roundUp(align, offset + lastSize);
3214
- lastSize = size;
3215
- lastOffset = offset;
3216
- structAlign = Math.max(structAlign, align);
3217
- member.offset = offset;
3218
- member.size = size;
3219
- this._updateTypeInfo(member.type);
3220
- }
3221
- struct.size = this._roundUp(structAlign, lastOffset + lastSize);
3222
- struct.align = structAlign;
3223
- }
3224
- _getTypeSize(type) {
3225
- var _a;
3226
- if (type === null || type === undefined)
3227
- return null;
3228
- const explicitSize = this._getAttributeNum(type.attributes, "size", 0);
3229
- const explicitAlign = this._getAttributeNum(type.attributes, "align", 0);
3230
- if (type instanceof MemberInfo)
3231
- type = type.type;
3232
- if (type instanceof TypeInfo) {
3233
- const alias = this._getAlias(type.name);
3234
- if (alias !== null) {
3235
- type = alias;
3236
- }
3237
- }
3238
- {
3239
- const info = WgslReflect._typeInfo[type.name];
3240
- if (info !== undefined) {
3241
- const divisor = type["format"] === "f16" ? 2 : 1;
3242
- return new _TypeSize(Math.max(explicitAlign, info.align / divisor), Math.max(explicitSize, info.size / divisor));
3243
- }
3244
- }
3245
- {
3246
- const info = WgslReflect._typeInfo[type.name.substring(0, type.name.length - 1)];
3247
- if (info) {
3248
- const divisor = type.name[type.name.length - 1] === "h" ? 2 : 1;
3249
- return new _TypeSize(Math.max(explicitAlign, info.align / divisor), Math.max(explicitSize, info.size / divisor));
3250
- }
3251
- }
3252
- if (type instanceof ArrayInfo) {
3253
- let arrayType = type;
3254
- let align = 8;
3255
- let size = 8;
3256
- // Type AlignOf(T) Sizeof(T)
3257
- // array<E, N> AlignOf(E) N * roundUp(AlignOf(E), SizeOf(E))
3258
- // array<E> AlignOf(E) N * roundUp(AlignOf(E), SizeOf(E)) (N determined at runtime)
3259
- //
3260
- // @stride(Q)
3261
- // array<E, N> AlignOf(E) N * Q
3262
- //
3263
- // @stride(Q)
3264
- // array<E> AlignOf(E) Nruntime * Q
3265
- //const E = type.format.name;
3266
- const E = this._getTypeSize(arrayType.format);
3267
- if (E !== null) {
3268
- size = E.size;
3269
- align = E.align;
3270
- }
3271
- const N = arrayType.count;
3272
- const stride = this._getAttributeNum((_a = type === null || type === void 0 ? void 0 : type.attributes) !== null && _a !== void 0 ? _a : null, "stride", this._roundUp(align, size));
3273
- size = N * stride;
3274
- if (explicitSize)
3275
- size = explicitSize;
3276
- return new _TypeSize(Math.max(explicitAlign, align), Math.max(explicitSize, size));
3277
- }
3278
- if (type instanceof StructInfo) {
3279
- let align = 0;
3280
- let size = 0;
3281
- // struct S AlignOf: max(AlignOfMember(S, M1), ... , AlignOfMember(S, MN))
3282
- // SizeOf: roundUp(AlignOf(S), OffsetOfMember(S, L) + SizeOfMember(S, L))
3283
- // Where L is the last member of the structure
3284
- let offset = 0;
3285
- let lastSize = 0;
3286
- let lastOffset = 0;
3287
- for (const m of type.members) {
3288
- const mi = this._getTypeSize(m.type);
3289
- if (mi !== null) {
3290
- align = Math.max(mi.align, align);
3291
- offset = this._roundUp(mi.align, offset + lastSize);
3292
- lastSize = mi.size;
3293
- lastOffset = offset;
3294
- }
3295
- }
3296
- size = this._roundUp(align, lastOffset + lastSize);
3297
- return new _TypeSize(Math.max(explicitAlign, align), Math.max(explicitSize, size));
3298
- }
3299
- return null;
3300
- }
3301
- _isUniformVar(node) {
3302
- return node instanceof Var && node.storage == "uniform";
3303
- }
3304
- _isStorageVar(node) {
3305
- return node instanceof Var && node.storage == "storage";
3306
- }
3307
- _isTextureVar(node) {
3308
- return (node instanceof Var &&
3309
- node.type !== null &&
3310
- WgslReflect._textureTypes.indexOf(node.type.name) != -1);
3311
- }
3312
- _isSamplerVar(node) {
3313
- return (node instanceof Var &&
3314
- node.type !== null &&
3315
- WgslReflect._samplerTypes.indexOf(node.type.name) != -1);
3316
- }
3317
- _getAttribute(node, name) {
3318
- const obj = node;
3319
- if (!obj || !obj["attributes"])
3320
- return null;
3321
- const attrs = obj["attributes"];
3322
- for (let a of attrs) {
3323
- if (a.name == name)
3324
- return a;
3325
- }
3326
- return null;
3327
- }
3328
- _getAttributeNum(attributes, name, defaultValue) {
3329
- if (attributes === null)
3330
- return defaultValue;
3331
- for (let a of attributes) {
3332
- if (a.name == name) {
3333
- let v = a !== null && a.value !== null ? a.value : defaultValue;
3334
- if (v instanceof Array) {
3335
- v = v[0];
3336
- }
3337
- if (typeof v === "number") {
3338
- return v;
3339
- }
3340
- if (typeof v === "string") {
3341
- return parseInt(v);
3342
- }
3343
- return defaultValue;
3344
- }
3345
- }
3346
- return defaultValue;
3347
- }
3348
- _roundUp(k, n) {
3349
- return Math.ceil(n / k) * k;
3350
- }
3351
- }
3352
- // Type AlignOf(T) Sizeof(T)
3353
- // i32, u32, or f32 4 4
3354
- // atomic<T> 4 4
3355
- // vec2<T> 8 8
3356
- // vec3<T> 16 12
3357
- // vec4<T> 16 16
3358
- // mat2x2<f32> 8 16
3359
- // mat3x2<f32> 8 24
3360
- // mat4x2<f32> 8 32
3361
- // mat2x3<f32> 16 32
3362
- // mat3x3<f32> 16 48
3363
- // mat4x3<f32> 16 64
3364
- // mat2x4<f32> 16 32
3365
- // mat3x4<f32> 16 48
3366
- // mat4x4<f32> 16 64
3367
- WgslReflect._typeInfo = {
3368
- f16: { align: 2, size: 2 },
3369
- i32: { align: 4, size: 4 },
3370
- u32: { align: 4, size: 4 },
3371
- f32: { align: 4, size: 4 },
3372
- atomic: { align: 4, size: 4 },
3373
- vec2: { align: 8, size: 8 },
3374
- vec3: { align: 16, size: 12 },
3375
- vec4: { align: 16, size: 16 },
3376
- mat2x2: { align: 8, size: 16 },
3377
- mat3x2: { align: 8, size: 24 },
3378
- mat4x2: { align: 8, size: 32 },
3379
- mat2x3: { align: 16, size: 32 },
3380
- mat3x3: { align: 16, size: 48 },
3381
- mat4x3: { align: 16, size: 64 },
3382
- mat2x4: { align: 16, size: 32 },
3383
- mat3x4: { align: 16, size: 48 },
3384
- mat4x4: { align: 16, size: 64 },
3385
- };
3386
- WgslReflect._textureTypes = TokenTypes.any_texture_type.map((t) => {
3387
- return t.name;
3388
- });
3389
- WgslReflect._samplerTypes = TokenTypes.sampler_type.map((t) => {
3390
- return t.name;
3391
- });
3392
-
3393
- export { Alias, AliasInfo, Argument, ArrayInfo, ArrayType, Assign, AssignOperator, Attribute, BinaryOperator, BitcastExpr, Break, Call, CallExpr, Case, Const, ConstExpr, Continue, Continuing, CreateExpr, Default, Discard, ElseIf, Enable, EntryFunctions, Expression, For, Function, FunctionInfo, GroupingExpr, If, Increment, IncrementOperator, InputInfo, Let, LiteralExpr, Loop, Member, MemberInfo, Node, Operator, OutputInfo, Override, OverrideInfo, ParseContext, PointerType, ResourceType, Return, SamplerType, Statement, StaticAssert, StringExpr, Struct, StructInfo, Switch, SwitchCase, TemplateInfo, TemplateType, Token, TokenClass, TokenType, TokenTypes, Type, TypeInfo, TypecastExpr, UnaryOperator, Var, VariableExpr, VariableInfo, WgslParser, WgslReflect, WgslScanner, While };
3394
- //# sourceMappingURL=wgsl_reflect.module.js.map