wesl 0.7.27 → 0.7.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +272 -126
- package/dist/index.js +1742 -1102
- package/package.json +1 -1
- package/src/AbstractElems.ts +263 -81
- package/src/Linker.ts +14 -2
- package/src/LinkerUtil.ts +141 -7
- package/src/LowerAndEmit.ts +660 -304
- package/src/ModuleResolver.ts +15 -4
- package/src/ParseWESL.ts +21 -33
- package/src/SrcMap.ts +7 -19
- package/src/debug/ASTtoString.ts +92 -76
- package/src/index.ts +1 -1
- package/src/parse/AttachComments.ts +289 -0
- package/src/parse/ExpressionUtil.ts +3 -3
- package/src/parse/ParseAttribute.ts +49 -71
- package/src/parse/ParseCall.ts +3 -4
- package/src/parse/ParseControlFlow.ts +100 -56
- package/src/parse/ParseDirective.ts +9 -8
- package/src/parse/ParseDoBlock.ts +63 -0
- package/src/parse/ParseExpression.ts +11 -10
- package/src/parse/ParseFn.ts +11 -33
- package/src/parse/ParseGlobalVar.ts +36 -27
- package/src/parse/ParseIdent.ts +4 -5
- package/src/parse/ParseLocalVar.ts +16 -12
- package/src/parse/ParseLoop.ts +76 -39
- package/src/parse/ParseModule.ts +65 -19
- package/src/parse/ParseSimpleStatement.ts +112 -66
- package/src/parse/ParseStatement.ts +39 -66
- package/src/parse/ParseStruct.ts +8 -22
- package/src/parse/ParseType.ts +10 -13
- package/src/parse/ParseUtil.ts +26 -12
- package/src/parse/ParseValueDeclaration.ts +18 -31
- package/src/parse/ParseWesl.ts +11 -14
- package/src/parse/ParsingContext.ts +11 -9
- package/src/parse/WeslStream.ts +138 -121
- package/src/parse/stream/RegexMatchers.ts +45 -0
- package/src/parse/stream/WeslLexer.ts +249 -0
- package/src/test/BevyLink.test.ts +17 -10
- package/src/test/ConditionalElif.test.ts +4 -2
- package/src/test/DeclCommentEmit.test.ts +122 -0
- package/src/test/DoBlock.test.ts +164 -0
- package/src/test/FilterValidElements.test.ts +4 -6
- package/src/test/Linker.test.ts +23 -7
- package/src/test/Mangling.test.ts +8 -4
- package/src/test/ParseComments.test.ts +234 -6
- package/src/test/ParseConditionsV2.test.ts +47 -175
- package/src/test/ParseElifV2.test.ts +12 -33
- package/src/test/ParseErrorV2.test.ts +0 -0
- package/src/test/ParseWeslV2.test.ts +247 -626
- package/src/test/StatementEmit.test.ts +143 -0
- package/src/test/StripWesl.ts +24 -3
- package/src/test/TestLink.ts +19 -3
- package/src/test/TestUtil.ts +18 -8
- package/src/test/Tokenizer.test.ts +96 -0
- package/src/test/__snapshots__/ParseWeslV2.test.ts.snap +10 -42
- package/src/RawEmit.ts +0 -103
- package/src/Reflection.ts +0 -336
- package/src/TransformBindingStructs.ts +0 -320
- package/src/parse/ContentsHelpers.ts +0 -70
- package/src/parse/stream/CachingStream.ts +0 -48
- package/src/parse/stream/MatchersStream.ts +0 -85
package/src/LinkerUtil.ts
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AbstractElem,
|
|
3
|
-
ContainerElem,
|
|
4
3
|
DeclIdentElem,
|
|
4
|
+
ExpressionElem,
|
|
5
|
+
HasAttributes,
|
|
6
|
+
ModuleElem,
|
|
5
7
|
RefIdentElem,
|
|
6
8
|
} from "./AbstractElems.ts";
|
|
9
|
+
import { assertUnreachableSilent } from "./Assertions.ts";
|
|
7
10
|
import { srcLog } from "./Logging.ts";
|
|
8
11
|
|
|
12
|
+
/** A module's top-level declarations of a given kind, narrowed to that elem type. */
|
|
13
|
+
export function declsOfKind<K extends AbstractElem["kind"]>(
|
|
14
|
+
moduleElem: ModuleElem,
|
|
15
|
+
kind: K,
|
|
16
|
+
): Extract<AbstractElem, { kind: K }>[] {
|
|
17
|
+
return moduleElem.decls.filter(
|
|
18
|
+
(e): e is Extract<AbstractElem, { kind: K }> => e.kind === kind,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Visit an elem and all its descendants, parent before children (pre-order). */
|
|
9
23
|
export function visitAst(
|
|
10
24
|
elem: AbstractElem,
|
|
11
25
|
visitor: (elem: AbstractElem) => void,
|
|
12
26
|
) {
|
|
13
27
|
visitor(elem);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
for (const child of childElems(elem)) visitAst(child, visitor);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Child elems of any AST node: the typed structural fields (attributes plus
|
|
33
|
+
* body / condition / decls / ...) in source order. Returns [] for leaf elems.
|
|
34
|
+
*/
|
|
35
|
+
export function childElems(elem: AbstractElem): readonly AbstractElem[] {
|
|
36
|
+
const attributes = (elem as HasAttributes).attributes ?? [];
|
|
37
|
+
return [...attributes, ...structuralFields(elem)];
|
|
20
38
|
}
|
|
21
39
|
|
|
22
40
|
export function identElemLog(
|
|
@@ -29,3 +47,119 @@ export function identElemLog(
|
|
|
29
47
|
...messages,
|
|
30
48
|
);
|
|
31
49
|
}
|
|
50
|
+
|
|
51
|
+
/** The child elems held in a node's typed fields, in source order (attributes
|
|
52
|
+
* are added separately by {@link childElems}). Empty for leaf kinds. The
|
|
53
|
+
* switch is exhaustive: a new elem kind without a case fails to compile in the
|
|
54
|
+
* default, so children can't be silently dropped. */
|
|
55
|
+
function structuralFields(elem: AbstractElem): AbstractElem[] {
|
|
56
|
+
switch (elem.kind) {
|
|
57
|
+
case "module":
|
|
58
|
+
return elem.decls;
|
|
59
|
+
case "var":
|
|
60
|
+
case "gvar":
|
|
61
|
+
return [
|
|
62
|
+
...(elem.template ?? []),
|
|
63
|
+
elem.name,
|
|
64
|
+
...(elem.init ? [elem.init] : []),
|
|
65
|
+
];
|
|
66
|
+
case "let":
|
|
67
|
+
case "const":
|
|
68
|
+
case "override":
|
|
69
|
+
return [elem.name, ...(elem.init ? [elem.init] : [])];
|
|
70
|
+
case "alias":
|
|
71
|
+
return [elem.name, elem.typeRef];
|
|
72
|
+
case "assert":
|
|
73
|
+
return [elem.expression];
|
|
74
|
+
case "struct":
|
|
75
|
+
return [elem.name, ...elem.members];
|
|
76
|
+
case "member":
|
|
77
|
+
return [elem.name, elem.typeRef];
|
|
78
|
+
case "type":
|
|
79
|
+
return [elem.name.refIdentElem, ...(elem.templateParams ?? [])];
|
|
80
|
+
case "expression":
|
|
81
|
+
return [elem.expression];
|
|
82
|
+
case "binary-expression":
|
|
83
|
+
return [elem.left, elem.right];
|
|
84
|
+
case "unary-expression":
|
|
85
|
+
case "parenthesized-expression":
|
|
86
|
+
return [elem.expression];
|
|
87
|
+
case "component-expression":
|
|
88
|
+
return [elem.base, elem.access];
|
|
89
|
+
case "component-member-expression":
|
|
90
|
+
return [elem.base, elem.access];
|
|
91
|
+
case "call-expression":
|
|
92
|
+
return [elem.function, ...(elem.templateArgs ?? []), ...elem.arguments];
|
|
93
|
+
case "param":
|
|
94
|
+
return [elem.name];
|
|
95
|
+
case "typeDecl":
|
|
96
|
+
return elem.typeRef ? [elem.decl, elem.typeRef] : [elem.decl];
|
|
97
|
+
case "fn":
|
|
98
|
+
return [
|
|
99
|
+
elem.name,
|
|
100
|
+
...elem.params,
|
|
101
|
+
...(elem.returnType ? [elem.returnType] : []),
|
|
102
|
+
elem.body,
|
|
103
|
+
];
|
|
104
|
+
case "block":
|
|
105
|
+
return elem.body;
|
|
106
|
+
case "if":
|
|
107
|
+
return [elem.condition, elem.body, ...(elem.else ? [elem.else] : [])];
|
|
108
|
+
case "for":
|
|
109
|
+
return [elem.init, elem.condition, elem.update, elem.body].filter(
|
|
110
|
+
isDefined,
|
|
111
|
+
);
|
|
112
|
+
case "while":
|
|
113
|
+
return [elem.condition, elem.body];
|
|
114
|
+
case "loop":
|
|
115
|
+
case "continuing":
|
|
116
|
+
return [elem.body];
|
|
117
|
+
case "switch":
|
|
118
|
+
return [elem.selector, ...(elem.bodyAttributes ?? []), ...elem.clauses];
|
|
119
|
+
case "switch-clause":
|
|
120
|
+
return [...exprSelectors(elem.selectors), elem.body];
|
|
121
|
+
case "return":
|
|
122
|
+
return elem.value ? [elem.value] : [];
|
|
123
|
+
case "break":
|
|
124
|
+
return elem.condition ? [elem.condition] : [];
|
|
125
|
+
case "assign":
|
|
126
|
+
return elem.lhs.kind === "phony" ? [elem.rhs] : [elem.lhs, elem.rhs];
|
|
127
|
+
case "increment":
|
|
128
|
+
case "decrement":
|
|
129
|
+
return [elem.target];
|
|
130
|
+
case "call":
|
|
131
|
+
return [elem.call];
|
|
132
|
+
case "continue":
|
|
133
|
+
case "discard":
|
|
134
|
+
case "empty":
|
|
135
|
+
return [];
|
|
136
|
+
case "do":
|
|
137
|
+
return [elem.name, ...elem.params, elem.body];
|
|
138
|
+
// import/directive hold no child elems in typed fields (their payload isn't
|
|
139
|
+
// an AbstractElem), but they carry attributes that childElems prepends.
|
|
140
|
+
case "import":
|
|
141
|
+
case "directive":
|
|
142
|
+
// leaf kinds: no child elems and no attributes.
|
|
143
|
+
case "attribute":
|
|
144
|
+
case "name":
|
|
145
|
+
case "literal":
|
|
146
|
+
case "ref":
|
|
147
|
+
case "decl":
|
|
148
|
+
case "synthetic":
|
|
149
|
+
return [];
|
|
150
|
+
default:
|
|
151
|
+
assertUnreachableSilent(elem);
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function isDefined<T>(value: T | undefined): value is T {
|
|
157
|
+
return value !== undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Drop the `"default"` sentinel, keeping only real case-selector expressions. */
|
|
161
|
+
function exprSelectors(
|
|
162
|
+
selectors: (ExpressionElem | "default")[],
|
|
163
|
+
): ExpressionElem[] {
|
|
164
|
+
return selectors.filter((s): s is ExpressionElem => s !== "default");
|
|
165
|
+
}
|