wesl 0.6.0-pre10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.md +31 -0
  2. package/dist/index.js +4468 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/minified.js +3426 -0
  5. package/dist/minified.js.map +1 -0
  6. package/dist/tools/packages/wesl/src/AbstractElems.d.ts +322 -0
  7. package/dist/tools/packages/wesl/src/Assertions.d.ts +27 -0
  8. package/dist/tools/packages/wesl/src/BindIdents.d.ts +70 -0
  9. package/dist/tools/packages/wesl/src/Conditions.d.ts +6 -0
  10. package/dist/tools/packages/wesl/src/FlattenTreeImport.d.ts +11 -0
  11. package/dist/tools/packages/wesl/src/LinkedWesl.d.ts +50 -0
  12. package/dist/tools/packages/wesl/src/Linker.d.ts +87 -0
  13. package/dist/tools/packages/wesl/src/LinkerUtil.d.ts +3 -0
  14. package/dist/tools/packages/wesl/src/LiveDeclarations.d.ts +12 -0
  15. package/dist/tools/packages/wesl/src/LowerAndEmit.d.ts +31 -0
  16. package/dist/tools/packages/wesl/src/Mangler.d.ts +39 -0
  17. package/dist/tools/packages/wesl/src/ParseWESL.d.ts +60 -0
  18. package/dist/tools/packages/wesl/src/ParsedRegistry.d.ts +29 -0
  19. package/dist/tools/packages/wesl/src/PathUtil.d.ts +6 -0
  20. package/dist/tools/packages/wesl/src/RawEmit.d.ts +6 -0
  21. package/dist/tools/packages/wesl/src/Reflection.d.ts +45 -0
  22. package/dist/tools/packages/wesl/src/Scope.d.ts +81 -0
  23. package/dist/tools/packages/wesl/src/StandardTypes.d.ts +13 -0
  24. package/dist/tools/packages/wesl/src/TransformBindingStructs.d.ts +52 -0
  25. package/dist/tools/packages/wesl/src/Util.d.ts +43 -0
  26. package/dist/tools/packages/wesl/src/WESLCollect.d.ts +94 -0
  27. package/dist/tools/packages/wesl/src/WeslBundle.d.ts +13 -0
  28. package/dist/tools/packages/wesl/src/WeslDevice.d.ts +25 -0
  29. package/dist/tools/packages/wesl/src/debug/ASTtoString.d.ts +5 -0
  30. package/dist/tools/packages/wesl/src/debug/ImportToString.d.ts +2 -0
  31. package/dist/tools/packages/wesl/src/debug/LineWrapper.d.ts +21 -0
  32. package/dist/tools/packages/wesl/src/debug/ScopeToString.d.ts +6 -0
  33. package/dist/tools/packages/wesl/src/index.d.ts +11 -0
  34. package/dist/tools/packages/wesl/src/parse/ImportGrammar.d.ts +5 -0
  35. package/dist/tools/packages/wesl/src/parse/Keywords.d.ts +4 -0
  36. package/dist/tools/packages/wesl/src/parse/WeslBaseGrammar.d.ts +5 -0
  37. package/dist/tools/packages/wesl/src/parse/WeslExpression.d.ts +13 -0
  38. package/dist/tools/packages/wesl/src/parse/WeslGrammar.d.ts +80 -0
  39. package/dist/tools/packages/wesl/src/parse/WeslStream.d.ts +44 -0
  40. package/dist/tools/packages/wesl/src/test/BindWESL.test.d.ts +1 -0
  41. package/dist/tools/packages/wesl/src/test/ConditionLinking.test.d.ts +1 -0
  42. package/dist/tools/packages/wesl/src/test/ConditionalTranslationCases.test.d.ts +1 -0
  43. package/dist/tools/packages/wesl/src/test/ErrorLogging.test.d.ts +1 -0
  44. package/dist/tools/packages/wesl/src/test/Expression.test.d.ts +1 -0
  45. package/dist/tools/packages/wesl/src/test/FlattenTreeImport.test.d.ts +1 -0
  46. package/dist/tools/packages/wesl/src/test/ImportCases.test.d.ts +1 -0
  47. package/dist/tools/packages/wesl/src/test/ImportSyntaxCases.test.d.ts +1 -0
  48. package/dist/tools/packages/wesl/src/test/LinkGlob.test.d.ts +1 -0
  49. package/dist/tools/packages/wesl/src/test/LinkPackage.test.d.ts +1 -0
  50. package/dist/tools/packages/wesl/src/test/Linker.test.d.ts +1 -0
  51. package/dist/tools/packages/wesl/src/test/Mangling.test.d.ts +1 -0
  52. package/dist/tools/packages/wesl/src/test/ParseComments.test.d.ts +1 -0
  53. package/dist/tools/packages/wesl/src/test/ParseConditions.test.d.ts +1 -0
  54. package/dist/tools/packages/wesl/src/test/ParseError.test.d.ts +1 -0
  55. package/dist/tools/packages/wesl/src/test/ParseWESL.test.d.ts +1 -0
  56. package/dist/tools/packages/wesl/src/test/PathUtil.test.d.ts +1 -0
  57. package/dist/tools/packages/wesl/src/test/PrettyGrammar.test.d.ts +1 -0
  58. package/dist/tools/packages/wesl/src/test/Reflection.test.d.ts +1 -0
  59. package/dist/tools/packages/wesl/src/test/ScopeWESL.test.d.ts +1 -0
  60. package/dist/tools/packages/wesl/src/test/TestLink.d.ts +21 -0
  61. package/dist/tools/packages/wesl/src/test/TestSetup.d.ts +1 -0
  62. package/dist/tools/packages/wesl/src/test/TestUtil.d.ts +40 -0
  63. package/dist/tools/packages/wesl/src/test/Tokenizer.test.d.ts +1 -0
  64. package/dist/tools/packages/wesl/src/test/TransformBindingStructs.test.d.ts +1 -0
  65. package/dist/tools/packages/wesl/src/test/Util.test.d.ts +1 -0
  66. package/dist/tools/packages/wesl/src/test/VirtualModules.test.d.ts +1 -0
  67. package/dist/tools/packages/wesl/src/test/WeslDevice.test.d.ts +1 -0
  68. package/dist/tools/packages/wesl/src/test/WgslTests.d.ts +0 -0
  69. package/dist/tools/packages/wesl/src/vlq/vlq.d.ts +11 -0
  70. package/package.json +46 -0
  71. package/src/AbstractElems.ts +446 -0
  72. package/src/Assertions.ts +51 -0
  73. package/src/BindIdents.ts +523 -0
  74. package/src/Conditions.ts +74 -0
  75. package/src/FlattenTreeImport.ts +55 -0
  76. package/src/LinkedWesl.ts +184 -0
  77. package/src/Linker.ts +284 -0
  78. package/src/LinkerUtil.ts +29 -0
  79. package/src/LiveDeclarations.ts +31 -0
  80. package/src/LowerAndEmit.ts +413 -0
  81. package/src/Mangler.ts +94 -0
  82. package/src/ParseWESL.ts +157 -0
  83. package/src/ParsedRegistry.ts +120 -0
  84. package/src/PathUtil.ts +31 -0
  85. package/src/RawEmit.ts +102 -0
  86. package/src/Reflection.ts +334 -0
  87. package/src/Scope.ts +162 -0
  88. package/src/StandardTypes.ts +97 -0
  89. package/src/TransformBindingStructs.ts +319 -0
  90. package/src/Util.ts +194 -0
  91. package/src/WESLCollect.ts +614 -0
  92. package/src/WeslBundle.ts +16 -0
  93. package/src/WeslDevice.ts +209 -0
  94. package/src/debug/ASTtoString.ts +290 -0
  95. package/src/debug/ImportToString.ts +29 -0
  96. package/src/debug/LineWrapper.ts +70 -0
  97. package/src/debug/ScopeToString.ts +79 -0
  98. package/src/index.ts +11 -0
  99. package/src/parse/ImportGrammar.ts +157 -0
  100. package/src/parse/Keywords.ts +26 -0
  101. package/src/parse/WeslBaseGrammar.ts +8 -0
  102. package/src/parse/WeslExpression.ts +207 -0
  103. package/src/parse/WeslGrammar.ts +856 -0
  104. package/src/parse/WeslStream.ts +279 -0
  105. package/src/test/BindWESL.test.ts +57 -0
  106. package/src/test/ConditionLinking.test.ts +91 -0
  107. package/src/test/ConditionalTranslationCases.test.ts +56 -0
  108. package/src/test/ErrorLogging.test.ts +30 -0
  109. package/src/test/Expression.test.ts +22 -0
  110. package/src/test/FlattenTreeImport.test.ts +74 -0
  111. package/src/test/ImportCases.test.ts +56 -0
  112. package/src/test/ImportSyntaxCases.test.ts +24 -0
  113. package/src/test/LinkGlob.test.ts +25 -0
  114. package/src/test/LinkPackage.test.ts +26 -0
  115. package/src/test/Linker.test.ts +125 -0
  116. package/src/test/Mangling.test.ts +45 -0
  117. package/src/test/ParseComments.test.ts +36 -0
  118. package/src/test/ParseConditions.test.ts +183 -0
  119. package/src/test/ParseError.test.ts +36 -0
  120. package/src/test/ParseWESL.test.ts +1572 -0
  121. package/src/test/PathUtil.test.ts +34 -0
  122. package/src/test/PrettyGrammar.test.ts +20 -0
  123. package/src/test/Reflection.test.ts +172 -0
  124. package/src/test/ScopeWESL.test.ts +462 -0
  125. package/src/test/TestLink.ts +82 -0
  126. package/src/test/TestSetup.ts +4 -0
  127. package/src/test/TestUtil.ts +126 -0
  128. package/src/test/Tokenizer.test.ts +135 -0
  129. package/src/test/TransformBindingStructs.test.ts +230 -0
  130. package/src/test/Util.test.ts +22 -0
  131. package/src/test/VirtualModules.test.ts +37 -0
  132. package/src/test/WeslDevice.test.ts +265 -0
  133. package/src/test/WgslTests.ts +0 -0
  134. package/src/test/__snapshots__/ParseDirectives.test.ts.snap +25 -0
  135. package/src/test/__snapshots__/ParseWESL.test.ts.snap +119 -0
  136. package/src/test/__snapshots__/RustDirective.test.ts.snap +359 -0
  137. package/src/test/wgsl_1/main.wgsl +3 -0
  138. package/src/test/wgsl_1/util.wgsl +1 -0
  139. package/src/test/wgsl_2/main2.wgsl +3 -0
  140. package/src/test/wgsl_2/util2.wgsl +1 -0
  141. package/src/vlq/vlq.ts +94 -0
