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.
- package/README.md +31 -0
- package/dist/index.js +4468 -0
- package/dist/index.js.map +1 -0
- package/dist/minified.js +3426 -0
- package/dist/minified.js.map +1 -0
- package/dist/tools/packages/wesl/src/AbstractElems.d.ts +322 -0
- package/dist/tools/packages/wesl/src/Assertions.d.ts +27 -0
- package/dist/tools/packages/wesl/src/BindIdents.d.ts +70 -0
- package/dist/tools/packages/wesl/src/Conditions.d.ts +6 -0
- package/dist/tools/packages/wesl/src/FlattenTreeImport.d.ts +11 -0
- package/dist/tools/packages/wesl/src/LinkedWesl.d.ts +50 -0
- package/dist/tools/packages/wesl/src/Linker.d.ts +87 -0
- package/dist/tools/packages/wesl/src/LinkerUtil.d.ts +3 -0
- package/dist/tools/packages/wesl/src/LiveDeclarations.d.ts +12 -0
- package/dist/tools/packages/wesl/src/LowerAndEmit.d.ts +31 -0
- package/dist/tools/packages/wesl/src/Mangler.d.ts +39 -0
- package/dist/tools/packages/wesl/src/ParseWESL.d.ts +60 -0
- package/dist/tools/packages/wesl/src/ParsedRegistry.d.ts +29 -0
- package/dist/tools/packages/wesl/src/PathUtil.d.ts +6 -0
- package/dist/tools/packages/wesl/src/RawEmit.d.ts +6 -0
- package/dist/tools/packages/wesl/src/Reflection.d.ts +45 -0
- package/dist/tools/packages/wesl/src/Scope.d.ts +81 -0
- package/dist/tools/packages/wesl/src/StandardTypes.d.ts +13 -0
- package/dist/tools/packages/wesl/src/TransformBindingStructs.d.ts +52 -0
- package/dist/tools/packages/wesl/src/Util.d.ts +43 -0
- package/dist/tools/packages/wesl/src/WESLCollect.d.ts +94 -0
- package/dist/tools/packages/wesl/src/WeslBundle.d.ts +13 -0
- package/dist/tools/packages/wesl/src/WeslDevice.d.ts +25 -0
- package/dist/tools/packages/wesl/src/debug/ASTtoString.d.ts +5 -0
- package/dist/tools/packages/wesl/src/debug/ImportToString.d.ts +2 -0
- package/dist/tools/packages/wesl/src/debug/LineWrapper.d.ts +21 -0
- package/dist/tools/packages/wesl/src/debug/ScopeToString.d.ts +6 -0
- package/dist/tools/packages/wesl/src/index.d.ts +11 -0
- package/dist/tools/packages/wesl/src/parse/ImportGrammar.d.ts +5 -0
- package/dist/tools/packages/wesl/src/parse/Keywords.d.ts +4 -0
- package/dist/tools/packages/wesl/src/parse/WeslBaseGrammar.d.ts +5 -0
- package/dist/tools/packages/wesl/src/parse/WeslExpression.d.ts +13 -0
- package/dist/tools/packages/wesl/src/parse/WeslGrammar.d.ts +80 -0
- package/dist/tools/packages/wesl/src/parse/WeslStream.d.ts +44 -0
- package/dist/tools/packages/wesl/src/test/BindWESL.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ConditionLinking.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ConditionalTranslationCases.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ErrorLogging.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/Expression.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/FlattenTreeImport.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ImportCases.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ImportSyntaxCases.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/LinkGlob.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/LinkPackage.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/Linker.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/Mangling.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ParseComments.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ParseConditions.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ParseError.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ParseWESL.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/PathUtil.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/PrettyGrammar.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/Reflection.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/ScopeWESL.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/TestLink.d.ts +21 -0
- package/dist/tools/packages/wesl/src/test/TestSetup.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/TestUtil.d.ts +40 -0
- package/dist/tools/packages/wesl/src/test/Tokenizer.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/TransformBindingStructs.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/Util.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/VirtualModules.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/WeslDevice.test.d.ts +1 -0
- package/dist/tools/packages/wesl/src/test/WgslTests.d.ts +0 -0
- package/dist/tools/packages/wesl/src/vlq/vlq.d.ts +11 -0
- package/package.json +46 -0
- package/src/AbstractElems.ts +446 -0
- package/src/Assertions.ts +51 -0
- package/src/BindIdents.ts +523 -0
- package/src/Conditions.ts +74 -0
- package/src/FlattenTreeImport.ts +55 -0
- package/src/LinkedWesl.ts +184 -0
- package/src/Linker.ts +284 -0
- package/src/LinkerUtil.ts +29 -0
- package/src/LiveDeclarations.ts +31 -0
- package/src/LowerAndEmit.ts +413 -0
- package/src/Mangler.ts +94 -0
- package/src/ParseWESL.ts +157 -0
- package/src/ParsedRegistry.ts +120 -0
- package/src/PathUtil.ts +31 -0
- package/src/RawEmit.ts +102 -0
- package/src/Reflection.ts +334 -0
- package/src/Scope.ts +162 -0
- package/src/StandardTypes.ts +97 -0
- package/src/TransformBindingStructs.ts +319 -0
- package/src/Util.ts +194 -0
- package/src/WESLCollect.ts +614 -0
- package/src/WeslBundle.ts +16 -0
- package/src/WeslDevice.ts +209 -0
- package/src/debug/ASTtoString.ts +290 -0
- package/src/debug/ImportToString.ts +29 -0
- package/src/debug/LineWrapper.ts +70 -0
- package/src/debug/ScopeToString.ts +79 -0
- package/src/index.ts +11 -0
- package/src/parse/ImportGrammar.ts +157 -0
- package/src/parse/Keywords.ts +26 -0
- package/src/parse/WeslBaseGrammar.ts +8 -0
- package/src/parse/WeslExpression.ts +207 -0
- package/src/parse/WeslGrammar.ts +856 -0
- package/src/parse/WeslStream.ts +279 -0
- package/src/test/BindWESL.test.ts +57 -0
- package/src/test/ConditionLinking.test.ts +91 -0
- package/src/test/ConditionalTranslationCases.test.ts +56 -0
- package/src/test/ErrorLogging.test.ts +30 -0
- package/src/test/Expression.test.ts +22 -0
- package/src/test/FlattenTreeImport.test.ts +74 -0
- package/src/test/ImportCases.test.ts +56 -0
- package/src/test/ImportSyntaxCases.test.ts +24 -0
- package/src/test/LinkGlob.test.ts +25 -0
- package/src/test/LinkPackage.test.ts +26 -0
- package/src/test/Linker.test.ts +125 -0
- package/src/test/Mangling.test.ts +45 -0
- package/src/test/ParseComments.test.ts +36 -0
- package/src/test/ParseConditions.test.ts +183 -0
- package/src/test/ParseError.test.ts +36 -0
- package/src/test/ParseWESL.test.ts +1572 -0
- package/src/test/PathUtil.test.ts +34 -0
- package/src/test/PrettyGrammar.test.ts +20 -0
- package/src/test/Reflection.test.ts +172 -0
- package/src/test/ScopeWESL.test.ts +462 -0
- package/src/test/TestLink.ts +82 -0
- package/src/test/TestSetup.ts +4 -0
- package/src/test/TestUtil.ts +126 -0
- package/src/test/Tokenizer.test.ts +135 -0
- package/src/test/TransformBindingStructs.test.ts +230 -0
- package/src/test/Util.test.ts +22 -0
- package/src/test/VirtualModules.test.ts +37 -0
- package/src/test/WeslDevice.test.ts +265 -0
- package/src/test/WgslTests.ts +0 -0
- package/src/test/__snapshots__/ParseDirectives.test.ts.snap +25 -0
- package/src/test/__snapshots__/ParseWESL.test.ts.snap +119 -0
- package/src/test/__snapshots__/RustDirective.test.ts.snap +359 -0
- package/src/test/wgsl_1/main.wgsl +3 -0
- package/src/test/wgsl_1/util.wgsl +1 -0
- package/src/test/wgsl_2/main2.wgsl +3 -0
- package/src/test/wgsl_2/util2.wgsl +1 -0
- package/src/vlq/vlq.ts +94 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
delimited,
|
|
3
|
+
fn,
|
|
4
|
+
opt,
|
|
5
|
+
or,
|
|
6
|
+
Parser,
|
|
7
|
+
preceded,
|
|
8
|
+
repeat,
|
|
9
|
+
repeatPlus,
|
|
10
|
+
req,
|
|
11
|
+
seq,
|
|
12
|
+
seqObj,
|
|
13
|
+
span,
|
|
14
|
+
Stream,
|
|
15
|
+
tagScope,
|
|
16
|
+
terminated,
|
|
17
|
+
tracing,
|
|
18
|
+
withSepPlus,
|
|
19
|
+
yes,
|
|
20
|
+
} from "mini-parse";
|
|
21
|
+
import type {
|
|
22
|
+
ImportCollection,
|
|
23
|
+
ImportElem,
|
|
24
|
+
ImportItem,
|
|
25
|
+
ImportSegment,
|
|
26
|
+
ImportStatement,
|
|
27
|
+
} from "../AbstractElems.js";
|
|
28
|
+
import { assertUnreachable } from "../Assertions.js";
|
|
29
|
+
import { importElem } from "../WESLCollect.js";
|
|
30
|
+
import { word } from "./WeslBaseGrammar.js";
|
|
31
|
+
import { WeslToken } from "./WeslStream.js";
|
|
32
|
+
|
|
33
|
+
function makeStatement(
|
|
34
|
+
segments: ImportSegment[],
|
|
35
|
+
finalSegment: ImportCollection | ImportItem,
|
|
36
|
+
): ImportStatement {
|
|
37
|
+
return { kind: "import-statement", segments, finalSegment };
|
|
38
|
+
}
|
|
39
|
+
function makeSegment(name: string): ImportSegment {
|
|
40
|
+
return { kind: "import-segment", name };
|
|
41
|
+
}
|
|
42
|
+
function makeCollection(subtrees: ImportStatement[]): ImportCollection {
|
|
43
|
+
return {
|
|
44
|
+
kind: "import-collection",
|
|
45
|
+
subtrees,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function makeItem(name: string, as?: string): ImportItem {
|
|
49
|
+
return { kind: "import-item", name, as };
|
|
50
|
+
}
|
|
51
|
+
function prependSegments(
|
|
52
|
+
segments: ImportSegment[],
|
|
53
|
+
statement: ImportStatement,
|
|
54
|
+
): ImportStatement {
|
|
55
|
+
statement.segments = segments.concat(statement.segments);
|
|
56
|
+
return statement;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// forward references for mutual recursion
|
|
60
|
+
let import_collection: Parser<
|
|
61
|
+
Stream<WeslToken>,
|
|
62
|
+
ImportCollection
|
|
63
|
+
> = null as any;
|
|
64
|
+
|
|
65
|
+
const import_path_or_item: Parser<Stream<WeslToken>, ImportStatement> = seq(
|
|
66
|
+
word,
|
|
67
|
+
or(
|
|
68
|
+
preceded(
|
|
69
|
+
"::",
|
|
70
|
+
req(
|
|
71
|
+
or(
|
|
72
|
+
fn(() => import_collection),
|
|
73
|
+
fn(() => import_path_or_item),
|
|
74
|
+
),
|
|
75
|
+
"invalid import, expected '{' or name",
|
|
76
|
+
),
|
|
77
|
+
),
|
|
78
|
+
preceded("as", req(word, "invalid alias, expected name")).map(v =>
|
|
79
|
+
makeItem("", v),
|
|
80
|
+
),
|
|
81
|
+
yes().map(() => makeItem("")), // Optional
|
|
82
|
+
),
|
|
83
|
+
).map(([name, next]): ImportStatement => {
|
|
84
|
+
if (next.kind === "import-collection") {
|
|
85
|
+
return makeStatement([makeSegment(name)], next);
|
|
86
|
+
} else if (next.kind === "import-statement") {
|
|
87
|
+
return prependSegments([makeSegment(name)], next);
|
|
88
|
+
} else if (next.kind === "import-item") {
|
|
89
|
+
next.name = name;
|
|
90
|
+
return makeStatement([], next);
|
|
91
|
+
} else {
|
|
92
|
+
assertUnreachable(next);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
import_collection = delimited(
|
|
97
|
+
"{",
|
|
98
|
+
withSepPlus(",", () => import_path_or_item).map(makeCollection),
|
|
99
|
+
req("}", "invalid import collection, expected }"),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const import_relative = or(
|
|
103
|
+
terminated("package", req("::", "invalid import, expected '::'")).map(v => [
|
|
104
|
+
makeSegment(v),
|
|
105
|
+
]),
|
|
106
|
+
repeatPlus(
|
|
107
|
+
terminated("super", req("::", "invalid import, expected '::'")).map(
|
|
108
|
+
makeSegment,
|
|
109
|
+
),
|
|
110
|
+
),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const import_statement = span(
|
|
114
|
+
delimited(
|
|
115
|
+
"import",
|
|
116
|
+
seqObj({
|
|
117
|
+
relative: opt(import_relative),
|
|
118
|
+
collection_or_statement: req(
|
|
119
|
+
or(import_collection, import_path_or_item),
|
|
120
|
+
"invalid import, expected { or name",
|
|
121
|
+
),
|
|
122
|
+
}).map(({ relative, collection_or_statement }): ImportStatement => {
|
|
123
|
+
if (collection_or_statement.kind === "import-statement") {
|
|
124
|
+
return prependSegments(relative ?? [], collection_or_statement);
|
|
125
|
+
} else {
|
|
126
|
+
return makeStatement(relative ?? [], collection_or_statement);
|
|
127
|
+
}
|
|
128
|
+
}),
|
|
129
|
+
req(";", "invalid import, expected ';'"),
|
|
130
|
+
),
|
|
131
|
+
).map(
|
|
132
|
+
(v): ImportElem => ({
|
|
133
|
+
kind: "import",
|
|
134
|
+
imports: v.value,
|
|
135
|
+
start: v.span[0],
|
|
136
|
+
end: v.span[1],
|
|
137
|
+
}),
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
/** parse a WESL style wgsl import statement. */
|
|
141
|
+
export const weslImports: Parser<Stream<WeslToken>, ImportElem[]> = tagScope(
|
|
142
|
+
repeat(import_statement).ptag("owo").collect(importElem),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
if (tracing) {
|
|
146
|
+
const names: Record<string, Parser<Stream<WeslToken>, unknown>> = {
|
|
147
|
+
import_collection,
|
|
148
|
+
import_path_or_item,
|
|
149
|
+
import_relative,
|
|
150
|
+
import_statement,
|
|
151
|
+
weslImports,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
Object.entries(names).forEach(([name, parser]) => {
|
|
155
|
+
parser.setTraceName(name);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Use https://github.com/wgsl-tooling-wg/wgsl-spec to check this list in the future
|
|
2
|
+
// I recommend checking whether a new list and the current list are equal
|
|
3
|
+
|
|
4
|
+
/** https://www.w3.org/TR/WGSL/#keyword-summary */
|
|
5
|
+
export const keywords =
|
|
6
|
+
`alias break case const const_assert continue continuing
|
|
7
|
+
default diagnostic discard else enable false fn for if
|
|
8
|
+
let loop override requires return struct switch true var while`.split(/\s+/);
|
|
9
|
+
|
|
10
|
+
/** https://www.w3.org/TR/WGSL/#reserved-words */
|
|
11
|
+
export const reservedWords =
|
|
12
|
+
`NULL Self abstract active alignas alignof as asm asm_fragment async attribute auto await
|
|
13
|
+
become binding_array cast catch class co_await co_return co_yield coherent column_major
|
|
14
|
+
common compile compile_fragment concept const_cast consteval constexpr constinit crate
|
|
15
|
+
debugger decltype delete demote demote_to_helper do dynamic_cast
|
|
16
|
+
enum explicit export extends extern external fallthrough filter final finally friend from fxgroup
|
|
17
|
+
get goto groupshared highp impl implements import inline instanceof interface layout lowp
|
|
18
|
+
macro macro_rules match mediump meta mod module move mut mutable
|
|
19
|
+
namespace new nil noexcept noinline nointerpolation non_coherent noncoherent noperspective null nullptr
|
|
20
|
+
of operator package packoffset partition pass patch pixelfragment precise precision premerge
|
|
21
|
+
priv protected pub public readonly ref regardless register reinterpret_cast require resource restrict
|
|
22
|
+
self set shared sizeof smooth snorm static static_assert static_cast std subroutine super
|
|
23
|
+
target template this thread_local throw trait try type typedef typeid typename typeof
|
|
24
|
+
union unless unorm unsafe unsized use using varying virtual volatile wgsl where with writeonly yield`.split(
|
|
25
|
+
/\s+/,
|
|
26
|
+
);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { kind, or, withSepPlus } from "mini-parse";
|
|
2
|
+
import { 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("::", or(word, "package", "super")); // LATER consider efficiency (it's a pretty hot area of the grammar.)
|
|
8
|
+
export const number = kind<WeslTokenKind>("number");
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import {
|
|
2
|
+
collectArray,
|
|
3
|
+
delimited,
|
|
4
|
+
fn,
|
|
5
|
+
opt,
|
|
6
|
+
or,
|
|
7
|
+
Parser,
|
|
8
|
+
preceded,
|
|
9
|
+
repeat,
|
|
10
|
+
repeatPlus,
|
|
11
|
+
req,
|
|
12
|
+
seq,
|
|
13
|
+
Stream,
|
|
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";
|
|
29
|
+
import { number, qualified_ident, word } from "./WeslBaseGrammar";
|
|
30
|
+
import { templateClose, templateOpen, WeslToken } from "./WeslStream";
|
|
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
|
+
// prettier-ignore
|
|
41
|
+
const template_elaborated_ident = seq(
|
|
42
|
+
qualified_ident.collect(refIdent),
|
|
43
|
+
opt_template_list
|
|
44
|
+
);
|
|
45
|
+
const literal = or("true", "false", number);
|
|
46
|
+
const paren_expression = seq(
|
|
47
|
+
"(",
|
|
48
|
+
() => expression,
|
|
49
|
+
req(")", "invalid expression, expected ')'"),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const primary_expression = or(
|
|
53
|
+
literal,
|
|
54
|
+
paren_expression,
|
|
55
|
+
seq(template_elaborated_ident, opt(fn(() => argument_expression_list))),
|
|
56
|
+
);
|
|
57
|
+
export const component_or_swizzle = repeatPlus(
|
|
58
|
+
or(
|
|
59
|
+
preceded(".", word),
|
|
60
|
+
collectArray(
|
|
61
|
+
delimited(
|
|
62
|
+
"[",
|
|
63
|
+
() => expression,
|
|
64
|
+
req("]", "invalid expression, expected ']'"),
|
|
65
|
+
),
|
|
66
|
+
),
|
|
67
|
+
),
|
|
68
|
+
);
|
|
69
|
+
// LATER Remove
|
|
70
|
+
// prettier-ignore
|
|
71
|
+
/** parse simple struct.member style references specially, for binding struct lowering */
|
|
72
|
+
export const simple_component_reference = tagScope(
|
|
73
|
+
seq(
|
|
74
|
+
qualified_ident.collect(refIdent, "structRef"),
|
|
75
|
+
seq(".", word.collect(nameCollect, "component")),
|
|
76
|
+
opt(component_or_swizzle.collect(stuffCollect, "extra_components"))
|
|
77
|
+
).collect(memberRefCollect)
|
|
78
|
+
);
|
|
79
|
+
const unary_expression: Parser<Stream<WeslToken>, any> = or(
|
|
80
|
+
seq(tokenOf("symbol", ["!", "&", "*", "-", "~"]), () => unary_expression),
|
|
81
|
+
or(
|
|
82
|
+
simple_component_reference,
|
|
83
|
+
seq(primary_expression, opt(component_or_swizzle)),
|
|
84
|
+
),
|
|
85
|
+
);
|
|
86
|
+
const bitwise_post_unary = or(
|
|
87
|
+
// LATER I can skip template list discovery in these cases, because a&b<c cannot be a comparison. Must be a template
|
|
88
|
+
repeatPlus(seq("&", unary_expression)),
|
|
89
|
+
repeatPlus(seq("^", unary_expression)),
|
|
90
|
+
repeatPlus(seq("|", unary_expression)),
|
|
91
|
+
);
|
|
92
|
+
const multiplicative_operator = or("%", "*", "/");
|
|
93
|
+
const additive_operator = or("+", "-");
|
|
94
|
+
const shift_post_unary = (inTemplate: boolean) => {
|
|
95
|
+
const shift_left = seq("<<", unary_expression);
|
|
96
|
+
const shift_right = seq(">>", unary_expression);
|
|
97
|
+
const mul_add = seq(
|
|
98
|
+
repeat(seq(multiplicative_operator, unary_expression)),
|
|
99
|
+
repeat(
|
|
100
|
+
seq(
|
|
101
|
+
additive_operator,
|
|
102
|
+
unary_expression,
|
|
103
|
+
repeat(seq(multiplicative_operator, unary_expression)),
|
|
104
|
+
),
|
|
105
|
+
),
|
|
106
|
+
);
|
|
107
|
+
return inTemplate ?
|
|
108
|
+
or(shift_left, mul_add)
|
|
109
|
+
: or(shift_left, shift_right, mul_add);
|
|
110
|
+
};
|
|
111
|
+
const relational_post_unary = (inTemplate: boolean) => {
|
|
112
|
+
return seq(
|
|
113
|
+
shift_post_unary(inTemplate),
|
|
114
|
+
opt(
|
|
115
|
+
seq(
|
|
116
|
+
// '<' is unambiguous, since templates were already caught by the primary expression inside of the previous unary_expression!
|
|
117
|
+
inTemplate ?
|
|
118
|
+
tokenOf("symbol", ["<", "<=", "!=", "=="])
|
|
119
|
+
: tokenOf("symbol", [">", ">=", "<", "<=", "!=", "=="]),
|
|
120
|
+
// LATER I can skip template list discovery in this cases, because a>=b<c cannot be a comparison. Must be a template
|
|
121
|
+
unary_expression,
|
|
122
|
+
shift_post_unary(inTemplate),
|
|
123
|
+
),
|
|
124
|
+
),
|
|
125
|
+
);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/** The expression parser exists in two variants
|
|
129
|
+
* `true` is template-expression: Refuses to parse parse symbols like `&&` and `||`.
|
|
130
|
+
* `false` is maybe-template-expression: Does the template disambiguation.
|
|
131
|
+
*/
|
|
132
|
+
const expressionParser = (
|
|
133
|
+
inTemplate: boolean,
|
|
134
|
+
): Parser<Stream<WeslToken>, any> => {
|
|
135
|
+
return seq(
|
|
136
|
+
unary_expression,
|
|
137
|
+
or(
|
|
138
|
+
bitwise_post_unary,
|
|
139
|
+
seq(
|
|
140
|
+
relational_post_unary(inTemplate),
|
|
141
|
+
inTemplate ?
|
|
142
|
+
// Don't accept || or && in template mode
|
|
143
|
+
yes()
|
|
144
|
+
: or(
|
|
145
|
+
repeatPlus(
|
|
146
|
+
seq("||", seq(unary_expression, relational_post_unary(false))),
|
|
147
|
+
),
|
|
148
|
+
repeatPlus(
|
|
149
|
+
seq("&&", seq(unary_expression, relational_post_unary(false))),
|
|
150
|
+
),
|
|
151
|
+
yes().map(() => []),
|
|
152
|
+
),
|
|
153
|
+
),
|
|
154
|
+
),
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
let maybe_template = false;
|
|
159
|
+
export const expression = expressionParser(maybe_template);
|
|
160
|
+
let is_template = true;
|
|
161
|
+
const template_arg_expression = expressionParser(is_template);
|
|
162
|
+
|
|
163
|
+
// prettier-ignore
|
|
164
|
+
const std_type_specifier = seq(
|
|
165
|
+
qualified_ident .collect(refIdent, "typeRefName"),
|
|
166
|
+
() => opt_template_list,
|
|
167
|
+
) .collect(typeRefCollect);
|
|
168
|
+
|
|
169
|
+
// prettier-ignore
|
|
170
|
+
export const type_specifier: Parser<Stream<WeslToken>,any> = tagScope(
|
|
171
|
+
std_type_specifier,
|
|
172
|
+
) .ctag("typeRefElem");
|
|
173
|
+
|
|
174
|
+
/** a template_arg_expression with additional collection for parameters
|
|
175
|
+
* that are types like array<f32> vs. expressions like 1+2 */
|
|
176
|
+
// prettier-ignore
|
|
177
|
+
const template_parameter = or(
|
|
178
|
+
// LATER Remove this, it's wrong. This should instead be done by inspecting the syntax tree.
|
|
179
|
+
type_specifier.ctag("templateParam"),
|
|
180
|
+
template_arg_expression.collect(expressionCollect, "templateParam")
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
export const argument_expression_list = seq(
|
|
184
|
+
"(",
|
|
185
|
+
withSep(",", expression),
|
|
186
|
+
req(")", "invalid fn arguments, expected ')'"),
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
if (tracing) {
|
|
190
|
+
const names: Record<string, Parser<Stream<WeslToken>, unknown>> = {
|
|
191
|
+
argument_expression_list,
|
|
192
|
+
type_specifier,
|
|
193
|
+
opt_template_list,
|
|
194
|
+
template_elaborated_ident,
|
|
195
|
+
literal,
|
|
196
|
+
paren_expression,
|
|
197
|
+
primary_expression,
|
|
198
|
+
component_or_swizzle,
|
|
199
|
+
unary_expression,
|
|
200
|
+
expression,
|
|
201
|
+
template_arg_expression,
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
Object.entries(names).forEach(([name, parser]) => {
|
|
205
|
+
parser.setTraceName(name);
|
|
206
|
+
});
|
|
207
|
+
}
|