wesl 0.6.49 → 0.7.1
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 +269 -215
- package/dist/index.js +2911 -1539
- package/package.json +6 -8
- package/src/AbstractElems.ts +81 -81
- package/src/Assertions.ts +5 -5
- package/src/BindIdents.ts +192 -306
- package/src/ClickableError.ts +3 -2
- package/src/Conditions.ts +2 -2
- package/src/LinkedWesl.ts +1 -1
- package/src/Linker.ts +4 -3
- package/src/LinkerUtil.ts +1 -1
- package/src/Logging.ts +165 -0
- package/src/LowerAndEmit.ts +278 -110
- package/src/ModuleResolver.ts +15 -25
- package/src/ParseError.ts +9 -0
- package/src/ParseWESL.ts +30 -94
- package/src/RawEmit.ts +1 -4
- package/src/Reflection.ts +1 -1
- package/src/Scope.ts +3 -0
- package/src/Span.ts +2 -0
- package/src/SrcMap.ts +208 -0
- package/src/Stream.ts +30 -0
- package/src/TransformBindingStructs.ts +2 -2
- package/src/Util.ts +1 -1
- package/src/debug/ASTtoString.ts +84 -135
- package/src/discovery/FindUnboundIdents.ts +14 -5
- package/src/index.ts +4 -0
- package/src/parse/ContentsHelpers.ts +70 -0
- package/src/parse/ExpressionUtil.ts +121 -0
- package/src/parse/Keywords.ts +12 -12
- package/src/parse/OperatorBinding.ts +146 -0
- package/src/parse/ParseAttribute.ts +272 -0
- package/src/parse/ParseCall.ts +77 -0
- package/src/parse/ParseControlFlow.ts +129 -0
- package/src/parse/ParseDirective.ts +105 -0
- package/src/parse/ParseExpression.ts +288 -0
- package/src/parse/ParseFn.ts +151 -0
- package/src/parse/ParseGlobalVar.ts +131 -0
- package/src/parse/ParseIdent.ts +77 -0
- package/src/parse/ParseImport.ts +160 -0
- package/src/parse/ParseLocalVar.ts +69 -0
- package/src/parse/ParseLoop.ts +112 -0
- package/src/parse/ParseModule.ts +116 -0
- package/src/parse/ParseSimpleStatement.ts +162 -0
- package/src/parse/ParseStatement.ts +215 -0
- package/src/parse/ParseStruct.ts +89 -0
- package/src/parse/ParseType.ts +71 -0
- package/src/parse/ParseUtil.ts +174 -0
- package/src/parse/ParseValueDeclaration.ts +130 -0
- package/src/parse/ParseWesl.ts +51 -0
- package/src/parse/ParsingContext.ts +93 -0
- package/src/parse/WeslStream.ts +63 -20
- package/src/parse/stream/CachingStream.ts +48 -0
- package/src/parse/stream/MatchersStream.ts +85 -0
- package/src/parse/stream/RegexHelpers.ts +38 -0
- package/src/test/BevyLink.test.ts +100 -0
- package/src/test/BindStdTypes.test.ts +110 -0
- package/src/test/{BindWESL.test.ts → BindWESLV2.test.ts} +21 -22
- package/src/test/BulkTests.test.ts +11 -12
- package/src/test/ConditionLinking.test.ts +107 -0
- package/src/test/ConditionalElif.test.ts +1 -13
- package/src/test/ConditionalTranslationCases.test.ts +5 -0
- package/src/test/ErrorLogging.test.ts +2 -2
- package/src/test/ImportCasesV2.test.ts +63 -0
- package/src/test/LinkFails.test.ts +69 -0
- package/src/test/LinkPackage.test.ts +1 -1
- package/src/test/Linker.test.ts +75 -2
- package/src/test/LogCatcher.ts +53 -0
- package/src/test/Mangling.test.ts +1 -1
- package/src/test/ParseComments.test.ts +1 -2
- package/src/test/{ParseConditions.test.ts → ParseConditionsV2.test.ts} +57 -49
- package/src/test/ParseErrorV2.test.ts +73 -0
- package/src/test/{ParseWESL.test.ts → ParseWeslV2.test.ts} +288 -370
- package/src/test/{ScopeWESL.test.ts → ScopeWESLV2.test.ts} +205 -176
- package/src/test/TestLink.ts +51 -51
- package/src/test/TestSetup.ts +9 -3
- package/src/test/TestUtil.ts +47 -77
- package/src/test/TrimmedMatch.ts +40 -0
- package/src/test/VirtualModules.test.ts +33 -2
- package/src/test/WeslDevice.test.ts +9 -2
- package/src/test/__snapshots__/ParseWeslV2.test.ts.snap +67 -0
- package/src/test-util.ts +7 -0
- package/src/WESLCollect.ts +0 -656
- package/src/parse/AttributeGrammar.ts +0 -232
- package/src/parse/ImportGrammar.ts +0 -195
- package/src/parse/WeslBaseGrammar.ts +0 -11
- package/src/parse/WeslExpression.ts +0 -231
- package/src/parse/WeslGrammar.ts +0 -739
- package/src/test/Expression.test.ts +0 -22
- package/src/test/ImportSyntaxCases.test.ts +0 -24
- package/src/test/ParseError.test.ts +0 -45
- package/src/test/Reflection.test.ts +0 -176
- package/src/test/TransformBindingStructs.test.ts +0 -238
- /package/src/test/{ParseElif.test.ts → ParseElifV2.test.ts} +0 -0
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
delimited,
|
|
3
|
-
fn,
|
|
4
|
-
opt,
|
|
5
|
-
or,
|
|
6
|
-
type Parser,
|
|
7
|
-
preceded,
|
|
8
|
-
repeatPlus,
|
|
9
|
-
req,
|
|
10
|
-
type Span,
|
|
11
|
-
type Stream,
|
|
12
|
-
seq,
|
|
13
|
-
span,
|
|
14
|
-
tagScope,
|
|
15
|
-
token,
|
|
16
|
-
tokenKind,
|
|
17
|
-
tokenOf,
|
|
18
|
-
yes,
|
|
19
|
-
} from "mini-parse";
|
|
20
|
-
import type {
|
|
21
|
-
BinaryExpression,
|
|
22
|
-
BinaryOperator,
|
|
23
|
-
ElifAttribute,
|
|
24
|
-
ElseAttribute,
|
|
25
|
-
ExpressionElem,
|
|
26
|
-
IfAttribute,
|
|
27
|
-
Literal,
|
|
28
|
-
ParenthesizedExpression,
|
|
29
|
-
TranslateTimeExpressionElem,
|
|
30
|
-
TranslateTimeFeature,
|
|
31
|
-
UnaryExpression,
|
|
32
|
-
UnaryOperator,
|
|
33
|
-
} from "../AbstractElems.ts";
|
|
34
|
-
import { specialAttribute } from "../WESLCollect.ts";
|
|
35
|
-
import type { WeslToken } from "./WeslStream.ts";
|
|
36
|
-
import { weslExtension } from "./WeslStream.ts";
|
|
37
|
-
|
|
38
|
-
// Expression parsers for @if conditions - supports literals (true/false),
|
|
39
|
-
// parenthesized expressions, translate-time features, and binary operators (&&, ||)
|
|
40
|
-
const attribute_if_primary_expression: Parser<
|
|
41
|
-
Stream<WeslToken>,
|
|
42
|
-
Literal | ParenthesizedExpression | TranslateTimeFeature
|
|
43
|
-
> = or(
|
|
44
|
-
tokenOf("keyword", ["true", "false"]).map(makeLiteral),
|
|
45
|
-
delimited(
|
|
46
|
-
token("symbol", "("),
|
|
47
|
-
fn(() => attribute_if_expression),
|
|
48
|
-
token("symbol", ")"),
|
|
49
|
-
).map(makeParenthesizedExpression),
|
|
50
|
-
tokenKind("word").map(makeTranslateTimeFeature),
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const attribute_if_unary_expression: Parser<
|
|
54
|
-
Stream<WeslToken>,
|
|
55
|
-
ExpressionElem
|
|
56
|
-
> = or(
|
|
57
|
-
seq(
|
|
58
|
-
token("symbol", "!").map(makeUnaryOperator),
|
|
59
|
-
fn(() => attribute_if_unary_expression),
|
|
60
|
-
).map(makeUnaryExpression),
|
|
61
|
-
attribute_if_primary_expression,
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const attribute_if_expression: Parser<
|
|
65
|
-
Stream<WeslToken>,
|
|
66
|
-
ExpressionElem
|
|
67
|
-
> = weslExtension(
|
|
68
|
-
seq(
|
|
69
|
-
attribute_if_unary_expression,
|
|
70
|
-
or(
|
|
71
|
-
repeatPlus(
|
|
72
|
-
seq(
|
|
73
|
-
token("symbol", "||").map(makeBinaryOperator),
|
|
74
|
-
req(
|
|
75
|
-
attribute_if_unary_expression,
|
|
76
|
-
"invalid expression, expected expression",
|
|
77
|
-
),
|
|
78
|
-
),
|
|
79
|
-
),
|
|
80
|
-
repeatPlus(
|
|
81
|
-
seq(
|
|
82
|
-
token("symbol", "&&").map(makeBinaryOperator),
|
|
83
|
-
req(
|
|
84
|
-
attribute_if_unary_expression,
|
|
85
|
-
"invalid expression, expected expression",
|
|
86
|
-
),
|
|
87
|
-
),
|
|
88
|
-
),
|
|
89
|
-
yes().map(() => []),
|
|
90
|
-
),
|
|
91
|
-
).map(makeRepeatingBinaryExpression),
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
/** Base parser for @if attributes without collection - use in seq() compositions */
|
|
95
|
-
// prettier-ignore
|
|
96
|
-
export const if_attribute_base = preceded(
|
|
97
|
-
seq("@", weslExtension("if")),
|
|
98
|
-
span(
|
|
99
|
-
delimited(
|
|
100
|
-
"(",
|
|
101
|
-
fn(() => attribute_if_expression),
|
|
102
|
-
seq(opt(","), ")"),
|
|
103
|
-
),
|
|
104
|
-
).map(makeTranslateTimeExpressionElem),
|
|
105
|
-
)
|
|
106
|
-
.map(makeIfAttribute)
|
|
107
|
-
.ptag("attr_variant");
|
|
108
|
-
|
|
109
|
-
/** Base parser for @elif attributes without collection - use in seq() compositions */
|
|
110
|
-
// prettier-ignore
|
|
111
|
-
export const elif_attribute_base = preceded(
|
|
112
|
-
seq("@", weslExtension("elif")),
|
|
113
|
-
span(
|
|
114
|
-
delimited(
|
|
115
|
-
"(",
|
|
116
|
-
fn(() => attribute_if_expression),
|
|
117
|
-
seq(opt(","), ")"),
|
|
118
|
-
),
|
|
119
|
-
).map(makeTranslateTimeExpressionElem),
|
|
120
|
-
)
|
|
121
|
-
.map(makeElifAttribute)
|
|
122
|
-
.ptag("attr_variant");
|
|
123
|
-
|
|
124
|
-
/** Base parser for @else attributes without collection - use in seq() compositions */
|
|
125
|
-
// prettier-ignore
|
|
126
|
-
export const else_attribute_base = preceded(
|
|
127
|
-
seq("@", weslExtension("else")),
|
|
128
|
-
yes,
|
|
129
|
-
)
|
|
130
|
-
.map(makeElseAttribute)
|
|
131
|
-
.ptag("attr_variant");
|
|
132
|
-
|
|
133
|
-
/** Collected parser for @if attributes - use standalone, not in seq() */
|
|
134
|
-
// prettier-ignore
|
|
135
|
-
export const if_attribute = tagScope(
|
|
136
|
-
if_attribute_base.collect(specialAttribute),
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
/** Collected parser for @elif attributes - use standalone, not in seq() */
|
|
140
|
-
// prettier-ignore
|
|
141
|
-
export const elif_attribute = tagScope(
|
|
142
|
-
elif_attribute_base.collect(specialAttribute),
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
/** Collected parser for @else attributes - use standalone, not in seq() */
|
|
146
|
-
// prettier-ignore
|
|
147
|
-
export const else_attribute = tagScope(
|
|
148
|
-
else_attribute_base.collect(specialAttribute),
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
// Helper functions
|
|
152
|
-
function makeIfAttribute(param: TranslateTimeExpressionElem): IfAttribute {
|
|
153
|
-
return { kind: "@if", param };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function makeElifAttribute(param: TranslateTimeExpressionElem): ElifAttribute {
|
|
157
|
-
return { kind: "@elif", param };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function makeElseAttribute(): ElseAttribute {
|
|
161
|
-
return { kind: "@else" };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function makeTranslateTimeExpressionElem(args: {
|
|
165
|
-
value: ExpressionElem;
|
|
166
|
-
span: Span;
|
|
167
|
-
}): TranslateTimeExpressionElem {
|
|
168
|
-
return {
|
|
169
|
-
kind: "translate-time-expression",
|
|
170
|
-
expression: args.value,
|
|
171
|
-
span: args.span,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function makeLiteral(token: WeslToken<"keyword" | "number">): Literal {
|
|
176
|
-
return {
|
|
177
|
-
kind: "literal",
|
|
178
|
-
value: token.text,
|
|
179
|
-
span: token.span,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function makeTranslateTimeFeature(
|
|
184
|
-
token: WeslToken<"word">,
|
|
185
|
-
): TranslateTimeFeature {
|
|
186
|
-
return {
|
|
187
|
-
kind: "translate-time-feature",
|
|
188
|
-
name: token.text,
|
|
189
|
-
span: token.span,
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function makeParenthesizedExpression(
|
|
194
|
-
expression: ExpressionElem,
|
|
195
|
-
): ParenthesizedExpression {
|
|
196
|
-
return {
|
|
197
|
-
kind: "parenthesized-expression",
|
|
198
|
-
expression,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function makeUnaryOperator(token: WeslToken<"symbol">): UnaryOperator {
|
|
203
|
-
return { value: token.text as any, span: token.span };
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function makeBinaryOperator(token: WeslToken<"symbol">): BinaryOperator {
|
|
207
|
-
return { value: token.text as any, span: token.span };
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function makeUnaryExpression([operator, expression]: [
|
|
211
|
-
UnaryOperator,
|
|
212
|
-
ExpressionElem,
|
|
213
|
-
]): UnaryExpression {
|
|
214
|
-
return { kind: "unary-expression", operator, expression };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function makeRepeatingBinaryExpression([start, repeating]: [
|
|
218
|
-
ExpressionElem,
|
|
219
|
-
[BinaryOperator, ExpressionElem][],
|
|
220
|
-
]): ExpressionElem {
|
|
221
|
-
let result: ExpressionElem = start;
|
|
222
|
-
for (const [op, left] of repeating) {
|
|
223
|
-
const binaryExpression: BinaryExpression = {
|
|
224
|
-
kind: "binary-expression",
|
|
225
|
-
operator: op,
|
|
226
|
-
left: result,
|
|
227
|
-
right: left,
|
|
228
|
-
};
|
|
229
|
-
result = binaryExpression;
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
delimited,
|
|
3
|
-
fn,
|
|
4
|
-
not,
|
|
5
|
-
opt,
|
|
6
|
-
or,
|
|
7
|
-
type Parser,
|
|
8
|
-
preceded,
|
|
9
|
-
repeat,
|
|
10
|
-
repeatPlus,
|
|
11
|
-
req,
|
|
12
|
-
type Stream,
|
|
13
|
-
seq,
|
|
14
|
-
seqObj,
|
|
15
|
-
span,
|
|
16
|
-
tagScope,
|
|
17
|
-
terminated,
|
|
18
|
-
tracing,
|
|
19
|
-
withSepPlus,
|
|
20
|
-
yes,
|
|
21
|
-
} from "mini-parse";
|
|
22
|
-
import type {
|
|
23
|
-
AttributeElem,
|
|
24
|
-
ElifAttribute,
|
|
25
|
-
ElseAttribute,
|
|
26
|
-
IfAttribute,
|
|
27
|
-
ImportCollection,
|
|
28
|
-
ImportElem,
|
|
29
|
-
ImportItem,
|
|
30
|
-
ImportSegment,
|
|
31
|
-
ImportStatement,
|
|
32
|
-
} from "../AbstractElems.ts";
|
|
33
|
-
import { assertUnreachable } from "../Assertions.ts";
|
|
34
|
-
import { importElem } from "../WESLCollect.ts";
|
|
35
|
-
import {
|
|
36
|
-
elif_attribute_base,
|
|
37
|
-
else_attribute_base,
|
|
38
|
-
if_attribute_base,
|
|
39
|
-
} from "./AttributeGrammar.ts";
|
|
40
|
-
import { keyword, word } from "./WeslBaseGrammar.ts";
|
|
41
|
-
import type { WeslToken } from "./WeslStream.ts";
|
|
42
|
-
|
|
43
|
-
function makeStatement(
|
|
44
|
-
segments: ImportSegment[],
|
|
45
|
-
finalSegment: ImportCollection | ImportItem,
|
|
46
|
-
): ImportStatement {
|
|
47
|
-
return { kind: "import-statement", segments, finalSegment };
|
|
48
|
-
}
|
|
49
|
-
function makeSegment(name: string): ImportSegment {
|
|
50
|
-
return { kind: "import-segment", name };
|
|
51
|
-
}
|
|
52
|
-
function makeCollection(subtrees: ImportStatement[]): ImportCollection {
|
|
53
|
-
return {
|
|
54
|
-
kind: "import-collection",
|
|
55
|
-
subtrees,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function makeItem(name: string, as?: string): ImportItem {
|
|
59
|
-
return { kind: "import-item", name, as };
|
|
60
|
-
}
|
|
61
|
-
function prependSegments(
|
|
62
|
-
segments: ImportSegment[],
|
|
63
|
-
statement: ImportStatement,
|
|
64
|
-
): ImportStatement {
|
|
65
|
-
statement.segments = segments.concat(statement.segments);
|
|
66
|
-
return statement;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// forward references for mutual recursion
|
|
70
|
-
let import_collection: Parser<
|
|
71
|
-
Stream<WeslToken>,
|
|
72
|
-
ImportCollection
|
|
73
|
-
> = null as any;
|
|
74
|
-
|
|
75
|
-
const segment_blacklist = or("super", "package", "import", "as");
|
|
76
|
-
|
|
77
|
-
/** words allowed in an import segment (after the package:: or super::super:: part if any) */
|
|
78
|
-
const packageWord = preceded(not(segment_blacklist), or(word, keyword));
|
|
79
|
-
|
|
80
|
-
const import_path_or_item: Parser<Stream<WeslToken>, ImportStatement> = seq(
|
|
81
|
-
packageWord,
|
|
82
|
-
or(
|
|
83
|
-
preceded(
|
|
84
|
-
"::",
|
|
85
|
-
req(
|
|
86
|
-
or(
|
|
87
|
-
fn(() => import_collection),
|
|
88
|
-
fn(() => import_path_or_item),
|
|
89
|
-
),
|
|
90
|
-
"invalid import, expected '{' or name",
|
|
91
|
-
),
|
|
92
|
-
),
|
|
93
|
-
preceded("as", req(word, "invalid alias, expected name")).map(v =>
|
|
94
|
-
makeItem("", v),
|
|
95
|
-
),
|
|
96
|
-
yes().map(() => makeItem("")), // Optional
|
|
97
|
-
),
|
|
98
|
-
// biome-ignore lint/suspicious/useIterableCallbackReturn: biome doesn't recognize assertUnreachable's never return type
|
|
99
|
-
).map(([name, next]): ImportStatement => {
|
|
100
|
-
if (next.kind === "import-collection") {
|
|
101
|
-
return makeStatement([makeSegment(name)], next);
|
|
102
|
-
} else if (next.kind === "import-statement") {
|
|
103
|
-
return prependSegments([makeSegment(name)], next);
|
|
104
|
-
} else if (next.kind === "import-item") {
|
|
105
|
-
next.name = name;
|
|
106
|
-
return makeStatement([], next);
|
|
107
|
-
} else {
|
|
108
|
-
assertUnreachable(next);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
import_collection = delimited(
|
|
113
|
-
"{",
|
|
114
|
-
withSepPlus(",", () => import_path_or_item).map(makeCollection),
|
|
115
|
-
req("}", "invalid import collection, expected }"),
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const import_relative = or(
|
|
119
|
-
terminated("package", req("::", "invalid import, expected '::'")).map(v => [
|
|
120
|
-
makeSegment(v),
|
|
121
|
-
]),
|
|
122
|
-
repeatPlus(
|
|
123
|
-
terminated("super", req("::", "invalid import, expected '::'")).map(
|
|
124
|
-
makeSegment,
|
|
125
|
-
),
|
|
126
|
-
),
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
const import_statement_base = delimited(
|
|
130
|
-
"import",
|
|
131
|
-
seqObj({
|
|
132
|
-
relative: opt(import_relative),
|
|
133
|
-
collection_or_statement: req(
|
|
134
|
-
or(import_collection, import_path_or_item),
|
|
135
|
-
"invalid import, expected { or name",
|
|
136
|
-
),
|
|
137
|
-
}).map(({ relative, collection_or_statement }): ImportStatement => {
|
|
138
|
-
if (collection_or_statement.kind === "import-statement") {
|
|
139
|
-
return prependSegments(relative ?? [], collection_or_statement);
|
|
140
|
-
} else {
|
|
141
|
-
return makeStatement(relative ?? [], collection_or_statement);
|
|
142
|
-
}
|
|
143
|
-
}),
|
|
144
|
-
req(";", "invalid import, expected ';'"),
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
function wrapAttributes(
|
|
148
|
-
rawAttributes: (IfAttribute | ElifAttribute | ElseAttribute)[],
|
|
149
|
-
): AttributeElem[] {
|
|
150
|
-
return rawAttributes.map(attribute => ({
|
|
151
|
-
kind: "attribute",
|
|
152
|
-
attribute,
|
|
153
|
-
contents: [],
|
|
154
|
-
start: 0,
|
|
155
|
-
end: 0,
|
|
156
|
-
}));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const import_statement = span(
|
|
160
|
-
seq(
|
|
161
|
-
repeat(or(if_attribute_base, elif_attribute_base, else_attribute_base)),
|
|
162
|
-
import_statement_base,
|
|
163
|
-
),
|
|
164
|
-
).map(({ value: [rawAttributes, imports], span }): ImportElem => {
|
|
165
|
-
const importElem: ImportElem = {
|
|
166
|
-
kind: "import",
|
|
167
|
-
imports,
|
|
168
|
-
start: span[0],
|
|
169
|
-
end: span[1],
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
if (rawAttributes.length > 0) {
|
|
173
|
-
return { ...importElem, attributes: wrapAttributes(rawAttributes) };
|
|
174
|
-
}
|
|
175
|
-
return importElem;
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
/** parse a WESL style wgsl import statement. */
|
|
179
|
-
export const weslImports: Parser<Stream<WeslToken>, ImportElem[]> = tagScope(
|
|
180
|
-
repeat(import_statement).ptag("owo").collect(importElem),
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
if (tracing) {
|
|
184
|
-
const names: Record<string, Parser<Stream<WeslToken>, unknown>> = {
|
|
185
|
-
import_collection,
|
|
186
|
-
import_path_or_item,
|
|
187
|
-
import_relative,
|
|
188
|
-
import_statement,
|
|
189
|
-
weslImports,
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
Object.entries(names).forEach(([name, parser]) => {
|
|
193
|
-
parser.setTraceName(name);
|
|
194
|
-
});
|
|
195
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { kind, or, withSepPlus } from "mini-parse";
|
|
2
|
-
import type { WeslTokenKind } from "./WeslStream";
|
|
3
|
-
|
|
4
|
-
export const word = kind<WeslTokenKind>("word");
|
|
5
|
-
export const keyword = kind<WeslTokenKind>("keyword");
|
|
6
|
-
|
|
7
|
-
export const qualified_ident = withSepPlus(
|
|
8
|
-
"::",
|
|
9
|
-
or(word, keyword, "package", "super"),
|
|
10
|
-
); // LATER consider efficiency (it's a pretty hot area of the grammar.)
|
|
11
|
-
export const number = kind<WeslTokenKind>("number");
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collectArray,
|
|
3
|
-
delimited,
|
|
4
|
-
fn,
|
|
5
|
-
opt,
|
|
6
|
-
or,
|
|
7
|
-
type Parser,
|
|
8
|
-
preceded,
|
|
9
|
-
repeat,
|
|
10
|
-
repeatPlus,
|
|
11
|
-
req,
|
|
12
|
-
type Stream,
|
|
13
|
-
seq,
|
|
14
|
-
tagScope,
|
|
15
|
-
tokenOf,
|
|
16
|
-
tracing,
|
|
17
|
-
withSep,
|
|
18
|
-
withSepPlus,
|
|
19
|
-
yes,
|
|
20
|
-
} from "mini-parse";
|
|
21
|
-
import {
|
|
22
|
-
expressionCollect,
|
|
23
|
-
memberRefCollect,
|
|
24
|
-
nameCollect,
|
|
25
|
-
refIdent,
|
|
26
|
-
stuffCollect,
|
|
27
|
-
typeRefCollect,
|
|
28
|
-
} from "../WESLCollect.ts";
|
|
29
|
-
import { number, qualified_ident, word } from "./WeslBaseGrammar.ts";
|
|
30
|
-
import { templateClose, templateOpen, type WeslToken } from "./WeslStream.ts";
|
|
31
|
-
|
|
32
|
-
export const opt_template_list = opt(
|
|
33
|
-
seq(
|
|
34
|
-
templateOpen,
|
|
35
|
-
withSepPlus(",", () => template_parameter),
|
|
36
|
-
req(templateClose, "invalid template, expected '>'"),
|
|
37
|
-
),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const other_address_space = or("private", "workgroup", "uniform", "function");
|
|
41
|
-
|
|
42
|
-
const storage_address_space = seq(
|
|
43
|
-
"storage",
|
|
44
|
-
opt(seq(",", or("read", "read_write"))),
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
export const var_template_list = opt(
|
|
48
|
-
seq(
|
|
49
|
-
templateOpen,
|
|
50
|
-
or(storage_address_space, other_address_space),
|
|
51
|
-
req(templateClose, "invalid template, expected '>'"),
|
|
52
|
-
),
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
// prettier-ignore
|
|
56
|
-
const template_elaborated_ident = seq(
|
|
57
|
-
qualified_ident.collect(refIdent),
|
|
58
|
-
opt_template_list,
|
|
59
|
-
);
|
|
60
|
-
const literal = or("true", "false", number);
|
|
61
|
-
const paren_expression = seq(
|
|
62
|
-
"(",
|
|
63
|
-
() => expression,
|
|
64
|
-
req(")", "invalid expression, expected ')'"),
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const primary_expression = or(
|
|
68
|
-
literal,
|
|
69
|
-
paren_expression,
|
|
70
|
-
seq(template_elaborated_ident, opt(fn(() => argument_expression_list))),
|
|
71
|
-
);
|
|
72
|
-
export const component_or_swizzle = repeatPlus(
|
|
73
|
-
or(
|
|
74
|
-
preceded(".", word),
|
|
75
|
-
collectArray(
|
|
76
|
-
delimited(
|
|
77
|
-
"[",
|
|
78
|
-
() => expression,
|
|
79
|
-
req("]", "invalid expression, expected ']'"),
|
|
80
|
-
),
|
|
81
|
-
),
|
|
82
|
-
),
|
|
83
|
-
);
|
|
84
|
-
// LATER Remove
|
|
85
|
-
// prettier-ignore
|
|
86
|
-
/** parse simple struct.member style references specially, for binding struct lowering */
|
|
87
|
-
export const simple_component_reference = tagScope(
|
|
88
|
-
seq(
|
|
89
|
-
qualified_ident.collect(refIdent, "structRef"),
|
|
90
|
-
seq(".", word.collect(nameCollect, "component")),
|
|
91
|
-
opt(component_or_swizzle.collect(stuffCollect, "extra_components")),
|
|
92
|
-
).collect(memberRefCollect),
|
|
93
|
-
);
|
|
94
|
-
const unary_expression: Parser<Stream<WeslToken>, any> = or(
|
|
95
|
-
seq(tokenOf("symbol", ["!", "&", "*", "-", "~"]), () => unary_expression),
|
|
96
|
-
or(
|
|
97
|
-
simple_component_reference,
|
|
98
|
-
seq(primary_expression, opt(component_or_swizzle)),
|
|
99
|
-
),
|
|
100
|
-
);
|
|
101
|
-
const bitwise_post_unary = or(
|
|
102
|
-
// LATER I can skip template list discovery in these cases, because a&b<c cannot be a comparison. Must be a template
|
|
103
|
-
repeatPlus(seq("&", unary_expression)),
|
|
104
|
-
repeatPlus(seq("^", unary_expression)),
|
|
105
|
-
repeatPlus(seq("|", unary_expression)),
|
|
106
|
-
);
|
|
107
|
-
const multiplicative_operator = or("%", "*", "/");
|
|
108
|
-
const additive_operator = or("+", "-");
|
|
109
|
-
const shift_post_unary = (inTemplate: boolean) => {
|
|
110
|
-
const shift_left = seq("<<", unary_expression);
|
|
111
|
-
const shift_right = seq(">>", unary_expression);
|
|
112
|
-
const mul_add = seq(
|
|
113
|
-
repeat(seq(multiplicative_operator, unary_expression)),
|
|
114
|
-
repeat(
|
|
115
|
-
seq(
|
|
116
|
-
additive_operator,
|
|
117
|
-
unary_expression,
|
|
118
|
-
repeat(seq(multiplicative_operator, unary_expression)),
|
|
119
|
-
),
|
|
120
|
-
),
|
|
121
|
-
);
|
|
122
|
-
return inTemplate
|
|
123
|
-
? or(shift_left, mul_add)
|
|
124
|
-
: or(shift_left, shift_right, mul_add);
|
|
125
|
-
};
|
|
126
|
-
const relational_post_unary = (inTemplate: boolean) => {
|
|
127
|
-
return seq(
|
|
128
|
-
shift_post_unary(inTemplate),
|
|
129
|
-
opt(
|
|
130
|
-
seq(
|
|
131
|
-
// '<' is unambiguous, since templates were already caught by the primary expression inside of the previous unary_expression!
|
|
132
|
-
inTemplate
|
|
133
|
-
? tokenOf("symbol", ["<", "<=", "!=", "=="])
|
|
134
|
-
: tokenOf("symbol", [">", ">=", "<", "<=", "!=", "=="]),
|
|
135
|
-
// LATER I can skip template list discovery in this cases, because a>=b<c cannot be a comparison. Must be a template
|
|
136
|
-
unary_expression,
|
|
137
|
-
shift_post_unary(inTemplate),
|
|
138
|
-
),
|
|
139
|
-
),
|
|
140
|
-
);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
/** The expression parser exists in two variants
|
|
144
|
-
* `true` is template-expression: Refuses to parse parse symbols like `&&` and `||`.
|
|
145
|
-
* `false` is maybe-template-expression: Does the template disambiguation.
|
|
146
|
-
*/
|
|
147
|
-
const expressionParser = (
|
|
148
|
-
inTemplate: boolean,
|
|
149
|
-
): Parser<Stream<WeslToken>, any> => {
|
|
150
|
-
return seq(
|
|
151
|
-
unary_expression,
|
|
152
|
-
or(
|
|
153
|
-
bitwise_post_unary,
|
|
154
|
-
seq(
|
|
155
|
-
relational_post_unary(inTemplate),
|
|
156
|
-
inTemplate
|
|
157
|
-
? // Don't accept || or && in template mode
|
|
158
|
-
yes()
|
|
159
|
-
: or(
|
|
160
|
-
repeatPlus(
|
|
161
|
-
seq("||", seq(unary_expression, relational_post_unary(false))),
|
|
162
|
-
),
|
|
163
|
-
repeatPlus(
|
|
164
|
-
seq("&&", seq(unary_expression, relational_post_unary(false))),
|
|
165
|
-
),
|
|
166
|
-
yes().map(() => []),
|
|
167
|
-
),
|
|
168
|
-
),
|
|
169
|
-
),
|
|
170
|
-
);
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
const maybe_template = false;
|
|
174
|
-
export const expression = expressionParser(maybe_template);
|
|
175
|
-
const is_template = true;
|
|
176
|
-
const template_arg_expression = expressionParser(is_template);
|
|
177
|
-
|
|
178
|
-
// prettier-ignore
|
|
179
|
-
const std_type_specifier = seq(
|
|
180
|
-
qualified_ident.collect(refIdent, "typeRefName"),
|
|
181
|
-
() => opt_template_list,
|
|
182
|
-
).collect(typeRefCollect);
|
|
183
|
-
|
|
184
|
-
// prettier-ignore
|
|
185
|
-
export const type_specifier: Parser<Stream<WeslToken>, any> = tagScope(
|
|
186
|
-
std_type_specifier,
|
|
187
|
-
).ctag("typeRefElem");
|
|
188
|
-
|
|
189
|
-
/** a template_arg_expression with additional collection for parameters
|
|
190
|
-
* that are types like array<f32> vs. expressions like 1+2 */
|
|
191
|
-
// prettier-ignore
|
|
192
|
-
const template_parameter = or(
|
|
193
|
-
// LATER Remove this, it's wrong. This should instead be done by inspecting the syntax tree.
|
|
194
|
-
type_specifier.ctag("templateParam"),
|
|
195
|
-
template_arg_expression.collect(expressionCollect, "templateParam"),
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
export const argument_expression_list = seq(
|
|
199
|
-
"(",
|
|
200
|
-
withSep(",", expression),
|
|
201
|
-
req(")", "invalid fn arguments, expected ')'"),
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
if (tracing) {
|
|
205
|
-
const names: Record<string, Parser<Stream<WeslToken>, unknown>> = {
|
|
206
|
-
opt_template_list,
|
|
207
|
-
other_address_space,
|
|
208
|
-
storage_address_space,
|
|
209
|
-
var_template_list,
|
|
210
|
-
template_elaborated_ident,
|
|
211
|
-
primary_expression,
|
|
212
|
-
literal,
|
|
213
|
-
paren_expression,
|
|
214
|
-
component_or_swizzle,
|
|
215
|
-
simple_component_reference,
|
|
216
|
-
unary_expression,
|
|
217
|
-
bitwise_post_unary,
|
|
218
|
-
multiplicative_operator,
|
|
219
|
-
additive_operator,
|
|
220
|
-
expression,
|
|
221
|
-
template_arg_expression,
|
|
222
|
-
std_type_specifier,
|
|
223
|
-
type_specifier,
|
|
224
|
-
template_parameter,
|
|
225
|
-
argument_expression_list,
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
Object.entries(names).forEach(([name, parser]) => {
|
|
229
|
-
parser.setTraceName(name);
|
|
230
|
-
});
|
|
231
|
-
}
|