package/dist/index.js ADDED
@@ -0,0 +1,4468 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
+ var _fragments, _destLength, _entries, _fragments2, _column, _spc, _oneLine, _isHanging, _hangingSpc;
9
+ function assertThat(condition, msg) {
10
+ if (!condition) {
11
+ throw new Error(msg);
12
+ }
13
+ }
14
+ function assertUnreachable$1(value) {
15
+ throw new ErrorWithData$1("Unreachable value", { data: value });
16
+ }
17
+ let ErrorWithData$1 = class ErrorWithData extends Error {
18
+ constructor(message, options) {
19
+ super(message, options);
20
+ this.data = options == null ? void 0 : options.data;
21
+ }
22
+ };
23
+ let log = console.log;
24
+ function srcLog(src, pos, ...msgs) {
25
+ logInternal(log, src, pos, ...msgs);
26
+ }
27
+ function quotedText(text2) {
28
+ return text2 ? `'${text2.replace(/\n/g, "\\n")}'` : "";
29
+ }
30
+ function logInternal(log2, srcOrSrcMap, destPos, ...msgs) {
31
+ if (typeof srcOrSrcMap === "string") {
32
+ logInternalSrc(log2, srcOrSrcMap, destPos, ...msgs);
33
+ return;
34
+ }
35
+ const { src, positions } = mapSrcPositions(srcOrSrcMap, destPos);
36
+ logInternalSrc(log2, src.text, positions, ...msgs);
37
+ }
38
+ function mapSrcPositions(srcMap, destPos) {
39
+ var _a, _b, _c, _d;
40
+ const srcPos = srcMap.mapPositions(...[destPos].flat());
41
+ const { src } = srcPos[0];
42
+ let positions;
43
+ if (((_b = (_a = srcPos[1]) == null ? void 0 : _a.src) == null ? void 0 : _b.path) === src.path && ((_d = (_c = srcPos[1]) == null ? void 0 : _c.src) == null ? void 0 : _d.text) === src.text) {
44
+ positions = srcPos.map((p) => p.position);
45
+ } else {
46
+ positions = srcPos[0].position;
47
+ }
48
+ return { src, positions };
49
+ }
50
+ function logInternalSrc(log2, src, pos, ...msgs) {
51
+ log2(...msgs);
52
+ const { line, lineNum, linePos, linePos2 } = srcLine(src, pos);
53
+ {
54
+ log2(line, ` Ln ${lineNum}`);
55
+ }
56
+ const caret = carets(linePos, linePos2);
57
+ log2(caret);
58
+ }
59
+ function carets(linePos, linePos2) {
60
+ const firstCaret = " ".repeat(linePos) + "^";
61
+ let secondCaret = "";
62
+ if (linePos2 && linePos2 > linePos) {
63
+ secondCaret = " ".repeat(linePos2 - linePos - 1) + "^";
64
+ }
65
+ return firstCaret + secondCaret;
66
+ }
67
+ const startCache = /* @__PURE__ */ new Map();
68
+ function srcLine(src, position) {
69
+ let pos;
70
+ let pos2;
71
+ if (typeof position === "number") {
72
+ pos = position;
73
+ } else {
74
+ [pos, pos2] = position;
75
+ }
76
+ const starts = getStarts(src);
77
+ let start = 0;
78
+ let end = starts.length - 1;
79
+ if (pos >= starts[end]) {
80
+ start = end;
81
+ }
82
+ while (start + 1 < end) {
83
+ const mid = start + end >> 1;
84
+ if (pos >= starts[mid]) {
85
+ start = mid;
86
+ } else {
87
+ end = mid;
88
+ }
89
+ }
90
+ let linePos2;
91
+ if (pos2 !== void 0 && pos2 >= starts[start] && pos2 < starts[end]) {
92
+ linePos2 = pos2 - starts[start];
93
+ }
94
+ const lineNl = src.slice(starts[start], starts[start + 1] || src.length);
95
+ const line = lineNl.slice(-1) === "\n" ? lineNl.slice(0, -1) : lineNl;
96
+ return { line, linePos: pos - starts[start], linePos2, lineNum: start + 1 };
97
+ }
98
+ function getStarts(src) {
99
+ const found = startCache.get(src);
100
+ if (found) return found;
101
+ const starts = [...src.matchAll(/\n/g)].map((m) => m.index + 1);
102
+ starts.unshift(0);
103
+ startCache.set(src, starts);
104
+ return starts;
105
+ }
106
+ function peekToken(stream) {
107
+ const start = stream.checkpoint();
108
+ const token2 = stream.nextToken();
109
+ stream.reset(start);
110
+ return token2;
111
+ }
112
+ function token(kindStr, value) {
113
+ return simpleParser(
114
+ `token '${kindStr}' ${quotedText(value)}`,
115
+ function _token(state) {
116
+ const start = state.stream.checkpoint();
117
+ const next = state.stream.nextToken();
118
+ if (next === null) return null;
119
+ if (next.kind !== kindStr || next.text !== value) {
120
+ state.stream.reset(start);
121
+ return null;
122
+ }
123
+ return { value: next };
124
+ }
125
+ );
126
+ }
127
+ function tokenOf(kindStr, values) {
128
+ return simpleParser(
129
+ `tokenOf '${kindStr}'`,
130
+ function _tokenOf(state) {
131
+ const start = state.stream.checkpoint();
132
+ const next = state.stream.nextToken();
133
+ if (next === null) return null;
134
+ if (next.kind !== kindStr || !values.includes(next.text)) {
135
+ state.stream.reset(start);
136
+ return null;
137
+ }
138
+ return { value: next };
139
+ }
140
+ );
141
+ }
142
+ function tokenKind(kindStr) {
143
+ return simpleParser(
144
+ `tokenKind '${kindStr}'`,
145
+ function _tokenKind(state) {
146
+ const start = state.stream.checkpoint();
147
+ const next = state.stream.nextToken();
148
+ if (next === null) return null;
149
+ if (next.kind !== kindStr) {
150
+ state.stream.reset(start);
151
+ return null;
152
+ }
153
+ return { value: next };
154
+ }
155
+ );
156
+ }
157
+ function kind(kindStr) {
158
+ return simpleParser(
159
+ `kind '${kindStr}'`,
160
+ function _kind(state) {
161
+ const start = state.stream.checkpoint();
162
+ const next = state.stream.nextToken();
163
+ if (next === null) return null;
164
+ if (next.kind !== kindStr) {
165
+ state.stream.reset(start);
166
+ return null;
167
+ }
168
+ return { value: next.text };
169
+ }
170
+ );
171
+ }
172
+ function text(value) {
173
+ return simpleParser(
174
+ `${quotedText(value)}`,
175
+ function _text(state) {
176
+ const start = state.stream.checkpoint();
177
+ const next = state.stream.nextToken();
178
+ if (next === null) return null;
179
+ if (next.text !== value) {
180
+ state.stream.reset(start);
181
+ return null;
182
+ }
183
+ return { value: next.text };
184
+ }
185
+ );
186
+ }
187
+ function seq(...args) {
188
+ const parsers = args.map(parserArg);
189
+ const seqParser = parser("seq", function _seq(ctx) {
190
+ const values = [];
191
+ for (const p of parsers) {
192
+ const result = p._run(ctx);
193
+ if (result === null) {
194
+ return null;
195
+ }
196
+ values.push(result.value);
197
+ }
198
+ return { value: values };
199
+ });
200
+ trackChildren(seqParser, ...parsers);
201
+ return seqParser;
202
+ }
203
+ function seqObj(args) {
204
+ const parsers = Object.entries(args).map(
205
+ ([name2, arg]) => [name2, parserArg(arg)]
206
+ );
207
+ const seqObjParser = parser("seqObj", function _seqObj(ctx) {
208
+ const values = {};
209
+ for (const [name2, p] of parsers) {
210
+ const result = p._run(ctx);
211
+ if (result === null) {
212
+ return null;
213
+ }
214
+ values[name2] = result.value;
215
+ }
216
+ return { value: values };
217
+ });
218
+ trackChildren(seqObjParser, ...parsers.map((v) => v[1]));
219
+ return seqObjParser;
220
+ }
221
+ function collectArray(p) {
222
+ return p.collect({ before: pushOpenArray, after: closeArray });
223
+ }
224
+ function preceded(ignoredArg, arg) {
225
+ const ignored = parserArg(ignoredArg);
226
+ const p = parserArg(arg);
227
+ const precededParser = parser(
228
+ "preceded",
229
+ function _preceded(ctx) {
230
+ const ignoredResult = ignored._run(ctx);
231
+ if (ignoredResult === null) return null;
232
+ const result = p._run(ctx);
233
+ return result;
234
+ }
235
+ );
236
+ return precededParser;
237
+ }
238
+ function terminated(arg, ignoredArg) {
239
+ const p = parserArg(arg);
240
+ const ignored = parserArg(ignoredArg);
241
+ const terminatedParser = parser(
242
+ "terminated",
243
+ function _terminated(ctx) {
244
+ const result = p._run(ctx);
245
+ if (result === null) return null;
246
+ const ignoredResult = ignored._run(ctx);
247
+ if (ignoredResult === null) return null;
248
+ return result;
249
+ }
250
+ );
251
+ return terminatedParser;
252
+ }
253
+ function delimited(ignoredArg1, arg, ignoredArg2) {
254
+ const ignored1 = parserArg(ignoredArg1);
255
+ const p = parserArg(arg);
256
+ const ignored2 = parserArg(ignoredArg2);
257
+ const delimitedParser = parser(
258
+ "delimited",
259
+ function _delimited(ctx) {
260
+ const ignoredResult1 = ignored1._run(ctx);
261
+ if (ignoredResult1 === null) return null;
262
+ const result = p._run(ctx);
263
+ if (result === null) return null;
264
+ const ignoredResult2 = ignored2._run(ctx);
265
+ if (ignoredResult2 === null) return null;
266
+ return result;
267
+ }
268
+ );
269
+ return delimitedParser;
270
+ }
271
+ function separated_pair(arg1, ignoredArg, arg2) {
272
+ const p1 = parserArg(arg1);
273
+ const ignored = parserArg(ignoredArg);
274
+ const p2 = parserArg(arg2);
275
+ const terminatedParser = parser(
276
+ "terminated",
277
+ function _terminated(ctx) {
278
+ const result1 = p1._run(ctx);
279
+ if (result1 === null) return null;
280
+ const ignoredResult = ignored._run(ctx);
281
+ if (ignoredResult === null) return null;
282
+ const result2 = p2._run(ctx);
283
+ if (result2 === null) return null;
284
+ return { value: [result1.value, result2.value] };
285
+ }
286
+ );
287
+ return terminatedParser;
288
+ }
289
+ function or(...args) {
290
+ const parsers = args.map(parserArg);
291
+ const orParser = parser("or", function _or(state) {
292
+ const start = state.stream.checkpoint();
293
+ for (const p of parsers) {
294
+ state.stream.reset(start);
295
+ const result = p._run(state);
296
+ if (result !== null) {
297
+ return result;
298
+ }
299
+ }
300
+ return null;
301
+ });
302
+ trackChildren(orParser, ...parsers);
303
+ return orParser;
304
+ }
305
+ function opt(arg) {
306
+ const p = parserArg(arg);
307
+ const optParser = parser(
308
+ "opt",
309
+ function _opt(state) {
310
+ const start = state.stream.checkpoint();
311
+ const result = p._run(state);
312
+ if (result === null) {
313
+ state.stream.reset(start);
314
+ return { value: null };
315
+ } else {
316
+ return result;
317
+ }
318
+ }
319
+ );
320
+ return optParser;
321
+ }
322
+ function repeat(arg) {
323
+ const p = parserArg(arg);
324
+ const repeatParser = parser("repeat", repeatWhileFilter(p));
325
+ return repeatParser;
326
+ }
327
+ function repeatPlus(arg) {
328
+ const p = parserArg(arg);
329
+ const repeatParser = seq(p, repeat(p)).map((r) => [r[0], ...r[1]]).setTraceName("repeatPlus");
330
+ return repeatParser;
331
+ }
332
+ function repeatWhileFilter(p, filterFn = () => true) {
333
+ return function _repeatWhileFilter(ctx) {
334
+ const values = [];
335
+ for (; ; ) {
336
+ const before = ctx.stream.checkpoint();
337
+ const result = runExtended(ctx, p);
338
+ if (result === null) {
339
+ ctx.stream.reset(before);
340
+ return { value: values };
341
+ }
342
+ if (!filterFn(result)) {
343
+ return { value: values };
344
+ }
345
+ values.push(result.value);
346
+ }
347
+ };
348
+ }
349
+ function span(arg) {
350
+ const p = parserArg(arg);
351
+ const result = parser("span", function _span(ctx) {
352
+ var _a, _b;
353
+ const start = ((_b = (_a = peekToken(ctx.stream)) == null ? void 0 : _a.span) == null ? void 0 : _b[0]) ?? null;
354
+ const result2 = p._run(ctx);
355
+ if (result2 === null) return null;
356
+ const end = ctx.stream.checkpoint();
357
+ return {
358
+ value: {
359
+ value: result2.value,
360
+ span: [start ?? end, end]
361
+ }
362
+ };
363
+ });
364
+ return result;
365
+ }
366
+ function eof() {
367
+ return simpleParser("eof", function _eof(state) {
368
+ const start = state.stream.checkpoint();
369
+ const result = state.stream.nextToken();
370
+ if (result !== null) {
371
+ state.stream.reset(start);
372
+ return null;
373
+ }
374
+ return { value: true };
375
+ });
376
+ }
377
+ function req(arg, msg) {
378
+ const p = parserArg(arg);
379
+ const reqParser = parser("req", function _req(ctx) {
380
+ const result = p._run(ctx);
381
+ if (result === null) {
382
+ throw new ParseError(msg, ctx.stream.checkpoint());
383
+ }
384
+ return result;
385
+ });
386
+ return reqParser;
387
+ }
388
+ function yes() {
389
+ return simpleParser("yes", function _yes() {
390
+ return { value: null };
391
+ });
392
+ }
393
+ function withSep(sep, p, opts = {}) {
394
+ const { trailing = true, requireOne = false } = opts;
395
+ const elementParser = parserArg(p);
396
+ const sepParser = parserArg(sep);
397
+ return parser("withSep", function _withSep(ctx) {
398
+ const results = [];
399
+ const startPosition = ctx.stream.checkpoint();
400
+ const result = elementParser._run(ctx);
401
+ if (result === null) {
402
+ ctx.stream.reset(startPosition);
403
+ if (requireOne) {
404
+ return null;
405
+ } else {
406
+ return {
407
+ value: results
408
+ };
409
+ }
410
+ }
411
+ results.push(result.value);
412
+ while (true) {
413
+ const beforeSeparator = ctx.stream.checkpoint();
414
+ const resultSeparator = sepParser._run(ctx);
415
+ if (resultSeparator === null) {
416
+ ctx.stream.reset(beforeSeparator);
417
+ break;
418
+ }
419
+ const beforeElement = ctx.stream.checkpoint();
420
+ const resultElement = elementParser._run(ctx);
421
+ if (resultElement === null) {
422
+ if (trailing) {
423
+ ctx.stream.reset(beforeElement);
424
+ } else {
425
+ ctx.stream.reset(beforeSeparator);
426
+ }
427
+ break;
428
+ }
429
+ results.push(resultElement.value);
430
+ }
431
+ return {
432
+ value: results
433
+ };
434
+ });
435
+ }
436
+ function withSepPlus(sep, p) {
437
+ return withSep(sep, p, { requireOne: true }).setTraceName("withSepPlus");
438
+ }
439
+ function withStreamAction(action) {
440
+ return simpleParser(
441
+ `withStreamAction`,
442
+ function _withStreamAction(state) {
443
+ const result = action(state.stream);
444
+ if (result === null) return null;
445
+ return { value: result };
446
+ }
447
+ );
448
+ }
449
+ function parserArg(arg) {
450
+ if (typeof arg === "string") {
451
+ return text(arg);
452
+ } else if (arg instanceof Parser) {
453
+ return arg;
454
+ }
455
+ return fn(arg);
456
+ }
457
+ function fn(fn2) {
458
+ const fp = parser(
459
+ "fn()",
460
+ function _fn(state) {
461
+ if (!fn2) {
462
+ throw new ParseError(
463
+ `fn parser called before definition`,
464
+ state.stream.checkpoint()
465
+ );
466
+ }
467
+ const stage = fn2();
468
+ return stage._run(state);
469
+ }
470
+ );
471
+ return fp;
472
+ }
473
+ function collect(p, collectFn, ctag2) {
474
+ const origAfter = collectFn.after ?? collectFn;
475
+ const beforeFn = collectFn.before;
476
+ let afterFn = origAfter;
477
+ if (ctag2) {
478
+ afterFn = (cc) => {
479
+ const result = origAfter(cc);
480
+ if (result !== void 0 && result !== null) {
481
+ addTagValue(cc.tags, ctag2, result);
482
+ }
483
+ return result;
484
+ };
485
+ }
486
+ const debugName = ctag2 ? `${p.debugName}-${ctag2}` : `${p.debugName}`;
487
+ const collectParser = parser(
488
+ `collect`,
489
+ function _collect(ctx) {
490
+ const origStart = ctx.stream.checkpoint();
491
+ if (beforeFn) {
492
+ queueCollectFn(ctx, origStart, beforeFn, `${debugName}.before`);
493
+ }
494
+ return runAndCollectAfter(p, ctx, afterFn, debugName);
495
+ }
496
+ );
497
+ return collectParser;
498
+ }
499
+ function tagScope(arg) {
500
+ const p = parserArg(arg);
501
+ const sp = parser(
502
+ `tagScope`,
503
+ function _tagScope(ctx) {
504
+ const origStart = ctx.stream.checkpoint();
505
+ let origTags;
506
+ queueCollectFn(
507
+ ctx,
508
+ origStart,
509
+ (cc) => {
510
+ origTags = cloneTags(cc.tags);
511
+ cc.tags = {};
512
+ },
513
+ `scope.before ${p.debugName}`
514
+ );
515
+ return runAndCollectAfter(
516
+ p,
517
+ ctx,
518
+ (cc) => {
519
+ cc.tags = origTags;
520
+ },
521
+ `tagScope`
522
+ );
523
+ }
524
+ );
525
+ return sp;
526
+ }
527
+ function cloneTags(tags) {
528
+ const cloned = Object.entries(tags).map(([tag, values]) => {
529
+ return [tag, [...values]];
530
+ });
531
+ return Object.fromEntries(cloned);
532
+ }
533
+ function ctag(p, name2) {
534
+ const cp = parser(
535
+ `ctag`,
536
+ function _ctag(ctx) {
537
+ return runAndCollectAfter(
538
+ p,
539
+ ctx,
540
+ (cc) => {
541
+ const valueEntry = last$1(cc._values);
542
+ addTagValue(cc.tags, name2, valueEntry.value);
543
+ },
544
+ `ctag ${name2}`
545
+ );
546
+ }
547
+ );
548
+ return cp;
549
+ }
550
+ function runAndCollectAfter(p, ctx, collectFn, debugName = "") {
551
+ const origStart = ctx.stream.checkpoint();
552
+ const result = p._run(ctx);
553
+ if (result) {
554
+ queueCollectFn(ctx, origStart, collectFn, debugName);
555
+ }
556
+ return result;
557
+ }
558
+ function queueCollectFn(ctx, origStart, collectFn, debugName) {
559
+ const srcPosition = refinePosition(ctx.stream, origStart);
560
+ ctx._collect.push({
561
+ srcPosition,
562
+ collectFn,
563
+ debugName
564
+ });
565
+ }
566
+ function pushOpenArray(cc) {
567
+ cc._values.push({ value: null, openArray: [] });
568
+ }
569
+ function closeArray(cc) {
570
+ const lastValue = last$1(cc._values);
571
+ if (lastValue.openArray === void 0)
572
+ console.log("---closeArray: no open array");
573
+ cc._values.pop();
574
+ saveCollectValue(cc, lastValue.openArray);
575
+ }
576
+ function ptag(p, name2) {
577
+ const cp = parser(
578
+ `ptag`,
579
+ function _ptag(ctx) {
580
+ const origStart = ctx.stream.checkpoint();
581
+ const result = p._run(ctx);
582
+ if (result) {
583
+ const tagFn = (ctx2) => addTagValue(ctx2.tags, name2, result.value);
584
+ queueCollectFn(ctx, origStart, tagFn, `ptag ${name2}`);
585
+ }
586
+ return result;
587
+ }
588
+ );
589
+ return cp;
590
+ }
591
+ function addTagValue(tags, name2, value) {
592
+ if (tags[name2] === void 0) {
593
+ tags[name2] = [];
594
+ }
595
+ tags[name2].push(value);
596
+ }
597
+ function runCollection(_collect, app, stream) {
598
+ const tags = {};
599
+ const { src } = stream;
600
+ const _values = [{ value: null, openArray: void 0 }];
601
+ const collectContext = {
602
+ tags,
603
+ src,
604
+ start: -1,
605
+ end: -1,
606
+ app,
607
+ _values
608
+ };
609
+ _collect.forEach((entry) => {
610
+ const { collectFn, srcPosition } = entry;
611
+ collectContext.start = srcPosition.start;
612
+ collectContext.end = srcPosition.end;
613
+ const collectResult = collectFn(collectContext);
614
+ saveCollectValue(collectContext, collectResult);
615
+ });
616
+ }
617
+ function saveCollectValue(cc, value) {
618
+ if (value !== void 0) {
619
+ const valueEntry = last$1(cc._values);
620
+ if (!valueEntry) console.log("----saveCollectValue: no valueEntry");
621
+ if (valueEntry) valueEntry.value = value;
622
+ if ((valueEntry == null ? void 0 : valueEntry.openArray) !== void 0) {
623
+ valueEntry.openArray.push(value);
624
+ }
625
+ }
626
+ }
627
+ function last$1(elems) {
628
+ return elems[elems.length - 1];
629
+ }
630
+ function refinePosition(stream, origStart) {
631
+ const end = stream.checkpoint();
632
+ stream.reset(origStart);
633
+ const start = skipIgnored(stream);
634
+ stream.reset(end);
635
+ return { start, end };
636
+ }
637
+ function skipIgnored(stream) {
638
+ const result = stream.nextToken();
639
+ if (result === null) {
640
+ return stream.checkpoint();
641
+ } else {
642
+ stream.reset(result.span[0]);
643
+ return stream.checkpoint();
644
+ }
645
+ }
646
+ class ParseError extends Error {
647
+ constructor(msg, position) {
648
+ super(msg);
649
+ this.position = position;
650
+ }
651
+ }
652
+ class Parser {
653
+ constructor(args) {
654
+ this.fn = args.fn;
655
+ }
656
+ /** run the parser given an already created parsing context
657
+ *
658
+ * Execute a parser by running the core parsing fn given the parsing context
659
+ * also:
660
+ * . log if tracing is enabled
661
+ * . backtrack on failure
662
+ * . rollback context on failure
663
+ */
664
+ _run(context) {
665
+ {
666
+ const origAppContext = context.app.context;
667
+ const origCollectLength = context._collect.length;
668
+ const result = this.fn(context);
669
+ if (result === null) {
670
+ context.app.context = origAppContext;
671
+ context._collect.length = origCollectLength;
672
+ }
673
+ return result;
674
+ }
675
+ }
676
+ /** tag parse results */
677
+ ptag(name2) {
678
+ return ptag(this, name2);
679
+ }
680
+ /** tag collect results */
681
+ ctag(name2) {
682
+ return ctag(this, name2);
683
+ }
684
+ /** record a name for debug tracing */
685
+ setTraceName(name2) {
686
+ return this;
687
+ }
688
+ /** trigger tracing for this parser (and by default also this parsers descendants) */
689
+ setTrace(opts = {}) {
690
+ return this;
691
+ }
692
+ /** map results to a new value, or add to app state as a side effect.
693
+ * Return null to cause the parser to fail.
694
+ * SAFETY: Side-effects should not be done if backtracking could occur!
695
+ */
696
+ mapExtended(fn2) {
697
+ return mapExtended(this, fn2);
698
+ }
699
+ /** map results to a new value.
700
+ */
701
+ map(fn2) {
702
+ return map(this, fn2);
703
+ }
704
+ /** Queue a function that runs later, typically to collect AST elements from the parse.
705
+ * when a commit() is parsed.
706
+ * Collection functions are dropped with parser backtracking, so
707
+ * only succsessful parses are collected. */
708
+ collect(fn2, ctag2) {
709
+ return collect(this, fn2, ctag2);
710
+ }
711
+ /** switch next parser based on results */
712
+ toParser(fn2) {
713
+ return toParser(this, fn2);
714
+ }
715
+ /**
716
+ * start parsing
717
+ *
718
+ * @throws {ParseError} when a combinator like `req` fails
719
+ */
720
+ parse(init) {
721
+ const { stream, appState: app = { context: {}, stable: [] } } = init;
722
+ const _collect = [];
723
+ const result = this._run({
724
+ stream,
725
+ app,
726
+ _collect
727
+ });
728
+ if (result) runCollection(_collect, app, stream);
729
+ return result;
730
+ }
731
+ /** name of this parser for debugging/tracing */
732
+ get debugName() {
733
+ return "parser";
734
+ }
735
+ }
736
+ function parser(traceName, fn2, terminal) {
737
+ return new Parser({ fn: fn2, traceName, terminal });
738
+ }
739
+ function simpleParser(traceName, parserFn) {
740
+ return parser(traceName, parserFn, true);
741
+ }
742
+ function mapExtended(p, fn2) {
743
+ const mapParser = parser(
744
+ `mapExtended`,
745
+ function _mapExtended(ctx) {
746
+ const extended = runExtended(ctx, p);
747
+ if (!extended) return null;
748
+ const mappedValue = fn2(extended);
749
+ if (mappedValue === null) return null;
750
+ return { value: mappedValue };
751
+ }
752
+ );
753
+ return mapParser;
754
+ }
755
+ function map(p, fn2) {
756
+ const mapParser = parser(
757
+ `map`,
758
+ function _map(ctx) {
759
+ const result = p._run(ctx);
760
+ if (result === null) return null;
761
+ return { value: fn2(result.value) };
762
+ }
763
+ );
764
+ return mapParser;
765
+ }
766
+ function toParser(p, toParserFn) {
767
+ const newParser = parser(
768
+ "toParser",
769
+ function _toParser(ctx) {
770
+ const result = p._run(ctx);
771
+ if (result === null) return null;
772
+ const newParser2 = toParserFn(result);
773
+ if (newParser2 === null) {
774
+ return result;
775
+ }
776
+ const nextResult = newParser2._run(ctx);
777
+ return nextResult;
778
+ }
779
+ );
780
+ return newParser;
781
+ }
782
+ function runExtended(ctx, p) {
783
+ const origStart = ctx.stream.checkpoint();
784
+ const origResults = p._run(ctx);
785
+ if (origResults === null) {
786
+ ctx.stream.reset(origStart);
787
+ return null;
788
+ }
789
+ const { app } = ctx;
790
+ return { ...origResults, app };
791
+ }
792
+ function trackChildren(p, ...args) {
793
+ }
794
+ class SrcMap {
795
+ constructor(dest, entries = []) {
796
+ this.dest = dest;
797
+ this.entries = entries;
798
+ }
799
+ /** add a new mapping from src to dest ranges.
800
+ * entries must be non-overlapping in the destination
801
+ */
802
+ addEntries(newEntries) {
803
+ this.entries.push(...newEntries);
804
+ }
805
+ /** given positions in the dest string,
806
+ * @return corresponding positions in the src strings */
807
+ mapPositions(...positions) {
808
+ return positions.map((p) => this.destToSrc(p));
809
+ }
810
+ /** internally compress adjacent entries where possible */
811
+ compact() {
812
+ if (!this.entries.length) return;
813
+ let prev = this.entries[0];
814
+ const newEntries = [prev];
815
+ for (let i = 1; i < this.entries.length; i++) {
816
+ const e = this.entries[i];
817
+ if (e.src.path === prev.src.path && e.src.text === prev.src.text && prev.destEnd === e.destStart && prev.srcEnd === e.srcStart) {
818
+ prev.destEnd = e.destEnd;
819
+ prev.srcEnd = e.srcEnd;
820
+ } else {
821
+ newEntries.push(e);
822
+ prev = e;
823
+ }
824
+ }
825
+ this.entries = newEntries;
826
+ }
827
+ /** sort in destination order */
828
+ sort() {
829
+ this.entries.sort((a, b) => a.destStart - b.destStart);
830
+ }
831
+ /** This SrcMap's destination is a src for the other srcmap,
832
+ * so combine the two and return the result.
833
+ */
834
+ merge(other) {
835
+ if (other === this) return this;
836
+ const mappedEntries = other.entries.filter(
837
+ (e) => e.src.path === this.dest.path && e.src.text === this.dest.text
838
+ );
839
+ if (mappedEntries.length === 0) {
840
+ console.log("other source map does not link to this one");
841
+ return other;
842
+ }
843
+ sortSrc(mappedEntries);
844
+ const newEntries = mappedEntries.map((e) => {
845
+ const { src, position: srcStart } = this.destToSrc(e.srcStart);
846
+ const { src: endSrc, position: srcEnd } = this.destToSrc(e.srcEnd);
847
+ if (endSrc !== src) throw new Error("NYI, need to split");
848
+ const newEntry = {
849
+ src,
850
+ srcStart,
851
+ srcEnd,
852
+ destStart: e.destStart,
853
+ destEnd: e.destEnd
854
+ };
855
+ return newEntry;
856
+ });
857
+ const otherSources = other.entries.filter(
858
+ (e) => e.src.path !== this.dest.path || e.src.text !== this.dest.text
859
+ );
860
+ const newMap = new SrcMap(other.dest, [...otherSources, ...newEntries]);
861
+ newMap.sort();
862
+ return newMap;
863
+ }
864
+ /**
865
+ * @param entries should be sorted in destStart order
866
+ * @return the source position corresponding to a provided destination position
867
+ *
868
+ */
869
+ destToSrc(destPos) {
870
+ const entry = this.entries.find(
871
+ (e) => e.destStart <= destPos && e.destEnd >= destPos
872
+ );
873
+ if (!entry) {
874
+ return {
875
+ src: this.dest,
876
+ position: destPos
877
+ };
878
+ }
879
+ return {
880
+ src: entry.src,
881
+ position: entry.srcStart + destPos - entry.destStart
882
+ };
883
+ }
884
+ }
885
+ function sortSrc(entries) {
886
+ entries.sort((a, b) => a.srcStart - b.srcStart);
887
+ }
888
+ class SrcMapBuilder {
889
+ constructor(source) {
890
+ __privateAdd(this, _fragments, []);
891
+ __privateAdd(this, _destLength, 0);
892
+ __privateAdd(this, _entries, []);
893
+ this.source = source;
894
+ }
895
+ /** append a string fragment to the destination string */
896
+ add(fragment, srcStart, srcEnd) {
897
+ const destStart = __privateGet(this, _destLength);
898
+ __privateSet(this, _destLength, __privateGet(this, _destLength) + fragment.length);
899
+ const destEnd = __privateGet(this, _destLength);
900
+ __privateGet(this, _fragments).push(fragment);
901
+ __privateGet(this, _entries).push({
902
+ src: this.source,
903
+ srcStart,
904
+ srcEnd,
905
+ destStart,
906
+ destEnd
907
+ });
908
+ }
909
+ /**
910
+ * Append a fragment to the destination string,
911
+ * mapping source to the pervious,
912
+ * and guessing that the source fragment is just as long as the the dest fragment.
913
+ * (LATER we plan to drop or make optional src end positions)
914
+ */
915
+ appendNext(fragment) {
916
+ var _a;
917
+ const lastEnd = ((_a = __privateGet(this, _entries).at(-1)) == null ? void 0 : _a.destEnd) ?? 0;
918
+ this.add(fragment, lastEnd, lastEnd + fragment.length);
919
+ }
920
+ addSynthetic(fragment, syntheticSource, srcStart, srcEnd) {
921
+ const destStart = __privateGet(this, _destLength);
922
+ __privateSet(this, _destLength, __privateGet(this, _destLength) + fragment.length);
923
+ const destEnd = __privateGet(this, _destLength);
924
+ __privateGet(this, _fragments).push(fragment);
925
+ __privateGet(this, _entries).push({
926
+ src: { text: syntheticSource },
927
+ srcStart,
928
+ srcEnd,
929
+ destStart,
930
+ destEnd
931
+ });
932
+ }
933
+ /** append a synthetic newline, mapped to previous source location */
934
+ addNl() {
935
+ const lastEntry = __privateGet(this, _entries).at(-1) ?? { srcStart: 0, srcEnd: 0 };
936
+ const { srcStart, srcEnd } = lastEntry;
937
+ this.add("\n", srcStart, srcEnd);
938
+ }
939
+ /** copy a string fragment from the src to the destination string */
940
+ addCopy(srcStart, srcEnd) {
941
+ const fragment = this.source.text.slice(srcStart, srcEnd);
942
+ this.add(fragment, srcStart, srcEnd);
943
+ }
944
+ /** return a SrcMap */
945
+ static build(builders) {
946
+ const map2 = new SrcMap(
947
+ { text: builders.map((b) => __privateGet(b, _fragments).join("")).join("") },
948
+ builders.flatMap((b) => __privateGet(b, _entries))
949
+ );
950
+ map2.compact();
951
+ return map2;
952
+ }
953
+ }
954
+ _fragments = new WeakMap();
955
+ _destLength = new WeakMap();
956
+ _entries = new WeakMap();
957
+ class CachingStream {
958
+ constructor(inner) {
959
+ this.inner = inner;
960
+ this.cache = new Cache(5);
961
+ }
962
+ checkpoint() {
963
+ return this.inner.checkpoint();
964
+ }
965
+ reset(position) {
966
+ this.inner.reset(position);
967
+ }
968
+ nextToken() {
969
+ const startPos = this.checkpoint();
970
+ const cachedValue = this.cache.get(startPos);
971
+ if (cachedValue !== void 0) {
972
+ this.reset(cachedValue.checkpoint);
973
+ return cachedValue.token;
974
+ } else {
975
+ const token2 = this.inner.nextToken();
976
+ const checkpoint = this.checkpoint();
977
+ this.cache.set(startPos, { token: token2, checkpoint });
978
+ return token2;
979
+ }
980
+ }
981
+ get src() {
982
+ return this.inner.src;
983
+ }
984
+ }
985
+ class Cache extends Map {
986
+ constructor(max) {
987
+ super();
988
+ this.max = max;
989
+ }
990
+ set(k, v) {
991
+ if (this.size > this.max) {
992
+ const first = this.keys().next().value;
993
+ if (first) this.delete(first);
994
+ }
995
+ return super.set(k, v);
996
+ }
997
+ }
998
+ function toRegexSource(nameExp) {
999
+ const [name2, e] = nameExp;
1000
+ if (typeof e === "string") {
1001
+ const expSrc = `(${escapeRegex(e)})`;
1002
+ verifyNonCapturing(name2, new RegExp(expSrc));
1003
+ return expSrc;
1004
+ } else {
1005
+ verifyNonCapturing(name2, e);
1006
+ return `(${e.source})`;
1007
+ }
1008
+ }
1009
+ function verifyNonCapturing(name2, exp) {
1010
+ const willMatch = new RegExp("|" + exp.source);
1011
+ const result = willMatch.exec("");
1012
+ if (result.length > 1) {
1013
+ throw new Error(
1014
+ `match expression groups must be non-capturing: ${name2}: /${exp.source}/. Use (?:...) instead.`
1015
+ );
1016
+ }
1017
+ }
1018
+ const regexSpecials = /[$+*.?|(){}[\]\\/^]/g;
1019
+ function escapeRegex(s) {
1020
+ return s.replace(regexSpecials, "\\$&");
1021
+ }
1022
+ function matchOneOf(syms) {
1023
+ const symbolList = syms.split(/\s+/).sort((a, b) => b.length - a.length);
1024
+ const escaped = symbolList.filter((s) => s).map(escapeRegex);
1025
+ return new RegExp(escaped.join("|"));
1026
+ }
1027
+ class MatchersStream {
1028
+ constructor(text2, matchers) {
1029
+ this.text = text2;
1030
+ this.matchers = matchers;
1031
+ this.position = 0;
1032
+ }
1033
+ checkpoint() {
1034
+ return this.position;
1035
+ }
1036
+ reset(position) {
1037
+ this.position = position;
1038
+ }
1039
+ nextToken() {
1040
+ const result = this.matchers.execAt(this.text, this.position);
1041
+ if (result === null) return null;
1042
+ this.position = result.span[1];
1043
+ return result;
1044
+ }
1045
+ get src() {
1046
+ return this.text;
1047
+ }
1048
+ }
1049
+ class RegexMatchers {
1050
+ constructor(matchers) {
1051
+ this.groups = Object.keys(matchers);
1052
+ const expParts = Object.entries(matchers).map(toRegexSource).join("|");
1053
+ this.exp = new RegExp(expParts, "dyu");
1054
+ }
1055
+ execAt(text2, position) {
1056
+ this.exp.lastIndex = position;
1057
+ const matches = this.exp.exec(text2);
1058
+ const matchedIndex = findGroupDex(matches == null ? void 0 : matches.indices);
1059
+ if (matchedIndex) {
1060
+ const { span: span2, groupDex } = matchedIndex;
1061
+ const kind2 = this.groups[groupDex];
1062
+ return {
1063
+ kind: kind2,
1064
+ span: span2,
1065
+ text: text2.slice(span2[0], span2[1])
1066
+ };
1067
+ } else {
1068
+ return null;
1069
+ }
1070
+ }
1071
+ }
1072
+ function findGroupDex(indices) {
1073
+ if (indices !== void 0) {
1074
+ for (let i = 1; i < indices.length; i++) {
1075
+ const span2 = indices[i];
1076
+ if (span2 !== void 0) {
1077
+ return { span: span2, groupDex: i - 1 };
1078
+ }
1079
+ }
1080
+ }
1081
+ }
1082
+ function assertThatDebug(condition, msg) {
1083
+ }
1084
+ function assertUnreachable(value) {
1085
+ throw new ErrorWithData2("Unreachable value", { data: value });
1086
+ }
1087
+ class ErrorWithData2 extends Error {
1088
+ constructor(message, options) {
1089
+ super(message, options);
1090
+ this.data = options == null ? void 0 : options.data;
1091
+ }
1092
+ }
1093
+ function last(a) {
1094
+ return a[a.length - 1];
1095
+ }
1096
+ function filterMap(arr, fn2) {
1097
+ const out = [];
1098
+ for (const t of arr) {
1099
+ const u = fn2(t);
1100
+ if (u) out.push(u);
1101
+ }
1102
+ return out;
1103
+ }
1104
+ function findMap(arr, fn2) {
1105
+ for (const t of arr) {
1106
+ const u = fn2(t);
1107
+ if (u) return u;
1108
+ }
1109
+ return void 0;
1110
+ }
1111
+ function mapValues(obj, fn2) {
1112
+ return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, fn2(v)]));
1113
+ }
1114
+ function offsetToLineNumber(offset, text2) {
1115
+ offset = Math.min(text2.length, Math.max(0, offset));
1116
+ let lineStartOffset = 0;
1117
+ let lineNum = 1;
1118
+ while (true) {
1119
+ const lineEnd = text2.indexOf("\n", lineStartOffset);
1120
+ if (lineEnd === -1 || offset <= lineEnd) {
1121
+ const linePos = 1 + (offset - lineStartOffset);
1122
+ return [lineNum, linePos];
1123
+ } else {
1124
+ lineStartOffset = lineEnd + 1;
1125
+ lineNum += 1;
1126
+ }
1127
+ }
1128
+ }
1129
+ function errorHighlight(source, span2) {
1130
+ let lineStartOffset = source.lastIndexOf("\n", span2[0]);
1131
+ if (lineStartOffset === -1) {
1132
+ lineStartOffset = 0;
1133
+ }
1134
+ let lineEndOffset = source.indexOf("\n", span2[0]);
1135
+ if (lineEndOffset === -1) {
1136
+ lineEndOffset = source.length;
1137
+ }
1138
+ const errorLength = span2[1] - span2[0];
1139
+ const caretCount = Math.max(1, errorLength);
1140
+ const linePos = span2[0] - lineStartOffset;
1141
+ return [
1142
+ source.slice(lineStartOffset, lineEndOffset),
1143
+ " ".repeat(linePos) + "^".repeat(caretCount)
1144
+ ];
1145
+ }
1146
+ function elementValid(elem, conditions) {
1147
+ const attributes = elem.attributes;
1148
+ if (!attributes) return true;
1149
+ const ifAttr = findMap(attributes, extractIfAttribute);
1150
+ return !ifAttr || evaluateIfAttribute(ifAttr);
1151
+ }
1152
+ function scopeValid(scope, conditions) {
1153
+ const { ifAttribute } = scope;
1154
+ if (!ifAttribute) return true;
1155
+ const result = evaluateIfAttribute(ifAttribute);
1156
+ return result;
1157
+ }
1158
+ function extractIfAttribute(elem) {
1159
+ const { attribute } = elem;
1160
+ return attribute.kind === "@if" ? attribute : void 0;
1161
+ }
1162
+ function evaluateIfAttribute(ifAttribute, conditions) {
1163
+ return evaluateIfExpression(ifAttribute.param.expression);
1164
+ }
1165
+ function evaluateIfExpression(expression2, conditions) {
1166
+ const { kind: kind2 } = expression2;
1167
+ if (kind2 == "unary-expression") {
1168
+ assertThatDebug(expression2.operator.value === "!");
1169
+ return !evaluateIfExpression(expression2.expression);
1170
+ } else if (kind2 == "binary-expression") {
1171
+ const op = expression2.operator.value;
1172
+ const leftResult = evaluateIfExpression(expression2.left);
1173
+ if (op === "||") {
1174
+ return leftResult || evaluateIfExpression(expression2.right);
1175
+ } else if (op === "&&") {
1176
+ return leftResult && evaluateIfExpression(expression2.right);
1177
+ } else {
1178
+ assertUnreachable(op);
1179
+ }
1180
+ } else if (kind2 == "literal") {
1181
+ const { value } = expression2;
1182
+ return value === "true";
1183
+ } else if (kind2 == "parenthesized-expression") {
1184
+ return evaluateIfExpression(expression2.expression);
1185
+ } else {
1186
+ throw new Error("unexpected @if expression ${expression}");
1187
+ }
1188
+ }
1189
+ function mergeScope(a, b) {
1190
+ assertThatDebug(a.kind === b.kind);
1191
+ assertThatDebug(a.parent === b.parent);
1192
+ assertThatDebug(!b.ifAttribute);
1193
+ a.contents = a.contents.concat(b.contents);
1194
+ }
1195
+ function resetScopeIds() {
1196
+ scopeId = 0;
1197
+ identId = 0;
1198
+ }
1199
+ let scopeId = 0;
1200
+ let identId = 0;
1201
+ function nextIdentId() {
1202
+ return identId++;
1203
+ }
1204
+ function emptyScope(parent, kind2 = "scope") {
1205
+ const id = scopeId++;
1206
+ return { id, kind: kind2, parent, contents: [] };
1207
+ }
1208
+ function childScope(child) {
1209
+ const { kind: kind2 } = child;
1210
+ return kind2 === "partial" || kind2 === "scope";
1211
+ }
1212
+ function publicDecl(scope, name2, conditions) {
1213
+ for (const elem of scope.contents) {
1214
+ if (elem.kind === "decl" && elem.originalName === name2) {
1215
+ return elem;
1216
+ } else if (elem.kind === "partial" && scopeValid(elem)) {
1217
+ const found = publicDecl(elem, name2);
1218
+ if (found) return found;
1219
+ }
1220
+ }
1221
+ }
1222
+ class LineWrapper {
1223
+ constructor(indent = 0, maxWidth = 60, hangingIndent = 2) {
1224
+ __privateAdd(this, _fragments2, []);
1225
+ __privateAdd(this, _column, 0);
1226
+ __privateAdd(this, _spc);
1227
+ __privateAdd(this, _oneLine, true);
1228
+ __privateAdd(this, _isHanging, false);
1229
+ __privateAdd(this, _hangingSpc);
1230
+ this.indent = indent;
1231
+ this.maxWidth = maxWidth;
1232
+ this.hangingIndent = hangingIndent;
1233
+ __privateSet(this, _spc, " ".repeat(indent));
1234
+ __privateSet(this, _hangingSpc, " ".repeat(hangingIndent));
1235
+ }
1236
+ /** add a new line to the constructed string */
1237
+ nl() {
1238
+ __privateGet(this, _fragments2).push("\n");
1239
+ __privateSet(this, _column, 0);
1240
+ __privateSet(this, _oneLine, false);
1241
+ __privateSet(this, _isHanging, false);
1242
+ }
1243
+ /** add a string, wrapping to the next line if necessary */
1244
+ add(s) {
1245
+ if (__privateGet(this, _column) + firstLineLength(s) > this.maxWidth) {
1246
+ this.hangingNl();
1247
+ }
1248
+ if (__privateGet(this, _column) === 0) {
1249
+ __privateGet(this, _fragments2).push(__privateGet(this, _spc));
1250
+ if (__privateGet(this, _isHanging)) {
1251
+ __privateGet(this, _fragments2).push(__privateGet(this, _hangingSpc));
1252
+ }
1253
+ __privateSet(this, _column, this.indent);
1254
+ }
1255
+ __privateGet(this, _fragments2).push(s);
1256
+ __privateSet(this, _column, __privateGet(this, _column) + s.length);
1257
+ }
1258
+ /** add a raw block of text with no wrapping */
1259
+ addBlock(s, andNewLine = true) {
1260
+ __privateGet(this, _fragments2).push(s);
1261
+ if (andNewLine) this.nl();
1262
+ }
1263
+ /** @return the constructed string */
1264
+ get result() {
1265
+ return __privateGet(this, _fragments2).join("");
1266
+ }
1267
+ /** true if the result contains no newlines */
1268
+ get oneLine() {
1269
+ return __privateGet(this, _oneLine);
1270
+ }
1271
+ hangingNl() {
1272
+ this.nl();
1273
+ __privateSet(this, _isHanging, true);
1274
+ }
1275
+ }
1276
+ _fragments2 = new WeakMap();
1277
+ _column = new WeakMap();
1278
+ _spc = new WeakMap();
1279
+ _oneLine = new WeakMap();
1280
+ _isHanging = new WeakMap();
1281
+ _hangingSpc = new WeakMap();
1282
+ function firstLineLength(s) {
1283
+ const i = s.indexOf("\n");
1284
+ return i === -1 ? s.length : i;
1285
+ }
1286
+ function scopeToString(scope, indent = 0, shortIdents = true) {
1287
+ const { contents, kind: kind2, ifAttribute } = scope;
1288
+ const str = new LineWrapper(indent);
1289
+ const attrStrings = ifAttribute && attributeToString$1(ifAttribute);
1290
+ if (attrStrings) str.add(attrStrings + " ");
1291
+ if (kind2 === "partial") str.add("-");
1292
+ str.add("{ ");
1293
+ const last2 = contents.length - 1;
1294
+ let lastWasScope = false;
1295
+ let hasBlock = false;
1296
+ contents.forEach((elem, i) => {
1297
+ if (childScope(elem)) {
1298
+ const childScope2 = elem;
1299
+ const childBlock = scopeToString(childScope2, indent + 2, shortIdents);
1300
+ !lastWasScope && str.nl();
1301
+ str.addBlock(childBlock);
1302
+ lastWasScope = true;
1303
+ hasBlock = true;
1304
+ } else {
1305
+ lastWasScope && str.add(" ");
1306
+ lastWasScope = false;
1307
+ const ident2 = elem;
1308
+ if (shortIdents) {
1309
+ str.add(identShortString(ident2));
1310
+ } else {
1311
+ str.add(identToString(ident2));
1312
+ }
1313
+ if (i < last2) str.add(" ");
1314
+ }
1315
+ });
1316
+ if (!hasBlock && str.oneLine) {
1317
+ str.add(" }");
1318
+ } else {
1319
+ if (hasBlock && !lastWasScope) str.nl();
1320
+ str.add("}");
1321
+ }
1322
+ str.add(` #${scope.id}`);
1323
+ return str.result;
1324
+ }
1325
+ function scopeToStringLong(scope) {
1326
+ return scopeToString(scope, 0, false);
1327
+ }
1328
+ function identShortString(ident2) {
1329
+ const { kind: kind2, originalName } = ident2;
1330
+ const prefix = kind2 === "decl" ? "%" : "";
1331
+ return `${prefix}${originalName}`;
1332
+ }
1333
+ function identToString(ident2) {
1334
+ if (!ident2) return JSON.stringify(ident2);
1335
+ const { kind: kind2, originalName } = ident2;
1336
+ const idStr = ident2.id ? `#${ident2.id}` : "";
1337
+ if (kind2 === "ref") {
1338
+ const ref = identToString(ident2.refersTo);
1339
+ return `${originalName} ${idStr} -> ${ref}`;
1340
+ } else {
1341
+ const { mangledName } = ident2;
1342
+ const mangled = mangledName ? `(${mangledName})` : "";
1343
+ return `%${originalName}${mangled} ${idStr} `;
1344
+ }
1345
+ }
1346
+ function makeLiveDecls(parent = null) {
1347
+ return { decls: /* @__PURE__ */ new Map(), parent };
1348
+ }
1349
+ function minimalMangle(_d, _s, proposedName, globalNames) {
1350
+ return minimallyMangledName(proposedName, globalNames);
1351
+ }
1352
+ function minimallyMangledName(proposedName, globalNames) {
1353
+ let renamed = proposedName;
1354
+ let conflicts = 0;
1355
+ while (globalNames.has(renamed)) {
1356
+ renamed = proposedName + conflicts++;
1357
+ }
1358
+ return renamed;
1359
+ }
1360
+ function flattenTreeImport(imp) {
1361
+ return recursiveResolve([], [], imp.segments, imp.finalSegment);
1362
+ function recursiveResolve(resolvedImportPath, resolvedExportPath, remainingPath, finalSegment) {
1363
+ if (remainingPath.length > 0) {
1364
+ const [segment, ...rest] = remainingPath;
1365
+ const importPath = [...resolvedImportPath, segment.name];
1366
+ const modulePath = [...resolvedExportPath, segment.name];
1367
+ return recursiveResolve(importPath, modulePath, rest, finalSegment);
1368
+ } else if (finalSegment.kind === "import-collection") {
1369
+ return finalSegment.subtrees.flatMap((elem) => {
1370
+ return recursiveResolve(
1371
+ resolvedImportPath,
1372
+ resolvedExportPath,
1373
+ elem.segments,
1374
+ elem.finalSegment
1375
+ );
1376
+ });
1377
+ } else if (finalSegment.kind === "import-item") {
1378
+ const importPath = [
1379
+ ...resolvedImportPath,
1380
+ finalSegment.as ?? finalSegment.name
1381
+ ];
1382
+ const modulePath = [...resolvedExportPath, finalSegment.name];
1383
+ return [{ importPath, modulePath }];
1384
+ } else {
1385
+ assertUnreachable(finalSegment);
1386
+ }
1387
+ }
1388
+ }
1389
+ var spaces = memoize((nesting) => {
1390
+ return " ".repeat(nesting);
1391
+ });
1392
+ var defaultCallerSize = 20;
1393
+ "\n" + spaces(defaultCallerSize + 3);
1394
+ function memoize(fn2) {
1395
+ const cache = /* @__PURE__ */ new Map();
1396
+ return function(...args) {
1397
+ const key = JSON.stringify(args);
1398
+ if (cache.has(key)) {
1399
+ return cache.get(key);
1400
+ } else {
1401
+ const value = fn2(...args);
1402
+ cache.set(key, value);
1403
+ return value;
1404
+ }
1405
+ };
1406
+ }
1407
+ if (typeof DOMRect === "undefined") {
1408
+ globalThis.DOMRect = function() {
1409
+ };
1410
+ }
1411
+ function importElem(cc) {
1412
+ var _a;
1413
+ const importElems = (_a = cc.tags.owo) == null ? void 0 : _a[0];
1414
+ for (const importElem2 of importElems) {
1415
+ cc.app.stable.imports.push(importElem2.imports);
1416
+ addToOpenElem(cc, importElem2);
1417
+ }
1418
+ }
1419
+ function addToOpenElem(cc, elem) {
1420
+ const weslContext = cc.app.context;
1421
+ const { openElems } = weslContext;
1422
+ if (openElems && openElems.length) {
1423
+ const open = openElems[openElems.length - 1];
1424
+ open.contents.push(elem);
1425
+ }
1426
+ }
1427
+ function refIdent(cc) {
1428
+ const { src, start, end } = cc;
1429
+ const app = cc.app;
1430
+ const { srcModule } = app.stable;
1431
+ const originalName = src.slice(start, end);
1432
+ const kind2 = "ref";
1433
+ const ident2 = {
1434
+ kind: kind2,
1435
+ originalName,
1436
+ ast: cc.app.stable,
1437
+ id: nextIdentId(),
1438
+ refIdentElem: null
1439
+ // set below
1440
+ };
1441
+ const identElem = { kind: kind2, start, end, srcModule, ident: ident2 };
1442
+ ident2.refIdentElem = identElem;
1443
+ saveIdent(cc, identElem);
1444
+ addToOpenElem(cc, identElem);
1445
+ return identElem;
1446
+ }
1447
+ function declCollect(cc) {
1448
+ return declCollectInternal(cc, false);
1449
+ }
1450
+ function globalDeclCollect(cc) {
1451
+ return declCollectInternal(cc, true);
1452
+ }
1453
+ function declCollectInternal(cc, isGlobal2) {
1454
+ const { src, start, end } = cc;
1455
+ const app = cc.app;
1456
+ const { scope } = app.context;
1457
+ const { srcModule } = app.stable;
1458
+ const originalName = src.slice(start, end);
1459
+ const kind2 = "decl";
1460
+ const declElem = null;
1461
+ const ident2 = {
1462
+ declElem,
1463
+ kind: kind2,
1464
+ originalName,
1465
+ scope,
1466
+ isGlobal: isGlobal2,
1467
+ id: nextIdentId(),
1468
+ srcModule
1469
+ };
1470
+ const identElem = { kind: kind2, start, end, srcModule, ident: ident2 };
1471
+ saveIdent(cc, identElem);
1472
+ addToOpenElem(cc, identElem);
1473
+ return identElem;
1474
+ }
1475
+ const typedDecl = collectElem(
1476
+ "typeDecl",
1477
+ (cc, openElem) => {
1478
+ var _a, _b;
1479
+ const decl = (_a = cc.tags.decl_elem) == null ? void 0 : _a[0];
1480
+ const typeRef = (_b = cc.tags.typeRefElem) == null ? void 0 : _b[0];
1481
+ const partial = { ...openElem, decl, typeRef };
1482
+ const elem = withTextCover(partial, cc);
1483
+ return elem;
1484
+ }
1485
+ );
1486
+ function saveIdent(cc, identElem) {
1487
+ const { ident: ident2 } = identElem;
1488
+ ident2.id = nextIdentId();
1489
+ const weslContext = cc.app.context;
1490
+ weslContext.scope.contents.push(ident2);
1491
+ }
1492
+ function startScope(cc) {
1493
+ startSomeScope("scope", cc);
1494
+ }
1495
+ function startPartialScope(cc) {
1496
+ startSomeScope("partial", cc);
1497
+ }
1498
+ function startSomeScope(kind2, cc) {
1499
+ const { scope } = cc.app.context;
1500
+ const newScope = emptyScope(scope, kind2);
1501
+ scope.contents.push(newScope);
1502
+ cc.app.context.scope = newScope;
1503
+ }
1504
+ function completeScope(cc) {
1505
+ const weslContext = cc.app.context;
1506
+ const completedScope = weslContext.scope;
1507
+ const ifAttributes = collectIfAttributes(cc);
1508
+ const { parent } = completedScope;
1509
+ if (parent) {
1510
+ weslContext.scope = parent;
1511
+ }
1512
+ completedScope.ifAttribute = ifAttributes == null ? void 0 : ifAttributes[0];
1513
+ return completedScope;
1514
+ }
1515
+ function collectIfAttributes(cc) {
1516
+ const attributes = cc.tags.attribute;
1517
+ return filterIfAttributes(attributes);
1518
+ }
1519
+ function filterIfAttributes(attributes) {
1520
+ if (!attributes) return;
1521
+ return filterMap(
1522
+ attributes,
1523
+ (a) => a.attribute.kind === "@if" ? a.attribute : void 0
1524
+ );
1525
+ }
1526
+ function collectVarLike(kind2) {
1527
+ return collectElem(kind2, (cc, openElem) => {
1528
+ var _a, _b;
1529
+ const name2 = (_a = cc.tags.var_name) == null ? void 0 : _a[0];
1530
+ const decl_scope = (_b = cc.tags.decl_scope) == null ? void 0 : _b[0];
1531
+ const attributes = cc.tags.attribute;
1532
+ const partElem = { ...openElem, name: name2, attributes };
1533
+ const varElem = withTextCover(partElem, cc);
1534
+ name2.decl.ident.declElem = varElem;
1535
+ name2.decl.ident.scope = decl_scope;
1536
+ return varElem;
1537
+ });
1538
+ }
1539
+ const aliasCollect = collectElem(
1540
+ "alias",
1541
+ (cc, openElem) => {
1542
+ var _a, _b, _c, _d;
1543
+ const name2 = (_a = cc.tags.alias_name) == null ? void 0 : _a[0];
1544
+ const alias_scope = (_b = cc.tags.alias_scope) == null ? void 0 : _b[0];
1545
+ const typeRef = (_c = cc.tags.typeRefElem) == null ? void 0 : _c[0];
1546
+ const attributes = ((_d = cc.tags.attributes) == null ? void 0 : _d.flat()) ?? [];
1547
+ const partElem = { ...openElem, name: name2, attributes, typeRef };
1548
+ const aliasElem = withTextCover(partElem, cc);
1549
+ name2.ident.scope = alias_scope;
1550
+ name2.ident.declElem = aliasElem;
1551
+ return aliasElem;
1552
+ }
1553
+ );
1554
+ const fnCollect = collectElem(
1555
+ "fn",
1556
+ (cc, openElem) => {
1557
+ var _a;
1558
+ const ourTags = fnTags(cc);
1559
+ const { name: name2, headerScope, returnScope, bodyScope, body, params } = ourTags;
1560
+ const { attributes, returnAttributes, returnType, fnScope } = ourTags;
1561
+ const fnElem = {
1562
+ ...openElem,
1563
+ ...{ name: name2, attributes, params, returnAttributes, body, returnType }
1564
+ };
1565
+ fnScope.ifAttribute = (_a = filterIfAttributes(attributes)) == null ? void 0 : _a[0];
1566
+ const mergedScope = headerScope;
1567
+ returnScope && mergeScope(mergedScope, returnScope);
1568
+ mergeScope(mergedScope, bodyScope);
1569
+ const filtered = [];
1570
+ for (const e of fnScope.contents) {
1571
+ if (e === headerScope || e == returnScope) {
1572
+ continue;
1573
+ } else if (e === bodyScope) {
1574
+ filtered.push(mergedScope);
1575
+ } else {
1576
+ filtered.push(e);
1577
+ }
1578
+ }
1579
+ fnScope.contents = filtered;
1580
+ name2.ident.declElem = fnElem;
1581
+ name2.ident.scope = mergedScope;
1582
+ return fnElem;
1583
+ }
1584
+ );
1585
+ function fnTags(cc) {
1586
+ const { fn_attributes, fn_name, fn_param, return_attributes } = cc.tags;
1587
+ const { return_type } = cc.tags;
1588
+ const { header_scope, return_scope, body_scope, body_statement } = cc.tags;
1589
+ const { fn_partial_scope } = cc.tags;
1590
+ const name2 = fn_name == null ? void 0 : fn_name[0];
1591
+ const headerScope = header_scope == null ? void 0 : header_scope[0];
1592
+ const returnScope = return_scope == null ? void 0 : return_scope[0];
1593
+ const bodyScope = body_scope == null ? void 0 : body_scope[0];
1594
+ const body = body_statement == null ? void 0 : body_statement[0];
1595
+ const params = (fn_param == null ? void 0 : fn_param.flat(3)) ?? [];
1596
+ const attributes = fn_attributes == null ? void 0 : fn_attributes.flat();
1597
+ const returnAttributes = return_attributes == null ? void 0 : return_attributes.flat();
1598
+ const returnType = return_type == null ? void 0 : return_type.flat(3)[0];
1599
+ const fnScope = fn_partial_scope == null ? void 0 : fn_partial_scope[0];
1600
+ return {
1601
+ ...{ name: name2, headerScope, returnScope, bodyScope, body, params },
1602
+ ...{ attributes, returnAttributes, returnType, fnScope }
1603
+ };
1604
+ }
1605
+ const collectFnParam = collectElem(
1606
+ "param",
1607
+ (cc, openElem) => {
1608
+ var _a, _b;
1609
+ const name2 = (_a = cc.tags.param_name) == null ? void 0 : _a[0];
1610
+ const attributes = ((_b = cc.tags.attributes) == null ? void 0 : _b.flat()) ?? [];
1611
+ const elem = { ...openElem, name: name2, attributes };
1612
+ const paramElem = withTextCover(elem, cc);
1613
+ name2.decl.ident.declElem = paramElem;
1614
+ return paramElem;
1615
+ }
1616
+ );
1617
+ const collectStruct = collectElem(
1618
+ "struct",
1619
+ (cc, openElem) => {
1620
+ var _a, _b, _c;
1621
+ const name2 = (_a = cc.tags.type_name) == null ? void 0 : _a[0];
1622
+ const members = cc.tags.members;
1623
+ const attributes = ((_b = cc.tags.attributes) == null ? void 0 : _b.flat()) ?? [];
1624
+ name2.ident.scope = (_c = cc.tags.struct_scope) == null ? void 0 : _c[0];
1625
+ const structElem = { ...openElem, name: name2, attributes, members };
1626
+ const elem = withTextCover(structElem, cc);
1627
+ name2.ident.declElem = elem;
1628
+ return elem;
1629
+ }
1630
+ );
1631
+ const collectStructMember = collectElem(
1632
+ "member",
1633
+ (cc, openElem) => {
1634
+ var _a, _b, _c;
1635
+ const name2 = (_a = cc.tags.nameElem) == null ? void 0 : _a[0];
1636
+ const typeRef = (_b = cc.tags.typeRefElem) == null ? void 0 : _b[0];
1637
+ const attributes = (_c = cc.tags.attribute) == null ? void 0 : _c.flat(3);
1638
+ const partElem = { ...openElem, name: name2, attributes, typeRef };
1639
+ return withTextCover(partElem, cc);
1640
+ }
1641
+ );
1642
+ const specialAttribute = collectElem(
1643
+ "attribute",
1644
+ (cc, openElem) => {
1645
+ var _a;
1646
+ const attribute = (_a = cc.tags.attr_variant) == null ? void 0 : _a[0];
1647
+ const attrElem = { ...openElem, attribute };
1648
+ return attrElem;
1649
+ }
1650
+ );
1651
+ const assertCollect = attrElemCollect("assert");
1652
+ const statementCollect = attrElemCollect("statement");
1653
+ const switchClauseCollect = attrElemCollect("switch-clause");
1654
+ function attrElemCollect(kind2) {
1655
+ return collectElem(kind2, (cc, openElem) => {
1656
+ var _a;
1657
+ const attributes = (_a = cc.tags.attribute) == null ? void 0 : _a.flat(3);
1658
+ const partElem = { ...openElem, attributes };
1659
+ return withTextCover(partElem, cc);
1660
+ });
1661
+ }
1662
+ const collectAttribute = collectElem(
1663
+ "attribute",
1664
+ (cc, openElem) => {
1665
+ var _a;
1666
+ const params = cc.tags.attrParam;
1667
+ const name2 = (_a = cc.tags.name) == null ? void 0 : _a[0];
1668
+ const kind2 = "@attribute";
1669
+ const stdAttribute = { kind: kind2, name: name2, params };
1670
+ const attrElem = { ...openElem, attribute: stdAttribute };
1671
+ return attrElem;
1672
+ }
1673
+ );
1674
+ const typeRefCollect = collectElem(
1675
+ "type",
1676
+ // @ts-ignore
1677
+ (cc, openElem) => {
1678
+ var _a, _b;
1679
+ let templateParamsTemp = (_a = cc.tags.templateParam) == null ? void 0 : _a.flat(3);
1680
+ const typeRef = (_b = cc.tags.typeRefName) == null ? void 0 : _b[0];
1681
+ const name2 = typeof typeRef === "string" ? typeRef : typeRef.ident;
1682
+ const partElem = {
1683
+ ...openElem,
1684
+ name: name2,
1685
+ templateParams: templateParamsTemp
1686
+ };
1687
+ return withTextCover(partElem, cc);
1688
+ }
1689
+ );
1690
+ const expressionCollect = collectElem(
1691
+ "expression",
1692
+ (cc, openElem) => {
1693
+ const partElem = { ...openElem };
1694
+ return withTextCover(partElem, cc);
1695
+ }
1696
+ );
1697
+ function globalAssertCollect(cc) {
1698
+ var _a;
1699
+ const globalAssert = (_a = cc.tags.const_assert) == null ? void 0 : _a.flat()[0];
1700
+ const ast = cc.app.stable;
1701
+ if (!ast.moduleAsserts) ast.moduleAsserts = [];
1702
+ ast.moduleAsserts.push(globalAssert);
1703
+ }
1704
+ const stuffCollect = collectElem(
1705
+ "stuff",
1706
+ (cc, openElem) => {
1707
+ const partElem = { ...openElem };
1708
+ return withTextCover(partElem, cc);
1709
+ }
1710
+ );
1711
+ const memberRefCollect = collectElem(
1712
+ "memberRef",
1713
+ (cc, openElem) => {
1714
+ const { component, structRef, extra_components } = cc.tags;
1715
+ const member = component[0];
1716
+ const name2 = structRef == null ? void 0 : structRef.flat()[0];
1717
+ const extraComponents = extra_components == null ? void 0 : extra_components.flat()[0];
1718
+ const partElem = {
1719
+ ...openElem,
1720
+ name: name2,
1721
+ member,
1722
+ extraComponents
1723
+ };
1724
+ return withTextCover(partElem, cc);
1725
+ }
1726
+ );
1727
+ function nameCollect(cc) {
1728
+ const { start, end, src, app } = cc;
1729
+ const name2 = src.slice(start, end);
1730
+ const elem = { kind: "name", start, end, name: name2 };
1731
+ addToOpenElem(cc, elem);
1732
+ return elem;
1733
+ }
1734
+ const collectModule = collectElem(
1735
+ "module",
1736
+ (cc, openElem) => {
1737
+ const ccComplete = { ...cc, start: 0, end: cc.src.length };
1738
+ const moduleElem = withTextCover(openElem, ccComplete);
1739
+ const weslState = cc.app.stable;
1740
+ weslState.moduleElem = moduleElem;
1741
+ return moduleElem;
1742
+ }
1743
+ );
1744
+ function directiveCollect(cc) {
1745
+ var _a, _b;
1746
+ const { start, end } = cc;
1747
+ const directive = (_a = cc.tags.directive) == null ? void 0 : _a.flat()[0];
1748
+ const attributes = (_b = cc.tags.attribute) == null ? void 0 : _b.flat();
1749
+ const kind2 = "directive";
1750
+ const elem = { kind: kind2, attributes, start, end, directive };
1751
+ addToOpenElem(cc, elem);
1752
+ return elem;
1753
+ }
1754
+ const scopeCollect = {
1755
+ before: startScope,
1756
+ after: completeScope
1757
+ };
1758
+ const partialScopeCollect = {
1759
+ before: startPartialScope,
1760
+ after: completeScope
1761
+ };
1762
+ function collectElem(kind2, fn2) {
1763
+ return {
1764
+ before: (cc) => {
1765
+ const partialElem = { kind: kind2, contents: [] };
1766
+ const weslContext = cc.app.context;
1767
+ weslContext.openElems.push(partialElem);
1768
+ },
1769
+ after: (cc) => {
1770
+ const weslContext = cc.app.context;
1771
+ const partialElem = weslContext.openElems.pop();
1772
+ console.assert(partialElem && partialElem.kind === kind2);
1773
+ const elem = fn2(cc, { ...partialElem, start: cc.start, end: cc.end });
1774
+ if (elem) addToOpenElem(cc, elem);
1775
+ return elem;
1776
+ }
1777
+ };
1778
+ }
1779
+ function withTextCover(elem, cc) {
1780
+ const contents = coverWithText(cc, elem);
1781
+ return { ...elem, contents };
1782
+ }
1783
+ function coverWithText(cc, elem) {
1784
+ let { start: pos } = cc;
1785
+ const ast = cc.app.stable;
1786
+ const { contents, end } = elem;
1787
+ const sorted = contents.sort((a, b) => a.start - b.start);
1788
+ const elems = [];
1789
+ for (const elem2 of sorted) {
1790
+ if (pos < elem2.start) {
1791
+ elems.push(makeTextElem(elem2.start));
1792
+ }
1793
+ elems.push(elem2);
1794
+ pos = elem2.end;
1795
+ }
1796
+ if (pos < end) {
1797
+ elems.push(makeTextElem(end));
1798
+ }
1799
+ return elems;
1800
+ function makeTextElem(end2) {
1801
+ return { kind: "text", start: pos, end: end2, srcModule: ast.srcModule };
1802
+ }
1803
+ }
1804
+ const word = kind("word");
1805
+ kind("keyword");
1806
+ const qualified_ident = withSepPlus("::", or(word, "package", "super"));
1807
+ const number = kind("number");
1808
+ function makeStatement(segments, finalSegment) {
1809
+ return { kind: "import-statement", segments, finalSegment };
1810
+ }
1811
+ function makeSegment(name2) {
1812
+ return { kind: "import-segment", name: name2 };
1813
+ }
1814
+ function makeCollection(subtrees) {
1815
+ return {
1816
+ kind: "import-collection",
1817
+ subtrees
1818
+ };
1819
+ }
1820
+ function makeItem(name2, as) {
1821
+ return { kind: "import-item", name: name2, as };
1822
+ }
1823
+ function prependSegments(segments, statement2) {
1824
+ statement2.segments = segments.concat(statement2.segments);
1825
+ return statement2;
1826
+ }
1827
+ let import_collection = null;
1828
+ const import_path_or_item = seq(
1829
+ word,
1830
+ or(
1831
+ preceded(
1832
+ "::",
1833
+ req(
1834
+ or(
1835
+ fn(() => import_collection),
1836
+ fn(() => import_path_or_item)
1837
+ ),
1838
+ "invalid import, expected '{' or name"
1839
+ )
1840
+ ),
1841
+ preceded("as", req(word, "invalid alias, expected name")).map(
1842
+ (v) => makeItem("", v)
1843
+ ),
1844
+ yes().map(() => makeItem(""))
1845
+ // Optional
1846
+ )
1847
+ ).map(([name2, next]) => {
1848
+ if (next.kind === "import-collection") {
1849
+ return makeStatement([makeSegment(name2)], next);
1850
+ } else if (next.kind === "import-statement") {
1851
+ return prependSegments([makeSegment(name2)], next);
1852
+ } else if (next.kind === "import-item") {
1853
+ next.name = name2;
1854
+ return makeStatement([], next);
1855
+ } else {
1856
+ assertUnreachable(next);
1857
+ }
1858
+ });
1859
+ import_collection = delimited(
1860
+ "{",
1861
+ withSepPlus(",", () => import_path_or_item).map(makeCollection),
1862
+ req("}", "invalid import collection, expected }")
1863
+ );
1864
+ const import_relative = or(
1865
+ terminated("package", req("::", "invalid import, expected '::'")).map((v) => [
1866
+ makeSegment(v)
1867
+ ]),
1868
+ repeatPlus(
1869
+ terminated("super", req("::", "invalid import, expected '::'")).map(
1870
+ makeSegment
1871
+ )
1872
+ )
1873
+ );
1874
+ const import_statement = span(
1875
+ delimited(
1876
+ "import",
1877
+ seqObj({
1878
+ relative: opt(import_relative),
1879
+ collection_or_statement: req(
1880
+ or(import_collection, import_path_or_item),
1881
+ "invalid import, expected { or name"
1882
+ )
1883
+ }).map(({ relative, collection_or_statement }) => {
1884
+ if (collection_or_statement.kind === "import-statement") {
1885
+ return prependSegments(relative ?? [], collection_or_statement);
1886
+ } else {
1887
+ return makeStatement(relative ?? [], collection_or_statement);
1888
+ }
1889
+ }),
1890
+ req(";", "invalid import, expected ';'")
1891
+ )
1892
+ ).map(
1893
+ (v) => ({
1894
+ kind: "import",
1895
+ imports: v.value,
1896
+ start: v.span[0],
1897
+ end: v.span[1]
1898
+ })
1899
+ );
1900
+ const weslImports = tagScope(
1901
+ repeat(import_statement).ptag("owo").collect(importElem)
1902
+ );
1903
+ const keywords = `alias break case const const_assert continue continuing
1904
+ default diagnostic discard else enable false fn for if
1905
+ let loop override requires return struct switch true var while`.split(/\s+/);
1906
+ const reservedWords = `NULL Self abstract active alignas alignof as asm asm_fragment async attribute auto await
1907
+ become binding_array cast catch class co_await co_return co_yield coherent column_major
1908
+ common compile compile_fragment concept const_cast consteval constexpr constinit crate
1909
+ debugger decltype delete demote demote_to_helper do dynamic_cast
1910
+ enum explicit export extends extern external fallthrough filter final finally friend from fxgroup
1911
+ get goto groupshared highp impl implements import inline instanceof interface layout lowp
1912
+ macro macro_rules match mediump meta mod module move mut mutable
1913
+ namespace new nil noexcept noinline nointerpolation non_coherent noncoherent noperspective null nullptr
1914
+ of operator package packoffset partition pass patch pixelfragment precise precision premerge
1915
+ priv protected pub public readonly ref regardless register reinterpret_cast require resource restrict
1916
+ self set shared sizeof smooth snorm static static_assert static_cast std subroutine super
1917
+ target template this thread_local throw trait try type typedef typeid typename typeof
1918
+ union unless unorm unsafe unsized use using varying virtual volatile wgsl where with writeonly yield`.split(
1919
+ /\s+/
1920
+ );
1921
+ const blankspaces = /[ \t\n\v\f\r\u{0085}\u{200E}\u{200F}\u{2028}\u{2029}]+/u;
1922
+ const symbolSet = "& && -> @ / ! [ ] { } :: : , == = != >>= >> >= > <<= << <= < % - -- . + ++ | || ( ) ; * ~ ^ // /* */ += -= *= /= %= &= |= ^= _";
1923
+ const ident = /(?:(?:[_\p{XID_Start}][\p{XID_Continue}]+)|(?:[\p{XID_Start}]))/u;
1924
+ const keywordOrReserved = new Set(keywords.concat(reservedWords));
1925
+ const digits = new RegExp(
1926
+ // decimal_float_literal
1927
+ /(?:0[fh])|(?:[1-9][0-9]*[fh])/.source + /|(?:[0-9]*\.[0-9]+(?:[eE][+-]?[0-9]+)?[fh]?)/.source + /|(?:[0-9]+\.[0-9]*(?:[eE][+-]?[0-9]+)?[fh]?)/.source + /|(?:[0-9]+[eE][+-]?[0-9]+[fh]?)/.source + // hex_float_literal
1928
+ /|(?:0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+(?:[pP][+-]?[0-9]+[fh]?)?)/.source + /|(?:0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*(?:[pP][+-]?[0-9]+[fh]?)?)/.source + /|(?:0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+[fh]?)/.source + // hex_int_literal
1929
+ /|(?:0[xX][0-9a-fA-F]+[iu]?)/.source + // decimal_int_literal
1930
+ /|(?:0[iu]?)|(?:[1-9][0-9]*[iu]?)/.source
1931
+ );
1932
+ const commentStart = /\/\/|\/\*/;
1933
+ const weslMatcher = new RegexMatchers({
1934
+ word: ident,
1935
+ number: digits,
1936
+ blankspaces,
1937
+ commentStart,
1938
+ symbol: matchOneOf(symbolSet),
1939
+ invalid: /[^]/
1940
+ });
1941
+ function weslExtension(combinator) {
1942
+ return combinator;
1943
+ }
1944
+ class WeslStream {
1945
+ constructor(src) {
1946
+ this.src = src;
1947
+ this.eolPattern = /[\n\v\f\u{0085}\u{2028}\u{2029}]|\r\n?/gu;
1948
+ this.blockCommentPattern = /\/\*|\*\//g;
1949
+ this.stream = new CachingStream(new MatchersStream(src, weslMatcher));
1950
+ }
1951
+ checkpoint() {
1952
+ return this.stream.checkpoint();
1953
+ }
1954
+ reset(position) {
1955
+ this.stream.reset(position);
1956
+ }
1957
+ nextToken() {
1958
+ while (true) {
1959
+ const token2 = this.stream.nextToken();
1960
+ if (token2 === null) return null;
1961
+ const kind2 = token2.kind;
1962
+ if (kind2 === "blankspaces") {
1963
+ continue;
1964
+ } else if (kind2 === "commentStart") {
1965
+ if (token2.text === "//") {
1966
+ this.stream.reset(this.skipToEol(token2.span[1]));
1967
+ } else {
1968
+ this.stream.reset(this.skipBlockComment(token2.span[1]));
1969
+ }
1970
+ } else if (kind2 === "word") {
1971
+ let returnToken = token2;
1972
+ if (keywordOrReserved.has(token2.text)) {
1973
+ returnToken.kind = "keyword";
1974
+ }
1975
+ return returnToken;
1976
+ } else if (kind2 === "invalid") {
1977
+ throw new ParseError(
1978
+ "Invalid token " + token2.text,
1979
+ this.stream.checkpoint()
1980
+ );
1981
+ } else {
1982
+ return token2;
1983
+ }
1984
+ }
1985
+ }
1986
+ skipToEol(position) {
1987
+ this.eolPattern.lastIndex = position;
1988
+ const result = this.eolPattern.exec(this.src);
1989
+ if (result === null) {
1990
+ return this.src.length;
1991
+ } else {
1992
+ return this.eolPattern.lastIndex;
1993
+ }
1994
+ }
1995
+ skipBlockComment(position) {
1996
+ while (true) {
1997
+ this.blockCommentPattern.lastIndex = position;
1998
+ const result = this.blockCommentPattern.exec(this.src);
1999
+ if (result === null) {
2000
+ throw new ParseError("Unclosed block comment!", position);
2001
+ } else if (result[0] === "*/") {
2002
+ return this.blockCommentPattern.lastIndex;
2003
+ } else if (result[0] === "/*") {
2004
+ position = this.skipBlockComment(this.blockCommentPattern.lastIndex);
2005
+ } else {
2006
+ throw new Error("Unreachable, invalid block comment pattern");
2007
+ }
2008
+ }
2009
+ }
2010
+ /**
2011
+ * Only matches the `<` token if it is a template
2012
+ * Precondition: An ident was parsed right before this.
2013
+ * Runs the [template list discovery algorithm](https://www.w3.org/TR/WGSL/#template-list-discovery).
2014
+ */
2015
+ nextTemplateStartToken() {
2016
+ const startPosition = this.stream.checkpoint();
2017
+ const token2 = this.nextToken();
2018
+ this.stream.reset(startPosition);
2019
+ if (token2 === null) return null;
2020
+ if (token2.kind !== "symbol") {
2021
+ return null;
2022
+ }
2023
+ if (token2.text === "<") {
2024
+ if (this.isTemplateStart(token2.span[1])) {
2025
+ this.stream.reset(token2.span[1]);
2026
+ return token2;
2027
+ } else {
2028
+ this.stream.reset(startPosition);
2029
+ return null;
2030
+ }
2031
+ } else {
2032
+ return null;
2033
+ }
2034
+ }
2035
+ nextTemplateEndToken() {
2036
+ const startPosition = this.stream.checkpoint();
2037
+ const token2 = this.nextToken();
2038
+ this.stream.reset(startPosition);
2039
+ if (token2 === null) return null;
2040
+ if (token2.kind === "symbol" && token2.text[0] === ">") {
2041
+ const tokenPosition = token2.span[0];
2042
+ this.stream.reset(tokenPosition + 1);
2043
+ return {
2044
+ kind: "symbol",
2045
+ span: [tokenPosition, tokenPosition + 1],
2046
+ text: ">"
2047
+ };
2048
+ } else {
2049
+ return null;
2050
+ }
2051
+ }
2052
+ isTemplateStart(afterToken) {
2053
+ this.stream.reset(afterToken);
2054
+ let pendingCounter = 1;
2055
+ while (true) {
2056
+ const nextToken = this.stream.nextToken();
2057
+ if (nextToken === null) return false;
2058
+ if (nextToken.kind !== "symbol") continue;
2059
+ if (nextToken.text === "<") {
2060
+ pendingCounter += 1;
2061
+ } else if (nextToken.text[0] === ">") {
2062
+ if (nextToken.text === ">" || nextToken.text == ">=") {
2063
+ pendingCounter -= 1;
2064
+ } else if (nextToken.text === ">>=" || nextToken.text === ">>") {
2065
+ pendingCounter -= 2;
2066
+ } else {
2067
+ throw new Error(
2068
+ "This case should never be reached, looks like we forgot one of the tokens that start with >"
2069
+ );
2070
+ }
2071
+ if (pendingCounter <= 0) {
2072
+ return true;
2073
+ }
2074
+ } else if (nextToken.text === "(") {
2075
+ this.skipBracketsTo(")");
2076
+ } else if (nextToken.text === "[") {
2077
+ this.skipBracketsTo("]");
2078
+ } else if (nextToken.text === "==" || nextToken.text === "!=" || nextToken.text === ";" || nextToken.text === "{" || nextToken.text === ":" || nextToken.text === "&&" || nextToken.text === "||") {
2079
+ return false;
2080
+ }
2081
+ }
2082
+ }
2083
+ /**
2084
+ * Call this after consuming an opening bracket.
2085
+ * Skips until a closing bracket. This also consumes the closing bracket.
2086
+ */
2087
+ skipBracketsTo(closingBracket) {
2088
+ while (true) {
2089
+ const nextToken = this.stream.nextToken();
2090
+ if (nextToken === null)
2091
+ throw new ParseError("Unclosed bracket!", this.stream.checkpoint());
2092
+ if (nextToken.kind !== "symbol") continue;
2093
+ if (nextToken.text === "(") {
2094
+ this.skipBracketsTo(")");
2095
+ } else if (nextToken.text === "[") {
2096
+ this.skipBracketsTo("]");
2097
+ } else if (nextToken.text === closingBracket) {
2098
+ return;
2099
+ }
2100
+ }
2101
+ }
2102
+ }
2103
+ const templateOpen = withStreamAction((stream) => {
2104
+ return stream.nextTemplateStartToken();
2105
+ });
2106
+ const templateClose = withStreamAction((stream) => {
2107
+ return stream.nextTemplateEndToken();
2108
+ });
2109
+ const opt_template_list = opt(
2110
+ seq(
2111
+ templateOpen,
2112
+ withSepPlus(",", () => template_parameter),
2113
+ req(templateClose, "invalid template, expected '>'")
2114
+ )
2115
+ );
2116
+ const template_elaborated_ident = seq(
2117
+ qualified_ident.collect(refIdent),
2118
+ opt_template_list
2119
+ );
2120
+ const literal = or("true", "false", number);
2121
+ const paren_expression = seq(
2122
+ "(",
2123
+ () => expression,
2124
+ req(")", "invalid expression, expected ')'")
2125
+ );
2126
+ const primary_expression = or(
2127
+ literal,
2128
+ paren_expression,
2129
+ seq(template_elaborated_ident, opt(fn(() => argument_expression_list)))
2130
+ );
2131
+ const component_or_swizzle = repeatPlus(
2132
+ or(
2133
+ preceded(".", word),
2134
+ collectArray(
2135
+ delimited(
2136
+ "[",
2137
+ () => expression,
2138
+ req("]", "invalid expression, expected ']'")
2139
+ )
2140
+ )
2141
+ )
2142
+ );
2143
+ const simple_component_reference = tagScope(
2144
+ seq(
2145
+ qualified_ident.collect(refIdent, "structRef"),
2146
+ seq(".", word.collect(nameCollect, "component")),
2147
+ opt(component_or_swizzle.collect(stuffCollect, "extra_components"))
2148
+ ).collect(memberRefCollect)
2149
+ );
2150
+ const unary_expression = or(
2151
+ seq(tokenOf("symbol", ["!", "&", "*", "-", "~"]), () => unary_expression),
2152
+ or(
2153
+ simple_component_reference,
2154
+ seq(primary_expression, opt(component_or_swizzle))
2155
+ )
2156
+ );
2157
+ const bitwise_post_unary = or(
2158
+ // LATER I can skip template list discovery in these cases, because a&b<c cannot be a comparison. Must be a template
2159
+ repeatPlus(seq("&", unary_expression)),
2160
+ repeatPlus(seq("^", unary_expression)),
2161
+ repeatPlus(seq("|", unary_expression))
2162
+ );
2163
+ const multiplicative_operator = or("%", "*", "/");
2164
+ const additive_operator = or("+", "-");
2165
+ const shift_post_unary = (inTemplate) => {
2166
+ const shift_left = seq("<<", unary_expression);
2167
+ const shift_right = seq(">>", unary_expression);
2168
+ const mul_add = seq(
2169
+ repeat(seq(multiplicative_operator, unary_expression)),
2170
+ repeat(
2171
+ seq(
2172
+ additive_operator,
2173
+ unary_expression,
2174
+ repeat(seq(multiplicative_operator, unary_expression))
2175
+ )
2176
+ )
2177
+ );
2178
+ return inTemplate ? or(shift_left, mul_add) : or(shift_left, shift_right, mul_add);
2179
+ };
2180
+ const relational_post_unary = (inTemplate) => {
2181
+ return seq(
2182
+ shift_post_unary(inTemplate),
2183
+ opt(
2184
+ seq(
2185
+ // '<' is unambiguous, since templates were already caught by the primary expression inside of the previous unary_expression!
2186
+ inTemplate ? tokenOf("symbol", ["<", "<=", "!=", "=="]) : tokenOf("symbol", [">", ">=", "<", "<=", "!=", "=="]),
2187
+ // LATER I can skip template list discovery in this cases, because a>=b<c cannot be a comparison. Must be a template
2188
+ unary_expression,
2189
+ shift_post_unary(inTemplate)
2190
+ )
2191
+ )
2192
+ );
2193
+ };
2194
+ const expressionParser = (inTemplate) => {
2195
+ return seq(
2196
+ unary_expression,
2197
+ or(
2198
+ bitwise_post_unary,
2199
+ seq(
2200
+ relational_post_unary(inTemplate),
2201
+ inTemplate ? (
2202
+ // Don't accept || or && in template mode
2203
+ yes()
2204
+ ) : or(
2205
+ repeatPlus(
2206
+ seq("||", seq(unary_expression, relational_post_unary(false)))
2207
+ ),
2208
+ repeatPlus(
2209
+ seq("&&", seq(unary_expression, relational_post_unary(false)))
2210
+ ),
2211
+ yes().map(() => [])
2212
+ )
2213
+ )
2214
+ )
2215
+ );
2216
+ };
2217
+ let maybe_template = false;
2218
+ const expression = expressionParser(maybe_template);
2219
+ let is_template = true;
2220
+ const template_arg_expression = expressionParser(is_template);
2221
+ const std_type_specifier = seq(
2222
+ qualified_ident.collect(refIdent, "typeRefName"),
2223
+ () => opt_template_list
2224
+ ).collect(typeRefCollect);
2225
+ const type_specifier = tagScope(
2226
+ std_type_specifier
2227
+ ).ctag("typeRefElem");
2228
+ const template_parameter = or(
2229
+ // LATER Remove this, it's wrong. This should instead be done by inspecting the syntax tree.
2230
+ type_specifier.ctag("templateParam"),
2231
+ template_arg_expression.collect(expressionCollect, "templateParam")
2232
+ );
2233
+ const argument_expression_list = seq(
2234
+ "(",
2235
+ withSep(",", expression),
2236
+ req(")", "invalid fn arguments, expected ')'")
2237
+ );
2238
+ const name = tokenKind("word").map(makeName);
2239
+ const diagnostic_rule_name = seq(
2240
+ name,
2241
+ opt(preceded(".", req(name, "invalid diagnostic rule name, expected name")))
2242
+ );
2243
+ const diagnostic_control = delimited(
2244
+ "(",
2245
+ req(
2246
+ separated_pair(name, ",", diagnostic_rule_name),
2247
+ "invalid diagnostic control, expected rule name"
2248
+ ),
2249
+ seq(opt(","), req(")", "invalid diagnostic control, expected ')'"))
2250
+ );
2251
+ const name_list = withSep(",", name, { requireOne: true });
2252
+ const special_attribute = tagScope(
2253
+ preceded(
2254
+ "@",
2255
+ or(
2256
+ // These attributes have no arguments
2257
+ or("compute", "const", "fragment", "invariant", "must_use", "vertex").map((name2) => makeStandardAttribute([name2, []])),
2258
+ // These attributes have arguments, but the argument doesn't have any identifiers
2259
+ preceded("interpolate", req(delimited("(", name_list, ")"), "invalid @interpolate, expected '('")).map(makeInterpolateAttribute),
2260
+ preceded("builtin", req(delimited("(", name, ")"), "invalid @builtin, expected '('")).map(makeBuiltinAttribute),
2261
+ preceded("diagnostic", req(diagnostic_control, "invalid @diagnostic, expected '('")).map(makeDiagnosticAttribute)
2262
+ ).ptag("attr_variant")
2263
+ ).collect(specialAttribute)
2264
+ );
2265
+ const if_attribute = tagScope(
2266
+ preceded(
2267
+ seq("@", weslExtension("if")),
2268
+ span(
2269
+ delimited(
2270
+ "(",
2271
+ fn(() => attribute_if_expression),
2272
+ seq(opt(","), ")")
2273
+ )
2274
+ ).map(makeTranslateTimeExpressionElem)
2275
+ ).map(makeIfAttribute).ptag("attr_variant").collect(specialAttribute)
2276
+ );
2277
+ const normal_attribute = tagScope(
2278
+ preceded(
2279
+ "@",
2280
+ or(
2281
+ // These are normal attributes, with required arguments
2282
+ seq(
2283
+ or(
2284
+ "workgroup_size",
2285
+ "align",
2286
+ "binding",
2287
+ "blend_src",
2288
+ "group",
2289
+ "id",
2290
+ "location",
2291
+ "size"
2292
+ ).ptag("name"),
2293
+ req(() => attribute_argument_list, "invalid attribute, expected '('")
2294
+ ),
2295
+ // Everything else is also a normal attribute, optional expression list
2296
+ seq(
2297
+ // we don't want this to interfere with if_attribute,
2298
+ // but not("if") isn't necessary for now, since 'if' is a keyword, not a word
2299
+ word.ptag("name"),
2300
+ opt(() => attribute_argument_list)
2301
+ )
2302
+ )
2303
+ ).collect(collectAttribute)
2304
+ );
2305
+ const attribute_argument_list = delimited(
2306
+ "(",
2307
+ withSep(
2308
+ ",",
2309
+ span(fn(() => expression)).collect(expressionCollect, "attrParam")
2310
+ // LATER These unknown expressions have decls inside of them, that's why they're tough to replace!
2311
+ ),
2312
+ req(")", "invalid attribute arguments, expected ')'")
2313
+ );
2314
+ const attribute_no_if = or(
2315
+ special_attribute,
2316
+ normal_attribute
2317
+ ).ctag("attribute");
2318
+ const attribute_incl_if = or(
2319
+ if_attribute,
2320
+ special_attribute,
2321
+ normal_attribute
2322
+ ).ctag("attribute");
2323
+ const opt_attributes = repeat(attribute_incl_if);
2324
+ const opt_attributes_no_if = repeat(attribute_no_if);
2325
+ const globalTypeNameDecl = req(
2326
+ word.collect(globalDeclCollect, "type_name"),
2327
+ "invalid type name, expected a name"
2328
+ );
2329
+ const fnNameDecl = req(
2330
+ word.collect(globalDeclCollect, "fn_name"),
2331
+ "missing fn name"
2332
+ );
2333
+ const optionally_typed_ident = tagScope(
2334
+ seq(
2335
+ word.collect(declCollect, "decl_elem"),
2336
+ opt(seq(":", type_specifier))
2337
+ ).collect(typedDecl)
2338
+ ).ctag("var_name");
2339
+ const req_optionally_typed_ident = req(optionally_typed_ident, "invalid ident");
2340
+ const global_ident = tagScope(
2341
+ req(
2342
+ seq(
2343
+ word.collect(globalDeclCollect, "decl_elem"),
2344
+ opt(seq(":", type_specifier))
2345
+ ).collect(typedDecl),
2346
+ "expected identifier"
2347
+ )
2348
+ ).ctag("var_name");
2349
+ const struct_member = tagScope(
2350
+ seq(
2351
+ opt_attributes,
2352
+ word.collect(nameCollect, "nameElem"),
2353
+ req(":", "invalid struct member, expected ':'"),
2354
+ req(type_specifier, "invalid struct member, expected type specifier")
2355
+ ).collect(collectStructMember)
2356
+ ).ctag("members");
2357
+ const struct_decl = seq(
2358
+ weslExtension(opt_attributes).collect((cc) => cc.tags.attribute, "attributes"),
2359
+ "struct",
2360
+ req(globalTypeNameDecl, "invalid struct, expected name"),
2361
+ seq(
2362
+ req("{", "invalid struct, expected '{'"),
2363
+ withSepPlus(",", struct_member),
2364
+ req("}", "invalid struct, expected '}'")
2365
+ ).collect(scopeCollect, "struct_scope")
2366
+ ).collect(collectStruct);
2367
+ const fn_call = seq(
2368
+ qualified_ident.collect(refIdent),
2369
+ () => opt_template_list,
2370
+ argument_expression_list
2371
+ );
2372
+ const fnParam = tagScope(
2373
+ seq(
2374
+ opt_attributes.collect((cc) => cc.tags.attribute, "attributes"),
2375
+ word.collect(declCollect, "decl_elem"),
2376
+ opt(seq(":", req(type_specifier, "invalid fn parameter, expected type specifier"))).collect(typedDecl, "param_name")
2377
+ ).collect(collectFnParam)
2378
+ ).ctag("fn_param");
2379
+ const fnParamList = seq("(", withSep(",", fnParam), ")");
2380
+ const local_variable_decl = seq(
2381
+ "var",
2382
+ () => opt_template_list,
2383
+ req_optionally_typed_ident,
2384
+ opt(seq("=", () => expression))
2385
+ // no decl_scope, but I think that's ok
2386
+ ).collect(collectVarLike("var"));
2387
+ const global_variable_decl = seq(
2388
+ "var",
2389
+ () => opt_template_list,
2390
+ global_ident,
2391
+ // TODO shouldn't decl_scope include the ident type?
2392
+ opt(seq("=", () => expression.collect(scopeCollect, "decl_scope")))
2393
+ );
2394
+ const attribute_if_primary_expression = or(
2395
+ tokenOf("keyword", ["true", "false"]).map(makeLiteral),
2396
+ delimited(
2397
+ token("symbol", "("),
2398
+ fn(() => attribute_if_expression),
2399
+ token("symbol", ")")
2400
+ ).map(makeParenthesizedExpression),
2401
+ tokenKind("word").map(makeTranslateTimeFeature)
2402
+ );
2403
+ const attribute_if_unary_expression = or(
2404
+ seq(
2405
+ token("symbol", "!").map(makeUnaryOperator),
2406
+ fn(() => attribute_if_unary_expression)
2407
+ ).map(makeUnaryExpression),
2408
+ attribute_if_primary_expression
2409
+ );
2410
+ const attribute_if_expression = weslExtension(
2411
+ seq(
2412
+ attribute_if_unary_expression,
2413
+ or(
2414
+ repeatPlus(
2415
+ seq(
2416
+ token("symbol", "||").map(makeBinaryOperator),
2417
+ req(
2418
+ attribute_if_unary_expression,
2419
+ "invalid expression, expected expression"
2420
+ )
2421
+ )
2422
+ ),
2423
+ repeatPlus(
2424
+ seq(
2425
+ token("symbol", "&&").map(makeBinaryOperator),
2426
+ req(
2427
+ attribute_if_unary_expression,
2428
+ "invalid expression, expected expression"
2429
+ )
2430
+ )
2431
+ ),
2432
+ yes().map(() => [])
2433
+ )
2434
+ ).map(makeRepeatingBinaryExpression)
2435
+ );
2436
+ const unscoped_compound_statement = seq(
2437
+ opt_attributes,
2438
+ text("{"),
2439
+ repeat(() => statement),
2440
+ req("}", "invalid block, expected }")
2441
+ ).collect(statementCollect);
2442
+ const compound_statement = tagScope(
2443
+ seq(
2444
+ opt_attributes,
2445
+ seq(
2446
+ text("{"),
2447
+ repeat(() => statement),
2448
+ req("}", "invalid block, expected '}'")
2449
+ ).collect(scopeCollect)
2450
+ ).collect(statementCollect)
2451
+ );
2452
+ const for_init = seq(
2453
+ opt_attributes,
2454
+ or(
2455
+ fn_call,
2456
+ () => variable_or_value_statement,
2457
+ () => variable_updating_statement
2458
+ )
2459
+ );
2460
+ const for_update = seq(
2461
+ opt_attributes,
2462
+ or(fn_call, () => variable_updating_statement)
2463
+ );
2464
+ const for_statement = seq(
2465
+ // LATER consider allowing @if on for_init, expression and for_update
2466
+ "for",
2467
+ seq(
2468
+ req("(", "invalid for loop, expected '('"),
2469
+ opt(for_init),
2470
+ req(";", "invalid for loop, expected ';'"),
2471
+ opt(expression),
2472
+ req(";", "invalid for loop, expected ';'"),
2473
+ opt(for_update),
2474
+ req(")", "invalid for loop, expected ')'"),
2475
+ unscoped_compound_statement
2476
+ ).collect(scopeCollect)
2477
+ );
2478
+ const if_statement = seq(
2479
+ "if",
2480
+ req(seq(expression, compound_statement), "invalid if statement"),
2481
+ repeat(
2482
+ seq(
2483
+ "else",
2484
+ "if",
2485
+ req(seq(expression, compound_statement), "invalid else if branch")
2486
+ )
2487
+ ),
2488
+ opt(
2489
+ seq("else", req(compound_statement, "invalid else branch, expected '{'"))
2490
+ )
2491
+ );
2492
+ const loop_statement = seq(
2493
+ "loop",
2494
+ opt_attributes_no_if,
2495
+ req(
2496
+ seq(
2497
+ "{",
2498
+ repeat(() => statement),
2499
+ opt(
2500
+ tagScope(
2501
+ seq(
2502
+ opt_attributes,
2503
+ "continuing",
2504
+ opt_attributes_no_if,
2505
+ "{",
2506
+ repeat(() => statement),
2507
+ tagScope(
2508
+ opt(
2509
+ seq(
2510
+ opt_attributes,
2511
+ seq("break", "if", expression, ";")
2512
+ ).collect(statementCollect)
2513
+ )
2514
+ ),
2515
+ "}"
2516
+ ).collect(statementCollect).collect(scopeCollect)
2517
+ )
2518
+ ),
2519
+ "}"
2520
+ ),
2521
+ "invalid loop statement"
2522
+ )
2523
+ ).collect(scopeCollect);
2524
+ const case_selector = or("default", expression);
2525
+ const switch_clause = tagScope(
2526
+ seq(
2527
+ opt_attributes,
2528
+ or(
2529
+ seq(
2530
+ "case",
2531
+ withSep(",", case_selector, { requireOne: true }),
2532
+ opt(":"),
2533
+ compound_statement
2534
+ ),
2535
+ seq("default", opt(":"), compound_statement)
2536
+ ).collect(switchClauseCollect)
2537
+ )
2538
+ );
2539
+ const switch_body = seq(opt_attributes, "{", repeatPlus(switch_clause), "}");
2540
+ const switch_statement = seq("switch", expression, switch_body);
2541
+ const while_statement = seq("while", expression, compound_statement);
2542
+ const regular_statement = or(
2543
+ for_statement,
2544
+ if_statement,
2545
+ loop_statement,
2546
+ switch_statement,
2547
+ while_statement,
2548
+ seq("break", ";"),
2549
+ // ambiguous with break if
2550
+ seq("continue", req(";", "invalid statement, expected ';'")),
2551
+ seq(";"),
2552
+ // LATER this one cannot have attributes in front of it
2553
+ () => const_assert,
2554
+ seq("discard", req(";", "invalid statement, expected ';'")),
2555
+ seq("return", opt(expression), req(";", "invalid statement, expected ';'")),
2556
+ seq(fn_call, req(";", "invalid statement, expected ';'")),
2557
+ seq(
2558
+ () => variable_or_value_statement,
2559
+ req(";", "invalid statement, expected ';'")
2560
+ ),
2561
+ seq(
2562
+ () => variable_updating_statement,
2563
+ req(";", "invalid statement, expected ';'")
2564
+ )
2565
+ );
2566
+ const conditional_statement = tagScope(
2567
+ seq(
2568
+ opt_attributes,
2569
+ regular_statement
2570
+ ).collect(statementCollect).collect(partialScopeCollect)
2571
+ );
2572
+ const unconditional_statement = tagScope(
2573
+ seq(
2574
+ opt_attributes_no_if,
2575
+ regular_statement
2576
+ )
2577
+ );
2578
+ const statement = or(
2579
+ compound_statement,
2580
+ unconditional_statement,
2581
+ conditional_statement
2582
+ );
2583
+ const lhs_expression = or(
2584
+ simple_component_reference,
2585
+ seq(
2586
+ qualified_ident.collect(refIdent),
2587
+ opt(component_or_swizzle)
2588
+ ),
2589
+ seq(
2590
+ "(",
2591
+ () => lhs_expression,
2592
+ ")",
2593
+ opt(component_or_swizzle)
2594
+ // LATER this doesn't find member references.
2595
+ ),
2596
+ seq("&", () => lhs_expression),
2597
+ seq("*", () => lhs_expression)
2598
+ );
2599
+ const variable_or_value_statement = tagScope(
2600
+ // LATER consider collecting these as var elems and scopes
2601
+ or(
2602
+ // Also covers the = expression case
2603
+ local_variable_decl,
2604
+ seq("const", req_optionally_typed_ident, req("=", "invalid const declaration, expected '='"), expression),
2605
+ seq(
2606
+ "let",
2607
+ req_optionally_typed_ident,
2608
+ req("=", "invalid let declaration, expected '='"),
2609
+ expression
2610
+ )
2611
+ )
2612
+ );
2613
+ const variable_updating_statement = or(
2614
+ seq(
2615
+ lhs_expression,
2616
+ or("=", "<<=", ">>=", "%=", "&=", "*=", "+=", "-=", "/=", "^=", "|="),
2617
+ expression
2618
+ ),
2619
+ seq(lhs_expression, or("++", "--")),
2620
+ seq("_", "=", expression)
2621
+ );
2622
+ const fn_decl = seq(
2623
+ tagScope(
2624
+ opt_attributes.collect((cc) => cc.tags.attribute || [])
2625
+ ).ctag("fn_attributes"),
2626
+ text("fn"),
2627
+ req(fnNameDecl, "invalid fn, expected function name"),
2628
+ seq(
2629
+ req(fnParamList, "invalid fn, expected function parameters").collect(scopeCollect, "header_scope"),
2630
+ opt(seq(
2631
+ "->",
2632
+ opt_attributes.collect((cc) => cc.tags.attribute, "return_attributes"),
2633
+ type_specifier.ctag("return_type").collect(scopeCollect, "return_scope")
2634
+ )),
2635
+ req(
2636
+ unscoped_compound_statement,
2637
+ "invalid fn, expected function body"
2638
+ ).ctag("body_statement").collect(scopeCollect, "body_scope")
2639
+ )
2640
+ ).collect(partialScopeCollect, "fn_partial_scope").collect(fnCollect);
2641
+ const global_value_decl = or(
2642
+ seq(
2643
+ opt_attributes,
2644
+ "override",
2645
+ global_ident,
2646
+ seq(opt(seq("=", expression.collect(scopeCollect, "decl_scope")))),
2647
+ // TODO partial scopes for decl_scopes?
2648
+ ";"
2649
+ ).collect(collectVarLike("override")),
2650
+ seq(
2651
+ opt_attributes,
2652
+ "const",
2653
+ global_ident,
2654
+ "=",
2655
+ seq(expression).collect(scopeCollect, "decl_scope"),
2656
+ ";"
2657
+ ).collect(collectVarLike("const"))
2658
+ );
2659
+ const global_alias = seq(
2660
+ weslExtension(opt_attributes).collect((cc) => cc.tags.attribute, "attributes"),
2661
+ "alias",
2662
+ req(word, "invalid alias, expected name").collect(globalDeclCollect, "alias_name"),
2663
+ req("=", "invalid alias, expected '='"),
2664
+ req(type_specifier, "invalid alias, expected type").collect(scopeCollect, "alias_scope"),
2665
+ req(";", "invalid alias, expected ';'")
2666
+ ).collect(aliasCollect);
2667
+ const const_assert = tagScope(
2668
+ seq(
2669
+ opt_attributes,
2670
+ "const_assert",
2671
+ req(expression, "invalid const_assert, expected expression"),
2672
+ req(";", "invalid statement, expected ';'")
2673
+ ).collect(assertCollect)
2674
+ ).ctag("const_assert");
2675
+ const global_directive = tagScope(
2676
+ seq(
2677
+ opt_attributes,
2678
+ terminated(
2679
+ or(
2680
+ preceded("diagnostic", diagnostic_control).map(makeDiagnosticDirective),
2681
+ preceded("enable", name_list).map(makeEnableDirective),
2682
+ preceded("requires", name_list).map(makeRequiresDirective)
2683
+ ).ptag("directive"),
2684
+ ";"
2685
+ )
2686
+ ).collect(directiveCollect)
2687
+ );
2688
+ const global_decl = tagScope(
2689
+ or(
2690
+ fn_decl,
2691
+ seq(
2692
+ opt_attributes,
2693
+ global_variable_decl,
2694
+ ";"
2695
+ ).collect(collectVarLike("gvar")),
2696
+ global_value_decl,
2697
+ ";",
2698
+ global_alias,
2699
+ const_assert.collect(globalAssertCollect),
2700
+ struct_decl
2701
+ )
2702
+ );
2703
+ const weslRoot = seq(
2704
+ weslExtension(weslImports),
2705
+ repeat(global_directive),
2706
+ repeat(global_decl),
2707
+ req(eof(), "invalid WESL, expected EOF")
2708
+ ).collect(collectModule, "collectModule");
2709
+ function makeDiagnosticDirective([severity, rule]) {
2710
+ return { kind: "diagnostic", severity, rule };
2711
+ }
2712
+ function makeEnableDirective(extensions) {
2713
+ return { kind: "enable", extensions };
2714
+ }
2715
+ function makeRequiresDirective(extensions) {
2716
+ return { kind: "requires", extensions };
2717
+ }
2718
+ function makeStandardAttribute([name2, params]) {
2719
+ return {
2720
+ kind: "@attribute",
2721
+ name: name2,
2722
+ params
2723
+ };
2724
+ }
2725
+ function makeInterpolateAttribute(params) {
2726
+ return {
2727
+ kind: "@interpolate",
2728
+ params
2729
+ };
2730
+ }
2731
+ function makeBuiltinAttribute(param) {
2732
+ return {
2733
+ kind: "@builtin",
2734
+ param
2735
+ };
2736
+ }
2737
+ function makeDiagnosticAttribute([severity, rule]) {
2738
+ return {
2739
+ kind: "@diagnostic",
2740
+ severity,
2741
+ rule
2742
+ };
2743
+ }
2744
+ function makeIfAttribute(param) {
2745
+ return {
2746
+ kind: "@if",
2747
+ param
2748
+ };
2749
+ }
2750
+ function makeTranslateTimeExpressionElem(args) {
2751
+ return {
2752
+ kind: "translate-time-expression",
2753
+ expression: args.value,
2754
+ span: args.span
2755
+ };
2756
+ }
2757
+ function makeName(token2) {
2758
+ return {
2759
+ kind: "name",
2760
+ name: token2.text,
2761
+ start: token2.span[0],
2762
+ end: token2.span[1]
2763
+ };
2764
+ }
2765
+ function makeLiteral(token2) {
2766
+ return {
2767
+ kind: "literal",
2768
+ value: token2.text,
2769
+ span: token2.span
2770
+ };
2771
+ }
2772
+ function makeTranslateTimeFeature(token2) {
2773
+ return {
2774
+ kind: "translate-time-feature",
2775
+ name: token2.text,
2776
+ span: token2.span
2777
+ };
2778
+ }
2779
+ function makeParenthesizedExpression(expression2) {
2780
+ return {
2781
+ kind: "parenthesized-expression",
2782
+ expression: expression2
2783
+ };
2784
+ }
2785
+ function makeUnaryOperator(token2) {
2786
+ return {
2787
+ value: token2.text,
2788
+ span: token2.span
2789
+ };
2790
+ }
2791
+ function makeBinaryOperator(token2) {
2792
+ return {
2793
+ value: token2.text,
2794
+ span: token2.span
2795
+ };
2796
+ }
2797
+ function makeUnaryExpression([operator, expression2]) {
2798
+ return {
2799
+ kind: "unary-expression",
2800
+ operator,
2801
+ expression: expression2
2802
+ };
2803
+ }
2804
+ function makeRepeatingBinaryExpression([start, repeating]) {
2805
+ let result = start;
2806
+ for (const [op, left] of repeating) {
2807
+ result = makeBinaryExpression([result, op, left]);
2808
+ }
2809
+ return result;
2810
+ }
2811
+ function makeBinaryExpression([left, operator, right]) {
2812
+ return {
2813
+ kind: "binary-expression",
2814
+ operator,
2815
+ left,
2816
+ right
2817
+ };
2818
+ }
2819
+ /*!
2820
+ Copyright (c) 2017-2021 [these people](https://github.com/Rich-Harris/vlq/graphs/contributors)
2821
+
2822
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
2823
+
2824
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
2825
+
2826
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2827
+ */
2828
+ let integer_to_char = {};
2829
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach(function(char, i) {
2830
+ integer_to_char[i] = char;
2831
+ });
2832
+ function encodeVlq(value) {
2833
+ if (typeof value === "number") {
2834
+ return encode_integer(value);
2835
+ }
2836
+ let result = "";
2837
+ for (let i = 0; i < value.length; i += 1) {
2838
+ result += encode_integer(value[i]);
2839
+ }
2840
+ return result;
2841
+ }
2842
+ function encode_integer(num) {
2843
+ let result = "";
2844
+ if (num < 0) {
2845
+ num = -num << 1 | 1;
2846
+ } else {
2847
+ num <<= 1;
2848
+ }
2849
+ do {
2850
+ let clamped = num & 31;
2851
+ num >>>= 5;
2852
+ if (num > 0) {
2853
+ clamped |= 32;
2854
+ }
2855
+ result += integer_to_char[clamped];
2856
+ } while (num > 0);
2857
+ return result;
2858
+ }
2859
+ function makeWeslDevice(device) {
2860
+ const errorScopeStack = [];
2861
+ device.injectError = (type, error) => {
2862
+ const errorScope = errorScopeStack.findLast((v) => v.filter === type);
2863
+ if (errorScope !== void 0) {
2864
+ errorScope.errors.push(error);
2865
+ } else {
2866
+ error.then((e) => {
2867
+ if (e !== null) {
2868
+ dispatchError(e);
2869
+ }
2870
+ });
2871
+ }
2872
+ };
2873
+ function dispatchError(e) {
2874
+ device.addEventListener(
2875
+ "uncapturederror",
2876
+ (ev) => {
2877
+ if (!ev.defaultPrevented) {
2878
+ if ("compilationInfo" in ev.error) {
2879
+ const error = ev.error;
2880
+ if (error.compilationInfo) {
2881
+ for (const message of error.compilationInfo.messages) {
2882
+ throwClickableError({
2883
+ url: message.module.url,
2884
+ text: message.module.text ?? null,
2885
+ lineNumber: message.lineNum,
2886
+ lineColumn: message.linePos,
2887
+ length: message.length,
2888
+ error: new Error(message.type + ": " + message.message)
2889
+ });
2890
+ }
2891
+ } else {
2892
+ console.error(ev.error.message);
2893
+ }
2894
+ } else {
2895
+ console.error(ev.error.message);
2896
+ }
2897
+ }
2898
+ },
2899
+ {
2900
+ // This event listener should only happen for this event!
2901
+ once: true
2902
+ }
2903
+ );
2904
+ device.dispatchEvent(
2905
+ new GPUUncapturedErrorEvent("uncapturederror", { error: e })
2906
+ );
2907
+ }
2908
+ device.pushErrorScope = /* @__PURE__ */ ((baseFn) => {
2909
+ return function(filter) {
2910
+ errorScopeStack.push({
2911
+ filter,
2912
+ errors: []
2913
+ });
2914
+ return baseFn.call(this, filter);
2915
+ };
2916
+ })(device.pushErrorScope);
2917
+ device.popErrorScope = /* @__PURE__ */ ((baseFn) => {
2918
+ return function() {
2919
+ const errorScope = errorScopeStack.pop();
2920
+ if (errorScope === void 0) {
2921
+ throw new DOMException(
2922
+ "popErrorScope called on empty error scope stack",
2923
+ "OperationError"
2924
+ );
2925
+ }
2926
+ errorScope.errors.push(baseFn.call(this));
2927
+ const errorPromise = Promise.all(errorScope.errors).then(
2928
+ (values) => values.find((v) => v !== null) ?? null
2929
+ );
2930
+ return errorPromise;
2931
+ };
2932
+ })(device.popErrorScope);
2933
+ return device;
2934
+ }
2935
+ function throwClickableError({
2936
+ url,
2937
+ text: text2,
2938
+ lineNumber,
2939
+ lineColumn,
2940
+ length,
2941
+ error
2942
+ }) {
2943
+ let mappings = encodeVlq([
2944
+ 0,
2945
+ 0,
2946
+ Math.max(0, lineNumber - 1),
2947
+ Math.max(0, lineColumn - 1)
2948
+ ]) + "," + // Sadly no browser makes use of this info to map the error properly
2949
+ encodeVlq([
2950
+ 18,
2951
+ // Arbitrary number that is high enough
2952
+ 0,
2953
+ Math.max(0, lineNumber - 1),
2954
+ Math.max(0, lineColumn - 1) + length
2955
+ ]);
2956
+ const sourceMap = {
2957
+ version: 3,
2958
+ file: null,
2959
+ sources: [url],
2960
+ sourcesContent: [text2 ?? null],
2961
+ names: [],
2962
+ mappings
2963
+ };
2964
+ let generatedCode = `throw new Error(${JSON.stringify(error.message + "")})`;
2965
+ generatedCode += "\n//# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
2966
+ generatedCode += "\n//# sourceURL=" + sourceMap.sources[0];
2967
+ let oldLimit = 0;
2968
+ if ("stackTraceLimit" in Error) {
2969
+ oldLimit = Error.stackTraceLimit;
2970
+ Error.stackTraceLimit = 1;
2971
+ }
2972
+ try {
2973
+ (0, eval)(generatedCode);
2974
+ } catch (e) {
2975
+ if ("stackTraceLimit" in Error) {
2976
+ Error.stackTraceLimit = oldLimit;
2977
+ }
2978
+ error.message = "";
2979
+ e.cause = error;
2980
+ throw e;
2981
+ }
2982
+ }
2983
+ class WeslParseError extends Error {
2984
+ constructor(opts) {
2985
+ const source = opts.src.src;
2986
+ const [lineNum, linePos] = offsetToLineNumber(opts.cause.position, source);
2987
+ let message = `${opts.src.debugFilePath}:${lineNum}:${linePos}`;
2988
+ message += ` error: ${opts.cause.message}
2989
+ `;
2990
+ message += errorHighlight(source, [
2991
+ opts.cause.position,
2992
+ opts.cause.position + 1
2993
+ ]).join("\n");
2994
+ super(message, {
2995
+ cause: opts.cause
2996
+ });
2997
+ this.position = opts.cause.position;
2998
+ this.src = opts.src;
2999
+ }
3000
+ }
3001
+ function parseSrcModule(srcModule, srcMap) {
3002
+ const stream = new WeslStream(srcModule.src);
3003
+ const appState = blankWeslParseState(srcModule);
3004
+ const init = { stream, appState };
3005
+ try {
3006
+ const parseResult = weslRoot.parse(init);
3007
+ if (parseResult === null) {
3008
+ throw new Error("parseWESL failed");
3009
+ }
3010
+ } catch (e) {
3011
+ if (e instanceof ParseError) {
3012
+ const [lineNumber, lineColumn] = offsetToLineNumber(
3013
+ e.position,
3014
+ srcModule.src
3015
+ );
3016
+ const error = new WeslParseError({ cause: e, src: srcModule });
3017
+ throwClickableError({
3018
+ url: srcModule.debugFilePath,
3019
+ text: srcModule.src,
3020
+ error,
3021
+ lineNumber,
3022
+ lineColumn,
3023
+ length: 1
3024
+ });
3025
+ } else {
3026
+ throw e;
3027
+ }
3028
+ }
3029
+ return appState.stable;
3030
+ }
3031
+ function parseWESL(src, srcMap) {
3032
+ const srcModule = {
3033
+ modulePath: "package::test",
3034
+ // TODO this ought not be used outside of tests
3035
+ debugFilePath: "./test.wesl",
3036
+ src
3037
+ };
3038
+ return parseSrcModule(srcModule);
3039
+ }
3040
+ function blankWeslParseState(srcModule) {
3041
+ const rootScope = emptyScope(null);
3042
+ const moduleElem = null;
3043
+ return {
3044
+ context: { scope: rootScope, openElems: [] },
3045
+ stable: { srcModule, imports: [], rootScope, moduleElem }
3046
+ };
3047
+ }
3048
+ function syntheticWeslParseState() {
3049
+ const srcModule = {
3050
+ modulePath: "package::test",
3051
+ debugFilePath: "./test.wesl",
3052
+ src: ""
3053
+ };
3054
+ return blankWeslParseState(srcModule);
3055
+ }
3056
+ function flatImports(ast) {
3057
+ if (ast._flatImports) return ast._flatImports;
3058
+ const flat = ast.imports.flatMap(flattenTreeImport);
3059
+ ast._flatImports = flat;
3060
+ return flat;
3061
+ }
3062
+ const stdFns = `bitcast all any select arrayLength
3063
+ abs acos acosh asin asinh atan atanh atan2 ceil clamp cos cosh
3064
+ countLeadingZeros countOneBits countTrailingZeros cross
3065
+ degrees determinant distance dot dot4U8Packed dot4I8Packed
3066
+ exp exp2 extractBits faceForward firstLeadingBit firstTrailingBit
3067
+ floor fma fract frexp insertBits inverseSqrt ldexp length log log2
3068
+ max min mix modf normalize pow quantizeToF16 radians reflect refract
3069
+ reverseBits round saturate sign sin sinh smoothstep sqrt step tan tanh
3070
+ transpose trunc
3071
+ dpdx dpdxCoarse dpdxFine dpdy dpdyCoarse dpdyFine fwidth
3072
+ fwidthCoarse fwidthFine
3073
+ textureDimensions textureGather textureGatherCompare textureLoad
3074
+ textureNumLayers textureNumLevels textureNumSamples
3075
+ textureSample textureSampleBias textureSampleCompare textureSampleCompareLevel
3076
+ textureSampleGrad textureSampleLevel textureSampleBaseClampToEdge
3077
+ textureStore
3078
+ atomicLoad atomicStore atomicAdd atomicSub atomicMax atomicMin
3079
+ atomicAnd atomicOr atomicXor atomicExchange atomicCompareExchangeWeak
3080
+ pack4x8snorm pack4x8unorm pack4xI8 pack4xU8 pack4xI8Clamp pack4xU8Clamp
3081
+ pack2x16snorm pack2x16unorm pack2x16float
3082
+ unpack4x8snorm unpack4x8unorm unpack4xI8 unpack4xU8
3083
+ unpack2x16snorm unpack2x16unorm unpack2x16float
3084
+ storageBarrier textureBarrier workgroupBarrier workgroupUniformLoad
3085
+ subgroupAdd subgroupAll subgroupAnd subgroupAny subgroupBallot
3086
+ subgroupBroadcast subgroupBroadcastFirst subgroupElect
3087
+ subgroupExclusiveAdd subgroupExclusiveMul subgroupInclusiveAdd
3088
+ subgroupInclusiveMul subgroupMax subgroupMin subgroupMul subgroupOr
3089
+ subgroupShuffle subgroupShuffleUp subgroupShuffleXor subgroupXor
3090
+ quadBroadcast quadSwapDiagonal quadSwapX quadSwapY`.split(/\s+/);
3091
+ const sampledTextureTypes = `
3092
+ texture_1d texture_2d texture_2d_array texture_3d
3093
+ texture_cube texture_cube_array
3094
+ `;
3095
+ const multisampledTextureTypes = `
3096
+ texture_multisampled_2d texture_depth_multisampled_2d
3097
+ `;
3098
+ const textureStorageTypes = `
3099
+ texture_storage_1d texture_storage_2d texture_storage_2d_array
3100
+ texture_storage_3d
3101
+ `;
3102
+ const stdTypes = `array atomic bool f16 f32 i32
3103
+ mat2x2 mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4
3104
+ mat2x2f mat2x3f mat2x4f mat3x2f mat3x3f mat3x4f
3105
+ mat4x2f mat4x3f mat4x4f
3106
+ mat2x2h mat2x3h mat2x4h mat3x2h mat3x3h mat3x4h
3107
+ mat4x2h mat4x3h mat4x4h
3108
+ u32 vec2 vec3 vec4 ptr
3109
+ vec2i vec3i vec4i vec2u vec3u vec4u
3110
+ vec2f vec3f vec4f vec2h vec3h vec4h
3111
+ ${sampledTextureTypes}
3112
+ ${multisampledTextureTypes}
3113
+ texture_external
3114
+ ${textureStorageTypes}
3115
+ texture_depth_2d texture_depth_2d_array texture_depth_cube
3116
+ texture_depth_cube_array
3117
+ sampler sampler_comparison
3118
+ rgba8unorm rgba8snorm rgba8uint rgba8sint
3119
+ rgba16uint rgba16sint rgba16float
3120
+ r32uint r32sint r32float rg32uint rg32sint rg32float
3121
+ rgba32uint rgba32sint rgba32float
3122
+ bgra8unorm`.split(/\s+/);
3123
+ const stdEnumerants = `read write read_write
3124
+ function private workgroup uniform storage
3125
+ rgba8unorm rgba8snorm rgba8uint rgba8sint
3126
+ rgba16uint rgba16sint rgba16float
3127
+ r32uint r32sint r32float rg32uint rg32sint rg32float
3128
+ rgba32uint rgba32sint rgba32float bgra8unorm`.split(/\s+/);
3129
+ function stdType(name2) {
3130
+ return stdTypes.includes(name2);
3131
+ }
3132
+ function stdFn(name2) {
3133
+ return stdFns.includes(name2) || stdType(name2);
3134
+ }
3135
+ function stdEnumerant(name2) {
3136
+ return stdEnumerants.includes(name2);
3137
+ }
3138
+ function bindIdents(params) {
3139
+ const { rootAst, registry, virtuals } = params;
3140
+ const { conditions = {}, mangler = minimalMangle } = params;
3141
+ const { rootScope } = rootAst;
3142
+ const globalNames = /* @__PURE__ */ new Set();
3143
+ const knownDecls = /* @__PURE__ */ new Set();
3144
+ const validRootDecls = findValidRootDecls(rootScope);
3145
+ validRootDecls.forEach((decl) => {
3146
+ decl.mangledName = decl.originalName;
3147
+ globalNames.add(decl.originalName);
3148
+ knownDecls.add(decl);
3149
+ });
3150
+ const globalStatements = /* @__PURE__ */ new Map();
3151
+ const bindContext = {
3152
+ registry,
3153
+ conditions,
3154
+ knownDecls,
3155
+ foundScopes: /* @__PURE__ */ new Set(),
3156
+ globalNames,
3157
+ globalStatements,
3158
+ virtuals,
3159
+ mangler
3160
+ };
3161
+ const declEntries = validRootDecls.map((d) => [d.originalName, d]);
3162
+ const liveDecls = { decls: new Map(declEntries), parent: null };
3163
+ const decls = bindIdentsRecursive(rootScope, bindContext, liveDecls, true);
3164
+ const filteredDecls = decls.filter(isGlobal);
3165
+ const newStatements = [...globalStatements.values()];
3166
+ return { decls: filteredDecls, globalNames, newStatements };
3167
+ }
3168
+ function findValidRootDecls(rootScope, conditions) {
3169
+ const found = [];
3170
+ for (const e of rootScope.contents) {
3171
+ if (e.kind === "decl") {
3172
+ assertThatDebug(e.declElem);
3173
+ if (elementValid(e.declElem)) {
3174
+ found.push(e);
3175
+ }
3176
+ } else if (e.kind === "partial") {
3177
+ found.push(...findValidRootDecls(e));
3178
+ }
3179
+ }
3180
+ return found;
3181
+ }
3182
+ function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
3183
+ const { conditions, foundScopes } = bindContext;
3184
+ if (foundScopes.has(scope)) return [];
3185
+ foundScopes.add(scope);
3186
+ const newGlobals = [];
3187
+ const newFromChildren = [];
3188
+ scope.contents.forEach((child) => {
3189
+ const { kind: kind2 } = child;
3190
+ if (kind2 === "decl") {
3191
+ const ident2 = child;
3192
+ if (!isRoot) liveDecls.decls.set(ident2.originalName, ident2);
3193
+ } else if (kind2 === "ref") {
3194
+ const newDecl = handleRef(child, liveDecls, bindContext);
3195
+ newDecl && newGlobals.push(newDecl);
3196
+ } else {
3197
+ const fromScope = handleScope(child, liveDecls, bindContext);
3198
+ if (fromScope) {
3199
+ newFromChildren.push(...fromScope);
3200
+ }
3201
+ }
3202
+ });
3203
+ const newFromRefs = newGlobals.flatMap((decl) => {
3204
+ const foundsScope = decl.scope;
3205
+ const rootDecls = globalDeclToRootLiveDecls(decl);
3206
+ {
3207
+ const rootLive = makeLiveDecls(rootDecls);
3208
+ return bindIdentsRecursive(foundsScope, bindContext, rootLive);
3209
+ }
3210
+ });
3211
+ return [newGlobals, newFromChildren, newFromRefs].flat();
3212
+ }
3213
+ function handleRef(ident2, liveDecls, bindContext) {
3214
+ const { registry, conditions } = bindContext;
3215
+ const { virtuals } = bindContext;
3216
+ if (!ident2.refersTo && !ident2.std) {
3217
+ const foundDecl = findDeclInModule(ident2, liveDecls) ?? findQualifiedImport(ident2, registry, conditions, virtuals);
3218
+ if (foundDecl) {
3219
+ ident2.refersTo = foundDecl.decl;
3220
+ return handleNewDecl(ident2, foundDecl, bindContext);
3221
+ } else if (stdWgsl(ident2.originalName)) {
3222
+ ident2.std = true;
3223
+ } else {
3224
+ failMissingIdent(ident2);
3225
+ }
3226
+ }
3227
+ }
3228
+ function handleScope(childScope2, liveDecls, bindContext) {
3229
+ if (!scopeValid(childScope2)) return;
3230
+ const { kind: kind2 } = childScope2;
3231
+ if (kind2 === "scope") {
3232
+ const newLive = makeLiveDecls(liveDecls);
3233
+ return bindIdentsRecursive(childScope2, bindContext, newLive);
3234
+ } else if (kind2 === "partial") {
3235
+ return bindIdentsRecursive(childScope2, bindContext, liveDecls);
3236
+ } else ;
3237
+ }
3238
+ function handleNewDecl(refIdent2, foundDecl, bindContext) {
3239
+ const { decl, moduleAst } = foundDecl;
3240
+ const { knownDecls, globalNames, mangler, globalStatements } = bindContext;
3241
+ if (!knownDecls.has(decl)) {
3242
+ knownDecls.add(decl);
3243
+ const { srcModule } = decl;
3244
+ const proposed = refIdent2.originalName;
3245
+ setMangledName(proposed, decl, globalNames, srcModule, mangler);
3246
+ if (isGlobal(decl)) {
3247
+ const { moduleAsserts } = moduleAst;
3248
+ const moduleEmit = moduleAsserts == null ? void 0 : moduleAsserts.map((elem) => ({ srcModule, elem }));
3249
+ moduleEmit == null ? void 0 : moduleEmit.forEach((e) => globalStatements.set(e.elem, e));
3250
+ return decl;
3251
+ }
3252
+ }
3253
+ }
3254
+ function globalDeclToRootLiveDecls(decl, conditions) {
3255
+ assertThatDebug(decl.isGlobal, identToString(decl));
3256
+ let rootScope = decl.scope;
3257
+ while (rootScope.parent) {
3258
+ rootScope = rootScope.parent;
3259
+ }
3260
+ const rootDecls = findValidRootDecls(rootScope);
3261
+ const entires = rootDecls.map((d) => [d.originalName, d]);
3262
+ const decls = new Map(entires);
3263
+ return { decls };
3264
+ }
3265
+ function failMissingIdent(ident2) {
3266
+ const { refIdentElem } = ident2;
3267
+ if (refIdentElem) {
3268
+ const { srcModule, start, end } = refIdentElem;
3269
+ const { debugFilePath: filePath } = srcModule;
3270
+ const msg = `unresolved identifier '${ident2.originalName}' in file: ${filePath}`;
3271
+ srcLog(srcModule.src, [start, end], msg);
3272
+ throw new Error(msg);
3273
+ }
3274
+ }
3275
+ function setMangledName(proposedName, decl, globalNames, srcModule, mangler) {
3276
+ if (!decl.mangledName) {
3277
+ let mangledName;
3278
+ if (isGlobal(decl)) {
3279
+ const sep = proposedName.lastIndexOf("::");
3280
+ const name2 = sep === -1 ? proposedName : proposedName.slice(sep + 2);
3281
+ mangledName = mangler(decl, srcModule, name2, globalNames);
3282
+ } else {
3283
+ mangledName = decl.originalName;
3284
+ }
3285
+ decl.mangledName = mangledName;
3286
+ globalNames.add(mangledName);
3287
+ }
3288
+ }
3289
+ function stdWgsl(name2) {
3290
+ return stdType(name2) || stdFn(name2) || stdEnumerant(name2);
3291
+ }
3292
+ function findDeclInModule(ident2, liveDecls) {
3293
+ const { originalName } = ident2;
3294
+ const found = liveDecls.decls.get(originalName);
3295
+ if (found) {
3296
+ return { decl: found, moduleAst: ident2.ast };
3297
+ }
3298
+ const { parent } = liveDecls;
3299
+ if (parent) {
3300
+ return findDeclInModule(ident2, parent);
3301
+ }
3302
+ }
3303
+ function findQualifiedImport(refIdent2, parsed, conditions, virtuals) {
3304
+ const flatImps = flatImports(refIdent2.ast);
3305
+ const identParts = refIdent2.originalName.split("::");
3306
+ const modulePathParts = matchingImport(identParts, flatImps) ?? qualifiedImport(identParts);
3307
+ if (modulePathParts) {
3308
+ const { srcModule } = refIdent2.ast;
3309
+ return findExport(modulePathParts, srcModule, parsed, conditions, virtuals);
3310
+ }
3311
+ }
3312
+ function qualifiedImport(identParts) {
3313
+ if (identParts.length > 1) return identParts;
3314
+ }
3315
+ function matchingImport(identParts, flatImports2) {
3316
+ for (const flat of flatImports2) {
3317
+ if (flat.importPath.at(-1) === identParts.at(0)) {
3318
+ return [...flat.modulePath, ...identParts.slice(1)];
3319
+ }
3320
+ }
3321
+ }
3322
+ function findExport(modulePathParts, srcModule, parsed, conditions = {}, virtuals) {
3323
+ const fqPathParts = absoluteModulePath(modulePathParts, srcModule);
3324
+ const modulePath = fqPathParts.slice(0, -1).join("::");
3325
+ const moduleAst = parsed.modules[modulePath] ?? virtualModule(modulePathParts[0], conditions, virtuals);
3326
+ if (!moduleAst) {
3327
+ console.log(`ident ${modulePathParts.join("::")}, but module not found`);
3328
+ return void 0;
3329
+ }
3330
+ const name2 = last(modulePathParts);
3331
+ const decl = publicDecl(moduleAst.rootScope, name2);
3332
+ if (decl) {
3333
+ return { decl, moduleAst };
3334
+ }
3335
+ }
3336
+ function absoluteModulePath(modulePathParts, srcModule) {
3337
+ const lastSuper = modulePathParts.findLastIndex((p) => p === "super");
3338
+ if (lastSuper > -1) {
3339
+ const srcModuleParts = srcModule.modulePath.split("::");
3340
+ const base = srcModuleParts.slice(0, -(lastSuper + 1));
3341
+ const noSupers = modulePathParts.slice(lastSuper + 1);
3342
+ return [...base, ...noSupers];
3343
+ }
3344
+ return modulePathParts;
3345
+ }
3346
+ function virtualModule(moduleName, conditions = {}, virtuals) {
3347
+ if (!virtuals) return void 0;
3348
+ const found = virtuals[moduleName];
3349
+ if (found) {
3350
+ const { ast, fn: fn2 } = found;
3351
+ if (ast) return ast;
3352
+ const src = fn2(conditions);
3353
+ const srcModule = {
3354
+ modulePath: moduleName,
3355
+ debugFilePath: moduleName,
3356
+ src
3357
+ };
3358
+ found.ast = parseSrcModule(srcModule);
3359
+ return found.ast;
3360
+ }
3361
+ }
3362
+ function isGlobal(declIdent) {
3363
+ const { declElem } = declIdent;
3364
+ if (!declElem) return false;
3365
+ return ["alias", "const", "override", "fn", "struct", "gvar"].includes(
3366
+ declElem.kind
3367
+ );
3368
+ }
3369
+ function lowerAndEmit(srcBuilder, rootElems, conditions, extracting = true) {
3370
+ const emitContext = { conditions, srcBuilder, extracting };
3371
+ rootElems.forEach((e) => lowerAndEmitElem(e, emitContext));
3372
+ }
3373
+ function lowerAndEmitElem(e, ctx) {
3374
+ if (!conditionsValid(e, ctx.conditions)) return;
3375
+ switch (e.kind) {
3376
+ // import statements are dropped from from emitted text
3377
+ case "import":
3378
+ return;
3379
+ // terminal elements copy strings to the output
3380
+ case "text":
3381
+ return emitText(e, ctx);
3382
+ case "name":
3383
+ return emitName(e, ctx);
3384
+ case "synthetic":
3385
+ return emitSynthetic(e, ctx);
3386
+ // identifiers are copied to the output, but with potentially mangled names
3387
+ case "ref":
3388
+ return emitRefIdent(e, ctx);
3389
+ case "decl":
3390
+ return emitDeclIdent(e, ctx);
3391
+ // container elements just emit their child elements
3392
+ case "param":
3393
+ case "var":
3394
+ case "typeDecl":
3395
+ case "let":
3396
+ case "module":
3397
+ case "member":
3398
+ case "memberRef":
3399
+ case "expression":
3400
+ case "type":
3401
+ case "statement":
3402
+ case "stuff":
3403
+ case "switch-clause":
3404
+ return emitContents(e, ctx);
3405
+ // root level container elements get some extra newlines to make the output prettier
3406
+ case "override":
3407
+ case "const":
3408
+ case "assert":
3409
+ case "alias":
3410
+ case "gvar":
3411
+ emitRootElemNl(ctx);
3412
+ return emitContents(e, ctx);
3413
+ case "fn":
3414
+ emitRootElemNl(ctx);
3415
+ return emitFn(e, ctx);
3416
+ case "struct":
3417
+ emitRootElemNl(ctx);
3418
+ return emitStruct(e, ctx);
3419
+ case "attribute":
3420
+ return emitAttribute(e, ctx);
3421
+ case "directive":
3422
+ return emitDirective(e, ctx);
3423
+ default:
3424
+ assertUnreachable(e);
3425
+ }
3426
+ }
3427
+ function emitRootElemNl(ctx) {
3428
+ if (ctx.extracting) {
3429
+ ctx.srcBuilder.addNl();
3430
+ ctx.srcBuilder.addNl();
3431
+ }
3432
+ }
3433
+ function emitText(e, ctx) {
3434
+ ctx.srcBuilder.addCopy(e.start, e.end);
3435
+ }
3436
+ function emitName(e, ctx) {
3437
+ ctx.srcBuilder.add(e.name, e.start, e.end);
3438
+ }
3439
+ function emitFn(e, ctx) {
3440
+ const { attributes, name: name2, params, returnAttributes, returnType, body } = e;
3441
+ const { conditions, srcBuilder: builder } = ctx;
3442
+ emitAttributes(attributes, ctx);
3443
+ builder.add("fn ", name2.start - 3, name2.start);
3444
+ emitDeclIdent(name2, ctx);
3445
+ builder.appendNext("(");
3446
+ const validParams = params.filter((p) => conditionsValid(p));
3447
+ validParams.forEach((p, i) => {
3448
+ emitContentsNoWs(p, ctx);
3449
+ if (i < validParams.length - 1) {
3450
+ builder.appendNext(", ");
3451
+ }
3452
+ });
3453
+ builder.appendNext(") ");
3454
+ if (returnType) {
3455
+ builder.appendNext("-> ");
3456
+ emitAttributes(returnAttributes, ctx);
3457
+ emitContents(returnType, ctx);
3458
+ builder.appendNext(" ");
3459
+ }
3460
+ emitContents(body, ctx);
3461
+ }
3462
+ function emitAttributes(attributes, ctx) {
3463
+ attributes == null ? void 0 : attributes.forEach((a) => {
3464
+ emitAttribute(a, ctx);
3465
+ ctx.srcBuilder.add(" ", a.start, a.end);
3466
+ });
3467
+ }
3468
+ function emitStruct(e, ctx) {
3469
+ const { name: name2, members, start, end } = e;
3470
+ const { srcBuilder } = ctx;
3471
+ const validMembers = members.filter((m) => conditionsValid(m, ctx.conditions));
3472
+ const validLength = validMembers.length;
3473
+ if (validLength === 0) {
3474
+ warnEmptyStruct(e);
3475
+ return;
3476
+ }
3477
+ srcBuilder.add("struct ", start, name2.start);
3478
+ emitDeclIdent(name2, ctx);
3479
+ if (validLength === 1) {
3480
+ srcBuilder.add(" { ", name2.end, members[0].start);
3481
+ emitContentsNoWs(validMembers[0], ctx);
3482
+ srcBuilder.add(" }\n", end - 1, end);
3483
+ } else {
3484
+ srcBuilder.add(" {\n", name2.end, members[0].start);
3485
+ validMembers.forEach((m) => {
3486
+ srcBuilder.add(" ", m.start - 1, m.start);
3487
+ emitContentsNoWs(m, ctx);
3488
+ srcBuilder.add(",", m.end, m.end + 1);
3489
+ srcBuilder.addNl();
3490
+ });
3491
+ srcBuilder.add("}\n", end - 1, end);
3492
+ }
3493
+ }
3494
+ function warnEmptyStruct(e) {
3495
+ const { name: name2, members } = e;
3496
+ const condStr = members.length ? "(with current conditions)" : "";
3497
+ const { debugFilePath: filePath } = name2.srcModule;
3498
+ srcLog(
3499
+ name2.srcModule.src,
3500
+ e.start,
3501
+ `struct ${name2.ident.originalName} in ${filePath} has no members ${condStr}`
3502
+ );
3503
+ }
3504
+ function emitSynthetic(e, ctx) {
3505
+ const { text: text2 } = e;
3506
+ ctx.srcBuilder.addSynthetic(text2, text2, 0, text2.length);
3507
+ }
3508
+ function emitContents(elem, ctx) {
3509
+ elem.contents.forEach((e) => lowerAndEmitElem(e, ctx));
3510
+ }
3511
+ function emitContentsNoWs(elem, ctx) {
3512
+ elem.contents.forEach((e) => {
3513
+ if (e.kind === "text") {
3514
+ const { srcModule, start, end } = e;
3515
+ const text2 = srcModule.src.slice(start, end);
3516
+ if (text2.trim() === "") {
3517
+ return;
3518
+ }
3519
+ }
3520
+ lowerAndEmitElem(e, ctx);
3521
+ });
3522
+ }
3523
+ function emitRefIdent(e, ctx) {
3524
+ if (e.ident.std) {
3525
+ ctx.srcBuilder.add(e.ident.originalName, e.start, e.end);
3526
+ } else {
3527
+ const declIdent = findDecl(e.ident);
3528
+ const mangledName = displayName(declIdent);
3529
+ ctx.srcBuilder.add(mangledName, e.start, e.end);
3530
+ }
3531
+ }
3532
+ function emitDeclIdent(e, ctx) {
3533
+ const mangledName = displayName(e.ident);
3534
+ ctx.srcBuilder.add(mangledName, e.start, e.end);
3535
+ }
3536
+ function emitAttribute(e, ctx) {
3537
+ const { kind: kind2 } = e.attribute;
3538
+ if (kind2 === "@attribute") {
3539
+ const { params } = e.attribute;
3540
+ if (!params || params.length === 0) {
3541
+ ctx.srcBuilder.add("@" + e.attribute.name, e.start, e.end);
3542
+ } else {
3543
+ ctx.srcBuilder.add(
3544
+ "@" + e.attribute.name + "(",
3545
+ e.start,
3546
+ params[0].start
3547
+ );
3548
+ for (let i = 0; i < params.length; i++) {
3549
+ emitContents(params[i], ctx);
3550
+ if (i < params.length - 1) {
3551
+ ctx.srcBuilder.add(",", params[i].end, params[i + 1].start);
3552
+ }
3553
+ }
3554
+ ctx.srcBuilder.add(")", params[params.length - 1].end, e.end);
3555
+ }
3556
+ } else if (kind2 === "@builtin") {
3557
+ ctx.srcBuilder.add(
3558
+ "@builtin(" + e.attribute.param.name + ")",
3559
+ e.start,
3560
+ e.end
3561
+ );
3562
+ } else if (kind2 === "@diagnostic") {
3563
+ ctx.srcBuilder.add(
3564
+ "@diagnostic" + diagnosticControlToString(e.attribute.severity, e.attribute.rule),
3565
+ e.start,
3566
+ e.end
3567
+ );
3568
+ } else if (kind2 === "@if") ;
3569
+ else if (kind2 === "@interpolate") {
3570
+ ctx.srcBuilder.add(
3571
+ `@interpolate(${e.attribute.params.map((v) => v.name).join(", ")})`,
3572
+ e.start,
3573
+ e.end
3574
+ );
3575
+ } else {
3576
+ assertUnreachable(kind2);
3577
+ }
3578
+ }
3579
+ function diagnosticControlToString(severity, rule) {
3580
+ const ruleStr = rule[0].name + (rule[1] !== null ? "." + rule[1].name : "");
3581
+ return `(${severity.name}, ${ruleStr})`;
3582
+ }
3583
+ function expressionToString(elem) {
3584
+ const { kind: kind2 } = elem;
3585
+ if (kind2 === "binary-expression") {
3586
+ return `${expressionToString(elem.left)} ${elem.operator.value} ${expressionToString(elem.right)}`;
3587
+ } else if (kind2 === "unary-expression") {
3588
+ return `${elem.operator.value}${expressionToString(elem.expression)}`;
3589
+ } else if (kind2 === "ref") {
3590
+ return elem.ident.originalName;
3591
+ } else if (kind2 === "literal") {
3592
+ return elem.value;
3593
+ } else if (kind2 === "translate-time-feature") {
3594
+ return elem.name;
3595
+ } else if (kind2 === "parenthesized-expression") {
3596
+ return `(${expressionToString(elem.expression)})`;
3597
+ } else if (kind2 === "component-expression") {
3598
+ return `${expressionToString(elem.base)}[${elem.access}]`;
3599
+ } else if (kind2 === "component-member-expression") {
3600
+ return `${expressionToString(elem.base)}.${elem.access}`;
3601
+ } else if (kind2 === "call-expression") {
3602
+ return `${elem.function.ident.originalName}(${elem.arguments.map(expressionToString).join(", ")})`;
3603
+ } else {
3604
+ assertUnreachable(kind2);
3605
+ }
3606
+ }
3607
+ function emitDirective(e, ctx) {
3608
+ const { directive } = e;
3609
+ const { kind: kind2 } = directive;
3610
+ if (kind2 === "diagnostic") {
3611
+ ctx.srcBuilder.add(
3612
+ `diagnostic${diagnosticControlToString(directive.severity, directive.rule)};`,
3613
+ e.start,
3614
+ e.end
3615
+ );
3616
+ } else if (kind2 === "enable") {
3617
+ ctx.srcBuilder.add(
3618
+ `enable ${directive.extensions.map((v) => v.name).join(", ")};`,
3619
+ e.start,
3620
+ e.end
3621
+ );
3622
+ } else if (kind2 === "requires") {
3623
+ ctx.srcBuilder.add(
3624
+ `requires ${directive.extensions.map((v) => v.name).join(", ")};`,
3625
+ e.start,
3626
+ e.end
3627
+ );
3628
+ } else {
3629
+ assertUnreachable(kind2);
3630
+ }
3631
+ }
3632
+ function displayName(declIdent) {
3633
+ if (isGlobal(declIdent)) {
3634
+ assertThatDebug(
3635
+ declIdent.mangledName,
3636
+ `ERR: mangled name not found for decl ident ${identToString(declIdent)}`
3637
+ );
3638
+ return declIdent.mangledName;
3639
+ }
3640
+ return declIdent.mangledName || declIdent.originalName;
3641
+ }
3642
+ function findDecl(ident2) {
3643
+ let i = ident2;
3644
+ do {
3645
+ if (i.kind === "decl") {
3646
+ return i;
3647
+ }
3648
+ i = i.refersTo;
3649
+ } while (i);
3650
+ throw new Error(`unresolved identifer: ${ident2.originalName}`);
3651
+ }
3652
+ function conditionsValid(elem, conditions) {
3653
+ const attrElem = elem;
3654
+ const { kind: kind2 } = attrElem;
3655
+ switch (kind2) {
3656
+ case "alias":
3657
+ case "assert":
3658
+ case "const":
3659
+ case "directive":
3660
+ case "member":
3661
+ case "var":
3662
+ case "let":
3663
+ case "statement":
3664
+ case "switch-clause":
3665
+ case "override":
3666
+ case "gvar":
3667
+ case "fn":
3668
+ case "struct":
3669
+ case "param":
3670
+ return elementValid(attrElem);
3671
+ }
3672
+ return true;
3673
+ }
3674
+ function importToString(tree) {
3675
+ return importToStringImpl(tree) + ";";
3676
+ }
3677
+ function importToStringImpl(tree) {
3678
+ return [
3679
+ ...tree.segments.map((s) => s.name),
3680
+ segmentToString(tree.finalSegment)
3681
+ ].join("::");
3682
+ }
3683
+ function segmentToString(segment) {
3684
+ if (segment.kind === "import-item") {
3685
+ const { name: name2, as } = segment;
3686
+ const asMsg = as ? ` as ${as}` : "";
3687
+ return `${name2}${asMsg}`;
3688
+ } else if (segment.kind === "import-collection") {
3689
+ return `{${segment.subtrees.map((s) => importToStringImpl(s)).join(", ")}}`;
3690
+ } else {
3691
+ assertUnreachable$1(segment);
3692
+ }
3693
+ }
3694
+ const maxLineLength = 150;
3695
+ function astToString(elem, indent = 0) {
3696
+ const { kind: kind2 } = elem;
3697
+ const str = new LineWrapper(indent, maxLineLength);
3698
+ str.add(kind2);
3699
+ addElemFields(elem, str);
3700
+ let childStrings = [];
3701
+ if ("contents" in elem) {
3702
+ childStrings = elem.contents.map((e) => astToString(e, indent + 2));
3703
+ }
3704
+ if (childStrings.length) {
3705
+ str.nl();
3706
+ str.addBlock(childStrings.join("\n"), false);
3707
+ }
3708
+ return str.result;
3709
+ }
3710
+ function addElemFields(elem, str) {
3711
+ const { kind: kind2 } = elem;
3712
+ if (kind2 === "text") {
3713
+ const { srcModule, start, end } = elem;
3714
+ str.add(` '${srcModule.src.slice(start, end)}'`);
3715
+ } else if (kind2 === "var" || kind2 === "let" || kind2 === "gvar" || kind2 === "const" || kind2 === "override") {
3716
+ addTypedDeclIdent(elem.name, str);
3717
+ listAttributeElems(elem.attributes, str);
3718
+ } else if (kind2 === "struct") {
3719
+ str.add(" " + elem.name.ident.originalName);
3720
+ } else if (kind2 === "member") {
3721
+ const { name: name2, typeRef, attributes } = elem;
3722
+ listAttributeElems(attributes, str);
3723
+ str.add(" " + name2.name);
3724
+ str.add(": " + typeRefElemToString(typeRef));
3725
+ } else if (kind2 === "name") {
3726
+ str.add(" " + elem.name);
3727
+ } else if (kind2 === "memberRef") {
3728
+ const { extraComponents } = elem;
3729
+ const extraText = extraComponents ? debugContentsToString(extraComponents) : "";
3730
+ str.add(` ${elem.name.ident.originalName}.${elem.member.name}${extraText}`);
3731
+ } else if (kind2 === "fn") {
3732
+ addFnFields(elem, str);
3733
+ } else if (kind2 === "alias") {
3734
+ const { name: name2, typeRef } = elem;
3735
+ const prefix = name2.ident.kind === "decl" ? "%" : "";
3736
+ str.add(" " + prefix + name2.ident.originalName);
3737
+ str.add("=" + typeRefElemToString(typeRef));
3738
+ } else if (kind2 === "attribute") {
3739
+ addAttributeFields(elem.attribute, str);
3740
+ } else if (kind2 === "expression") {
3741
+ const contents = elem.contents.map((e) => {
3742
+ if (e.kind === "text") {
3743
+ return "'" + e.srcModule.src.slice(e.start, e.end) + "'";
3744
+ } else {
3745
+ return astToString(e);
3746
+ }
3747
+ }).join(" ");
3748
+ str.add(" " + contents);
3749
+ } else if (kind2 === "type") {
3750
+ const { name: name2 } = elem;
3751
+ const nameStr = typeof name2 === "string" ? name2 : name2.originalName;
3752
+ str.add(" " + nameStr);
3753
+ if (elem.templateParams !== void 0) {
3754
+ const paramStrs = elem.templateParams.map(templateParamToString).join(", ");
3755
+ str.add("<" + paramStrs + ">");
3756
+ }
3757
+ } else if (kind2 === "synthetic") {
3758
+ str.add(` '${elem.text}'`);
3759
+ } else if (kind2 === "import") {
3760
+ str.add(" " + importToString(elem.imports));
3761
+ } else if (kind2 === "ref") {
3762
+ str.add(" " + elem.ident.originalName);
3763
+ } else if (kind2 === "typeDecl") {
3764
+ addTypedDeclIdent(elem, str);
3765
+ } else if (kind2 === "decl") {
3766
+ const { ident: ident2 } = elem;
3767
+ str.add(" %" + ident2.originalName);
3768
+ } else if (kind2 === "assert") ;
3769
+ else if (kind2 === "module") ;
3770
+ else if (kind2 === "param") ;
3771
+ else if (kind2 === "stuff") ;
3772
+ else if (kind2 === "directive") {
3773
+ addDirective(elem, str);
3774
+ } else if (kind2 === "statement") {
3775
+ listAttributeElems(elem.attributes, str);
3776
+ } else if (kind2 === "switch-clause") ;
3777
+ else {
3778
+ assertUnreachable$1(kind2);
3779
+ }
3780
+ }
3781
+ function addAttributeFields(attr, str) {
3782
+ const { kind: kind2 } = attr;
3783
+ if (kind2 === "@attribute") {
3784
+ const { name: name2, params } = attr;
3785
+ str.add(" @" + name2);
3786
+ if (params && params.length > 0) {
3787
+ str.add("(");
3788
+ str.add(params.map(unknownExpressionToString).join(", "));
3789
+ str.add(")");
3790
+ }
3791
+ } else if (kind2 === "@builtin") {
3792
+ str.add(` @builtin(${attr.param.name})`);
3793
+ } else if (kind2 === "@diagnostic") {
3794
+ str.add(
3795
+ ` @diagnostic${diagnosticControlToString(attr.severity, attr.rule)}`
3796
+ );
3797
+ } else if (kind2 === "@if") {
3798
+ str.add(" @if");
3799
+ str.add("(");
3800
+ str.add(expressionToString(attr.param.expression));
3801
+ str.add(")");
3802
+ } else if (kind2 === "@interpolate") {
3803
+ str.add(` @interpolate(${attr.params.map((v) => v.name).join(", ")})`);
3804
+ } else {
3805
+ assertUnreachable$1(kind2);
3806
+ }
3807
+ }
3808
+ function attributeToString$1(attr) {
3809
+ const str = new LineWrapper(0, maxLineLength);
3810
+ addAttributeFields(attr, str);
3811
+ return str.result;
3812
+ }
3813
+ function addTypedDeclIdent(elem, str) {
3814
+ const { decl, typeRef } = elem;
3815
+ str.add(" %" + decl.ident.originalName);
3816
+ if (typeRef) {
3817
+ str.add(" : " + typeRefElemToString(typeRef));
3818
+ }
3819
+ }
3820
+ function addFnFields(elem, str) {
3821
+ const { name: name2, params, returnType, attributes } = elem;
3822
+ str.add(" " + name2.ident.originalName);
3823
+ str.add("(");
3824
+ const paramStrs = params.map(
3825
+ (p) => {
3826
+ const { name: name22 } = p;
3827
+ const { originalName } = name22.decl.ident;
3828
+ const typeRef = typeRefElemToString(name22.typeRef);
3829
+ return originalName + ": " + typeRef;
3830
+ }
3831
+ ).join(", ");
3832
+ str.add(paramStrs);
3833
+ str.add(")");
3834
+ listAttributeElems(attributes, str);
3835
+ if (returnType) {
3836
+ str.add(" -> " + typeRefElemToString(returnType));
3837
+ }
3838
+ }
3839
+ function listAttributeElems(attributes, str) {
3840
+ attributes == null ? void 0 : attributes.forEach((a) => str.add(" " + attributeName(a.attribute)));
3841
+ }
3842
+ function attributeName(attr) {
3843
+ const { kind: kind2 } = attr;
3844
+ if (kind2 === "@attribute") {
3845
+ return "@" + attr.name;
3846
+ } else {
3847
+ return kind2;
3848
+ }
3849
+ }
3850
+ function addDirective(elem, str) {
3851
+ const { directive, attributes } = elem;
3852
+ const { kind: kind2 } = directive;
3853
+ if (kind2 === "diagnostic") {
3854
+ const { severity, rule } = directive;
3855
+ const control = diagnosticControlToString(severity, rule);
3856
+ str.add(` diagnostic${control}`);
3857
+ } else if (kind2 === "enable" || kind2 === "requires") {
3858
+ str.add(` ${kind2} ${directive.extensions.map((v) => v.name).join(", ")}`);
3859
+ } else {
3860
+ assertUnreachable$1(kind2);
3861
+ }
3862
+ listAttributeElems(attributes, str);
3863
+ }
3864
+ function unknownExpressionToString(elem) {
3865
+ if ("contents" in elem) {
3866
+ const contents = elem.contents.map((e) => {
3867
+ if (e.kind === "text") {
3868
+ return "'" + e.srcModule.src.slice(e.start, e.end) + "'";
3869
+ } else {
3870
+ return astToString(e);
3871
+ }
3872
+ }).join(" ");
3873
+ return contents;
3874
+ }
3875
+ return astToString(elem);
3876
+ }
3877
+ function templateParamToString(p) {
3878
+ if (typeof p === "string") {
3879
+ return p;
3880
+ } else if (p.kind === "type") {
3881
+ return typeRefElemToString(p);
3882
+ } else if (p.kind === "expression") {
3883
+ return unknownExpressionToString(p);
3884
+ } else {
3885
+ console.log("unknown template parameter type", p);
3886
+ return "??";
3887
+ }
3888
+ }
3889
+ function typeRefElemToString(elem) {
3890
+ if (!elem) return "?type?";
3891
+ const { name: name2 } = elem;
3892
+ const nameStr = typeof name2 === "string" ? name2 : name2.originalName;
3893
+ let params = "";
3894
+ if (elem.templateParams !== void 0) {
3895
+ const paramStrs = elem.templateParams.map(templateParamToString).join(", ");
3896
+ params = "<" + paramStrs + ">";
3897
+ }
3898
+ return nameStr + params;
3899
+ }
3900
+ function debugContentsToString(elem) {
3901
+ const parts = elem.contents.map((c) => {
3902
+ const { kind: kind2 } = c;
3903
+ if (kind2 === "text") {
3904
+ return c.srcModule.src.slice(c.start, c.end);
3905
+ } else if (kind2 === "ref") {
3906
+ return c.ident.originalName;
3907
+ } else {
3908
+ return `?${c.kind}?`;
3909
+ }
3910
+ });
3911
+ return parts.join(" ");
3912
+ }
3913
+ class LinkedWesl {
3914
+ constructor(sourceMap) {
3915
+ this.sourceMap = sourceMap;
3916
+ }
3917
+ /**
3918
+ * Creates a {@link GPUShaderModule}.
3919
+ * When errors occur, they will point at the original WESL source code.
3920
+ *
3921
+ * The compilation info {@link GPUShaderModule.getCompilationInfo}
3922
+ * can be remapped with {@link mapGPUCompilationInfo}
3923
+ * @param device GPUDevice. Preferably a {@link WeslDevice} for better error reporting.
3924
+ * @param descriptor - Description of the {@link GPUShaderModule} to create.
3925
+ */
3926
+ createShaderModule(device, descriptor) {
3927
+ if (!("injectError" in device)) {
3928
+ return device.createShaderModule({
3929
+ ...descriptor,
3930
+ code: this.dest
3931
+ });
3932
+ }
3933
+ device.pushErrorScope("validation");
3934
+ const module = device.createShaderModule({
3935
+ ...descriptor,
3936
+ code: this.dest
3937
+ });
3938
+ device.popErrorScope();
3939
+ let { promise, resolve } = Promise.withResolvers();
3940
+ device.injectError("validation", promise);
3941
+ module.getCompilationInfo().then((compilationInfo) => {
3942
+ if (compilationInfo.messages.length === 0) {
3943
+ resolve(null);
3944
+ return;
3945
+ }
3946
+ const mappedCompilationInfo = this.mapGPUCompilationInfo(compilationInfo);
3947
+ const errorMessage = compilationInfoToErrorMessage(
3948
+ mappedCompilationInfo,
3949
+ module
3950
+ );
3951
+ assertThat(errorMessage !== null);
3952
+ const error = new GPUValidationError(
3953
+ errorMessage
3954
+ );
3955
+ error.cause = new Error("createShaderModule failed");
3956
+ error.compilationInfo = mappedCompilationInfo;
3957
+ resolve(error);
3958
+ });
3959
+ return module;
3960
+ }
3961
+ /**
3962
+ * Use {@link LinkedWesl.createShaderModule} for a
3963
+ * better error reporting experience.
3964
+ */
3965
+ get dest() {
3966
+ return this.sourceMap.dest.text;
3967
+ }
3968
+ /** Turns raw compilation info into compilation info
3969
+ * that points at the WESL sources. */
3970
+ mapGPUCompilationInfo(compilationInfo) {
3971
+ return {
3972
+ __brand: compilationInfo.__brand,
3973
+ messages: compilationInfo.messages.map(
3974
+ (v) => this.mapGPUCompilationMessage(v)
3975
+ )
3976
+ };
3977
+ }
3978
+ mapGPUCompilationMessage(message) {
3979
+ const srcMap = this.sourceMap;
3980
+ const srcPosition = srcMap.destToSrc(message.offset);
3981
+ const srcEndPosition = message.length > 0 ? srcMap.destToSrc(message.offset + message.length) : srcPosition;
3982
+ const length = srcEndPosition.position - srcPosition.position;
3983
+ let [lineNum, linePos] = offsetToLineNumber(
3984
+ srcPosition.position,
3985
+ srcPosition.src.text
3986
+ );
3987
+ return {
3988
+ __brand: message.__brand,
3989
+ type: message.type,
3990
+ message: message.message,
3991
+ offset: srcPosition.position,
3992
+ length,
3993
+ lineNum,
3994
+ linePos,
3995
+ module: {
3996
+ url: srcPosition.src.path ?? "",
3997
+ text: srcPosition.src.text
3998
+ }
3999
+ };
4000
+ }
4001
+ }
4002
+ function compilationInfoToErrorMessage(compilationInfo, shaderModule) {
4003
+ if (compilationInfo.messages.length === 0) return null;
4004
+ let result = `Compilation log for [Invalid ShaderModule (${shaderModule.label || "unlabled"})]:
4005
+ `;
4006
+ let errorCount = compilationInfo.messages.filter(
4007
+ (v) => v.type === "error"
4008
+ ).length;
4009
+ if (errorCount > 0) {
4010
+ result += `${errorCount} error(s) generated while compiling the shader:
4011
+ `;
4012
+ }
4013
+ for (const message of compilationInfo.messages) {
4014
+ const { lineNum, linePos } = message;
4015
+ result += `${message.module.url}:${lineNum}:${linePos}`;
4016
+ result += ` ${message.type}: ${message.message}
4017
+ `;
4018
+ const source = message.module.text;
4019
+ if (source) {
4020
+ result += errorHighlight(source, [
4021
+ message.offset,
4022
+ message.offset + message.length
4023
+ ]).join("\n");
4024
+ }
4025
+ }
4026
+ return result;
4027
+ }
4028
+ function normalize(path) {
4029
+ const segments = path.split("/");
4030
+ const noDots = segments.filter((s) => s !== ".");
4031
+ const noDbl = [];
4032
+ noDots.forEach((s) => {
4033
+ if (s !== "") {
4034
+ if (s === ".." && noDbl.length && noDbl[noDbl.length - 1] !== "..") {
4035
+ noDbl.pop();
4036
+ } else {
4037
+ noDbl.push(s);
4038
+ }
4039
+ }
4040
+ });
4041
+ return noDbl.join("/");
4042
+ }
4043
+ function noSuffix(path) {
4044
+ const lastSlash = path.lastIndexOf("/");
4045
+ const lastStart = lastSlash === -1 ? 0 : lastSlash + 1;
4046
+ const suffix = path.indexOf(".", lastStart);
4047
+ const suffixStart = suffix === -1 ? path.length : suffix;
4048
+ return path.slice(0, suffixStart);
4049
+ }
4050
+ function parsedRegistry() {
4051
+ resetScopeIds();
4052
+ return { modules: {} };
4053
+ }
4054
+ function registryToString(registry) {
4055
+ return `modules: ${[...Object.keys(registry.modules)]}`;
4056
+ }
4057
+ function parseWeslSrc(src) {
4058
+ const parsedEntries = Object.entries(src).map(([path, src2]) => {
4059
+ const weslAST = parseWESL(src2);
4060
+ return [path, weslAST];
4061
+ });
4062
+ return { modules: Object.fromEntries(parsedEntries) };
4063
+ }
4064
+ function selectModule(parsed, selectPath, packageName = "package") {
4065
+ let modulePath;
4066
+ if (selectPath.includes("::")) {
4067
+ modulePath = selectPath;
4068
+ } else if (selectPath.includes("/") || selectPath.endsWith(".wesl") || selectPath.endsWith(".wgsl")) {
4069
+ modulePath = fileToModulePath(selectPath, packageName);
4070
+ } else {
4071
+ modulePath = packageName + "::" + selectPath;
4072
+ }
4073
+ return parsed.modules[modulePath];
4074
+ }
4075
+ function parseIntoRegistry(srcFiles, registry, packageName = "package", debugWeslRoot) {
4076
+ if (debugWeslRoot === void 0) {
4077
+ debugWeslRoot = "";
4078
+ } else if (!debugWeslRoot.endsWith("/")) {
4079
+ debugWeslRoot += "/";
4080
+ }
4081
+ const srcModules = Object.entries(srcFiles).map(
4082
+ ([filePath, src]) => {
4083
+ const modulePath = fileToModulePath(filePath, packageName);
4084
+ return { modulePath, debugFilePath: debugWeslRoot + filePath, src };
4085
+ }
4086
+ );
4087
+ srcModules.forEach((mod) => {
4088
+ const parsed = parseSrcModule(mod);
4089
+ if (registry.modules[mod.modulePath]) {
4090
+ throw new Error(`duplicate module path: '${mod.modulePath}'`);
4091
+ }
4092
+ registry.modules[mod.modulePath] = parsed;
4093
+ });
4094
+ }
4095
+ function parseLibsIntoRegistry(libs, registry) {
4096
+ libs.forEach(
4097
+ ({ modules, name: name2 }) => parseIntoRegistry(modules, registry, name2)
4098
+ );
4099
+ }
4100
+ const libRegex = /^lib\.w[eg]sl$/i;
4101
+ function fileToModulePath(filePath, packageName) {
4102
+ if (filePath.includes("::")) {
4103
+ return filePath;
4104
+ }
4105
+ if (packageName !== "package" && libRegex.test(filePath)) {
4106
+ return packageName;
4107
+ }
4108
+ const strippedPath = noSuffix(normalize(filePath));
4109
+ const moduleSuffix = strippedPath.replaceAll("/", "::");
4110
+ const modulePath = packageName + "::" + moduleSuffix;
4111
+ return modulePath;
4112
+ }
4113
+ async function link(params) {
4114
+ const { weslSrc, debugWeslRoot, libs = [] } = params;
4115
+ const registry = parsedRegistry();
4116
+ parseIntoRegistry(weslSrc, registry, "package", debugWeslRoot);
4117
+ parseLibsIntoRegistry(libs, registry);
4118
+ return new LinkedWesl(linkRegistry({ registry, ...params }));
4119
+ }
4120
+ function linkRegistry(params) {
4121
+ const bound = bindAndTransform(params);
4122
+ const { transformedAst, newDecls, newStatements } = bound;
4123
+ return SrcMapBuilder.build(
4124
+ emitWgsl(
4125
+ transformedAst.moduleElem,
4126
+ transformedAst.srcModule,
4127
+ newDecls,
4128
+ newStatements,
4129
+ params.conditions
4130
+ )
4131
+ );
4132
+ }
4133
+ function bindAndTransform(params) {
4134
+ const { registry, mangler } = params;
4135
+ const { rootModuleName = "main", conditions = {} } = params;
4136
+ const rootAst = getRootModule(registry, rootModuleName);
4137
+ const { constants, config } = params;
4138
+ let { virtualLibs } = params;
4139
+ if (constants) {
4140
+ virtualLibs = { ...virtualLibs, constants: constantsGenerator(constants) };
4141
+ }
4142
+ let virtuals = virtualLibs && mapValues(virtualLibs, (fn2) => ({ fn: fn2 }));
4143
+ const bindParams = { rootAst, registry, conditions, virtuals, mangler };
4144
+ const bindResults = bindIdents(bindParams);
4145
+ const { globalNames, decls: newDecls, newStatements } = bindResults;
4146
+ const transformedAst = applyTransformPlugins(rootAst, globalNames, config);
4147
+ return { transformedAst, newDecls, newStatements };
4148
+ }
4149
+ function constantsGenerator(constants) {
4150
+ return () => Object.entries(constants).map(([name2, value]) => `const ${name2} = ${value};`).join("\n");
4151
+ }
4152
+ function getRootModule(parsed, rootModuleName) {
4153
+ const rootModule = selectModule(parsed, rootModuleName);
4154
+ if (!rootModule) {
4155
+ throw new Error(`Root module not found: ${rootModuleName}`);
4156
+ }
4157
+ return rootModule;
4158
+ }
4159
+ function applyTransformPlugins(rootModule, globalNames, config) {
4160
+ const { moduleElem, srcModule } = rootModule;
4161
+ const startAst = { moduleElem, srcModule, globalNames, notableElems: {} };
4162
+ const plugins = (config == null ? void 0 : config.plugins) ?? [];
4163
+ const transforms = filterMap(plugins, (plugin) => plugin.transform);
4164
+ const transformedAst = transforms.reduce(
4165
+ (ast, transform) => transform(ast),
4166
+ startAst
4167
+ );
4168
+ return transformedAst;
4169
+ }
4170
+ function emitWgsl(rootModuleElem, srcModule, newDecls, newStatements, conditions = {}) {
4171
+ const prologueBuilders = newStatements.map((s) => {
4172
+ const { elem, srcModule: srcModule2 } = s;
4173
+ const { src: text2, debugFilePath: path } = srcModule2;
4174
+ const builder = new SrcMapBuilder({ text: text2, path });
4175
+ lowerAndEmit(builder, [elem], conditions);
4176
+ builder.addNl();
4177
+ return builder;
4178
+ });
4179
+ const rootBuilder = new SrcMapBuilder({
4180
+ text: srcModule.src,
4181
+ path: srcModule.debugFilePath
4182
+ });
4183
+ lowerAndEmit(rootBuilder, [rootModuleElem], conditions, false);
4184
+ const declBuilders = newDecls.map((decl) => {
4185
+ const builder = new SrcMapBuilder({
4186
+ text: decl.srcModule.src,
4187
+ path: decl.srcModule.debugFilePath
4188
+ });
4189
+ lowerAndEmit(builder, [decl.declElem], conditions);
4190
+ return builder;
4191
+ });
4192
+ return [...prologueBuilders, rootBuilder, ...declBuilders];
4193
+ }
4194
+ function visitAst(elem, visitor) {
4195
+ visitor(elem);
4196
+ if (elem.contents) {
4197
+ const container = elem;
4198
+ container.contents.forEach((child) => visitAst(child, visitor));
4199
+ }
4200
+ }
4201
+ function attributeToString(e) {
4202
+ const { kind: kind2 } = e.attribute;
4203
+ if (kind2 === "@attribute") {
4204
+ const { params } = e.attribute;
4205
+ if (params === void 0 || params.length === 0) {
4206
+ return "@" + e.attribute.name;
4207
+ } else {
4208
+ return `@${e.attribute.name}(${params.map((param) => contentsToString(param)).join(", ")})`;
4209
+ }
4210
+ } else if (kind2 === "@builtin") {
4211
+ return "@builtin(" + e.attribute.param.name + ")";
4212
+ } else if (kind2 === "@diagnostic") {
4213
+ return "@diagnostic" + diagnosticControlToString(e.attribute.severity, e.attribute.rule);
4214
+ } else if (kind2 === "@if") {
4215
+ return `@if(${expressionToString(e.attribute.param.expression)})`;
4216
+ } else if (kind2 === "@interpolate") {
4217
+ return `@interpolate(${e.attribute.params.map((v) => v.name).join(", ")})`;
4218
+ } else {
4219
+ assertUnreachable(kind2);
4220
+ }
4221
+ }
4222
+ function typeListToString(params) {
4223
+ return `<${params.map(typeParamToString).join(", ")}>`;
4224
+ }
4225
+ function typeParamToString(param) {
4226
+ if (param === void 0) return "?";
4227
+ if (typeof param === "string") return param;
4228
+ if (param.kind === "expression") return contentsToString(param);
4229
+ if (param.kind === "type") return typeRefToString(param);
4230
+ assertUnreachable(param);
4231
+ }
4232
+ function typeRefToString(t) {
4233
+ if (!t) return "?";
4234
+ const { name: name2, templateParams } = t;
4235
+ const params = templateParams ? typeListToString(templateParams) : "";
4236
+ return `${refToString(name2)}${params}`;
4237
+ }
4238
+ function refToString(ref) {
4239
+ if (typeof ref === "string") return ref;
4240
+ if (ref.std) return ref.originalName;
4241
+ const decl = findDecl(ref);
4242
+ return decl.mangledName || decl.originalName;
4243
+ }
4244
+ function contentsToString(elem) {
4245
+ if (elem.kind === "translate-time-expression") {
4246
+ throw new Error("Not supported");
4247
+ } else if (elem.kind === "expression" || elem.kind === "stuff") {
4248
+ const parts = elem.contents.map((c) => {
4249
+ const { kind: kind2 } = c;
4250
+ if (kind2 === "text") {
4251
+ return c.srcModule.src.slice(c.start, c.end);
4252
+ } else if (kind2 === "ref") {
4253
+ return refToString(c.ident);
4254
+ } else {
4255
+ return `?${c.kind}?`;
4256
+ }
4257
+ });
4258
+ return parts.join(" ");
4259
+ } else if (elem.kind === "name") {
4260
+ return elem.name;
4261
+ } else {
4262
+ assertUnreachable(elem);
4263
+ }
4264
+ }
4265
+ const textureStorage = matchOneOf(textureStorageTypes);
4266
+ matchOneOf(sampledTextureTypes);
4267
+ matchOneOf(multisampledTextureTypes);
4268
+ function bindingStructsPlugin() {
4269
+ return {
4270
+ transform: lowerBindingStructs
4271
+ };
4272
+ }
4273
+ function lowerBindingStructs(ast) {
4274
+ const clonedAst = structuredClone(ast);
4275
+ const { moduleElem, globalNames, notableElems } = clonedAst;
4276
+ const bindingStructs = markBindingStructs(moduleElem);
4277
+ markEntryTypes(moduleElem, bindingStructs);
4278
+ const newVars = bindingStructs.flatMap(
4279
+ (s) => transformBindingStruct(s, globalNames)
4280
+ );
4281
+ const bindingRefs = findRefsToBindingStructs(moduleElem);
4282
+ bindingRefs.forEach(
4283
+ ({ memberRef, struct }) => transformBindingReference(memberRef, struct)
4284
+ );
4285
+ bindingRefs.forEach(
4286
+ ({ intermediates }) => intermediates.forEach((e) => e.contents = [])
4287
+ );
4288
+ const contents = removeBindingStructs(moduleElem);
4289
+ moduleElem.contents = [...newVars, ...contents];
4290
+ notableElems.bindingStructs = bindingStructs;
4291
+ return { ...clonedAst, moduleElem };
4292
+ }
4293
+ function markEntryTypes(moduleElem, bindingStructs) {
4294
+ const fns = moduleElem.contents.filter((e) => e.kind === "fn");
4295
+ const fnFound = fnReferencesBindingStruct(fns, bindingStructs);
4296
+ if (fnFound) {
4297
+ const { fn: fn2, struct } = fnFound;
4298
+ struct.entryFn = fn2;
4299
+ }
4300
+ }
4301
+ function fnReferencesBindingStruct(fns, bindingStructs) {
4302
+ var _a, _b, _c;
4303
+ for (const fn2 of fns) {
4304
+ const { params } = fn2;
4305
+ for (const p of params) {
4306
+ const ref = (_b = (_a = p.name) == null ? void 0 : _a.typeRef) == null ? void 0 : _b.name;
4307
+ const referencedElem = (_c = ref == null ? void 0 : ref.refersTo) == null ? void 0 : _c.declElem;
4308
+ const struct = bindingStructs.find((s) => s === referencedElem);
4309
+ if (struct) {
4310
+ return { fn: fn2, struct };
4311
+ }
4312
+ }
4313
+ }
4314
+ }
4315
+ function removeBindingStructs(moduleElem) {
4316
+ return moduleElem.contents.filter(
4317
+ (elem) => elem.kind !== "struct" || !elem.bindingStruct
4318
+ );
4319
+ }
4320
+ function markBindingStructs(moduleElem) {
4321
+ const structs = moduleElem.contents.filter((elem) => elem.kind === "struct");
4322
+ const bindingStructs = structs.filter(containsBinding);
4323
+ bindingStructs.forEach((struct) => struct.bindingStruct = true);
4324
+ return bindingStructs;
4325
+ }
4326
+ function containsBinding(struct) {
4327
+ return struct.members.some(({ attributes }) => bindingAttribute(attributes));
4328
+ }
4329
+ function bindingAttribute(attributes) {
4330
+ if (!attributes) return false;
4331
+ return attributes.some(
4332
+ ({ attribute }) => attribute.kind === "@attribute" && (attribute.name === "binding" || attribute.name === "group")
4333
+ );
4334
+ }
4335
+ function transformBindingStruct(s, globalNames) {
4336
+ return s.members.map((member) => {
4337
+ var _a;
4338
+ const { typeRef, name: memberName } = member;
4339
+ const { name: typeName } = typeRef;
4340
+ const typeParameters = typeRef == null ? void 0 : typeRef.templateParams;
4341
+ const varName = minimallyMangledName(memberName.name, globalNames);
4342
+ member.mangledVarName = varName;
4343
+ globalNames.add(varName);
4344
+ const attributes = ((_a = member.attributes) == null ? void 0 : _a.map(attributeToString).join(" ")) ?? "";
4345
+ const varTypes = lowerPtrMember(member, typeName, typeParameters) ?? lowerStdTypeMember(typeName, typeParameters) ?? lowerStorageTextureMember(typeName, typeParameters);
4346
+ if (!varTypes) {
4347
+ console.log("unhandled case transforming member", typeName);
4348
+ return syntheticVar(attributes, varName, "", "??");
4349
+ }
4350
+ const { storage: storageType, varType } = varTypes;
4351
+ return syntheticVar(attributes, varName, storageType, varType);
4352
+ });
4353
+ }
4354
+ function lowerPtrMember(member, typeName, typeParameters, varName) {
4355
+ if (typeName.originalName === "ptr") {
4356
+ const origParams = typeParameters ?? [];
4357
+ const newParams = [origParams[0]];
4358
+ if (origParams[2]) newParams.push(origParams[2]);
4359
+ const storage = typeListToString(newParams);
4360
+ const varType = typeParamToString(origParams == null ? void 0 : origParams[1]);
4361
+ return { storage, varType };
4362
+ }
4363
+ }
4364
+ function lowerStdTypeMember(typeName, typeParameters) {
4365
+ if (typeof typeName !== "string") {
4366
+ const varBaseType = typeName.std ? typeName.originalName : "??";
4367
+ const params = typeParameters ? typeListToString(typeParameters) : "";
4368
+ const varType = varBaseType + params;
4369
+ return { varType, storage: "" };
4370
+ }
4371
+ }
4372
+ function lowerStorageTextureMember(typeName, typeParameters) {
4373
+ if (textureStorage.test(typeName.originalName)) {
4374
+ const params = typeParameters ? typeListToString(typeParameters) : "";
4375
+ const varType = typeName + params;
4376
+ return { varType, storage: "" };
4377
+ }
4378
+ }
4379
+ function syntheticVar(attributes, varName, storageTemplate, varType) {
4380
+ const varText = `${attributes} var${storageTemplate} ${varName} : ${varType};
4381
+ `;
4382
+ const elem = {
4383
+ kind: "synthetic",
4384
+ text: varText
4385
+ };
4386
+ return elem;
4387
+ }
4388
+ function findRefsToBindingStructs(moduleElem) {
4389
+ const members = [];
4390
+ visitAst(moduleElem, (elem) => {
4391
+ if (elem.kind === "memberRef") members.push(elem);
4392
+ });
4393
+ return filterMap(members, refersToBindingStruct);
4394
+ }
4395
+ function refersToBindingStruct(memberRef) {
4396
+ const found = traceToStruct(memberRef.name.ident);
4397
+ if (found && found.struct.bindingStruct) {
4398
+ return { memberRef, ...found };
4399
+ }
4400
+ }
4401
+ function traceToStruct(ident2) {
4402
+ const decl = findDecl(ident2);
4403
+ const declElem = decl.declElem;
4404
+ if (declElem && declElem.kind === "param") {
4405
+ const name2 = declElem.name.typeRef.name;
4406
+ if (typeof name2 !== "string") {
4407
+ if (name2.std) {
4408
+ return void 0;
4409
+ }
4410
+ const paramDecl = findDecl(name2);
4411
+ const structElem = paramDecl.declElem;
4412
+ if ((structElem == null ? void 0 : structElem.kind) === "struct") {
4413
+ return { struct: structElem, intermediates: [declElem] };
4414
+ }
4415
+ return void 0;
4416
+ }
4417
+ }
4418
+ }
4419
+ function transformBindingReference(memberRef, struct) {
4420
+ const refName = memberRef.member.name;
4421
+ const structMember = struct.members.find((m) => m.name.name === refName);
4422
+ if (!structMember || !structMember.mangledVarName) {
4423
+ return { kind: "synthetic", text: refName };
4424
+ }
4425
+ const { extraComponents } = memberRef;
4426
+ const extraText = extraComponents ? contentsToString(extraComponents) : "";
4427
+ const text2 = structMember.mangledVarName + extraText;
4428
+ const synthElem = { kind: "synthetic", text: text2 };
4429
+ memberRef.contents = [synthElem];
4430
+ return synthElem;
4431
+ }
4432
+ export {
4433
+ LinkedWesl,
4434
+ WeslParseError,
4435
+ WeslStream,
4436
+ astToString,
4437
+ attributeToString$1 as attributeToString,
4438
+ bindAndTransform,
4439
+ bindingStructsPlugin,
4440
+ blankWeslParseState,
4441
+ debugContentsToString,
4442
+ findRefsToBindingStructs,
4443
+ flatImports,
4444
+ identToString,
4445
+ link,
4446
+ linkRegistry,
4447
+ lowerBindingStructs,
4448
+ makeWeslDevice,
4449
+ markBindingStructs,
4450
+ markEntryTypes,
4451
+ noSuffix,
4452
+ normalize,
4453
+ parseIntoRegistry,
4454
+ parseLibsIntoRegistry,
4455
+ parseSrcModule,
4456
+ parseWESL,
4457
+ parseWeslSrc,
4458
+ parsedRegistry,
4459
+ registryToString,
4460
+ scopeToString,
4461
+ scopeToStringLong,
4462
+ selectModule,
4463
+ syntheticWeslParseState,
4464
+ throwClickableError,
4465
+ transformBindingReference,
4466
+ transformBindingStruct
4467
+ };
4468
+ //# sourceMappingURL=index.js.map