@luma.gl/shadertools 9.0.14 → 9.0.16

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