shaderkit 0.7.0 → 0.8.0
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/LICENSE +21 -21
- package/README.md +781 -781
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/package.json +46 -46
- package/src/ast.ts +425 -425
- package/src/constants.ts +1005 -1005
- package/src/generator.ts +128 -128
- package/src/hoister.ts +171 -0
- package/src/index.ts +7 -7
- package/src/minifier.ts +445 -445
- package/src/parser.ts +878 -802
- package/src/tokenizer.ts +105 -105
- package/src/visitor.ts +131 -131
package/README.md
CHANGED
|
@@ -1,781 +1,781 @@
|
|
|
1
|
-
[](https://bundlephobia.com/package/shaderkit)
|
|
2
|
-
[](https://npmjs.com/package/shaderkit)
|
|
3
|
-
[](https://npmjs.com/package/shaderkit)
|
|
4
|
-
|
|
5
|
-
# shaderkit
|
|
6
|
-
|
|
7
|
-
Tools and IntelliSense for GLSL and WGSL.
|
|
8
|
-
|
|
9
|
-
## Table of Contents
|
|
10
|
-
|
|
11
|
-
- [Installation](#installation)
|
|
12
|
-
- [Tokenize](#tokenize)
|
|
13
|
-
- [Minify](#minify)
|
|
14
|
-
- [Parse](#parse)
|
|
15
|
-
- [Generate](#generate)
|
|
16
|
-
- [Visit](#visit)
|
|
17
|
-
- [AST](#ast)
|
|
18
|
-
- [Node Objects](#node-objects)
|
|
19
|
-
- [Identifier](#identifier)
|
|
20
|
-
- [Literal](#literal)
|
|
21
|
-
- [ArraySpecifier](#arrayspecifier)
|
|
22
|
-
- [Program](#program)
|
|
23
|
-
- Statements
|
|
24
|
-
- [ExpressionStatement](#expressionstatement)
|
|
25
|
-
- [BlockStatement](#blockstatement)
|
|
26
|
-
- [DiscardStatement](#discardstatement)
|
|
27
|
-
- [PreprocessorStatement](#preprocessorstatement)
|
|
28
|
-
- [PrecisionQualifierStatement](#precisionqualifierstatement)
|
|
29
|
-
- [InvariantQualifierStatement](#invariantqualifierstatement)
|
|
30
|
-
- [LayoutQualifierStatement](#layoutqualifierstatement)
|
|
31
|
-
- Control Flow
|
|
32
|
-
- [ReturnStatement](#returnstatement)
|
|
33
|
-
- [BreakStatement](#breakstatement)
|
|
34
|
-
- [ContinueStatement](#continuestatement)
|
|
35
|
-
- Choice
|
|
36
|
-
- [IfStatement](#ifstatement)
|
|
37
|
-
- [SwitchStatement](#switchstatement)
|
|
38
|
-
- [SwitchCase](#switchcase)
|
|
39
|
-
- Loops
|
|
40
|
-
- [WhileStatement](#whilestatement)
|
|
41
|
-
- [DoWhileStatement](#dowhilestatement)
|
|
42
|
-
- [ForStatement](#forstatement)
|
|
43
|
-
- Declarations
|
|
44
|
-
- [FunctionDeclaration](#functiondeclaration)
|
|
45
|
-
- [FunctionParameter](#functionparameter)
|
|
46
|
-
- [VariableDeclaration](#variabledeclaration)
|
|
47
|
-
- [VariableDeclarator](#variabledeclarator)
|
|
48
|
-
- [StructuredBufferDeclaration](#structuredbufferdeclaration)
|
|
49
|
-
- [StructDeclaration](#structdeclaration)
|
|
50
|
-
- Expressions
|
|
51
|
-
- [ArrayExpression](#arrayexpression)
|
|
52
|
-
- Unary Operations
|
|
53
|
-
- [UnaryExpression](#unaryexpression)
|
|
54
|
-
- [UnaryOperator](#unaryoperator)
|
|
55
|
-
- [UpdateExpression](#updateexpression)
|
|
56
|
-
- [UpdateOperator](#updateoperator)
|
|
57
|
-
- Binary Operations
|
|
58
|
-
- [BinaryExpression](#binaryexpression)
|
|
59
|
-
- [BinaryOperator](#binaryoperator)
|
|
60
|
-
- [AssignmentExpression](#assignmentexpression)
|
|
61
|
-
- [AssignmentOperator](#assignmentoperator)
|
|
62
|
-
- [LogicalExpression](#logicalexpression)
|
|
63
|
-
- [LogicalOperator](#logicaloperator)
|
|
64
|
-
- [MemberExpression](#memberexpression)
|
|
65
|
-
- [ConditionalExpression](#conditionalexpression)
|
|
66
|
-
- [CallExpression](#callexpression)
|
|
67
|
-
|
|
68
|
-
## Installation
|
|
69
|
-
|
|
70
|
-
To install, use your preferred package manager:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
npm install shaderkit
|
|
74
|
-
yarn add shaderkit
|
|
75
|
-
pnpm add shaderkit
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Or, use a CDN:
|
|
79
|
-
|
|
80
|
-
```html
|
|
81
|
-
<script type="module">
|
|
82
|
-
import * as shaderkit from 'https://unpkg.com/shaderkit'
|
|
83
|
-
</script>
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Tokenize
|
|
87
|
-
|
|
88
|
-
Tokenizes a string of GLSL or WGSL code, returning an array of `Token` objects, where each `Token` object represents a single syntax feature in the input code.
|
|
89
|
-
|
|
90
|
-
```ts
|
|
91
|
-
interface Token {
|
|
92
|
-
type: 'whitespace' | 'comment' | 'symbol' | 'bool' | 'float' | 'int' | 'identifier' | 'keyword'
|
|
93
|
-
value: string
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
<details>
|
|
98
|
-
<summary>GLSL Example</summary>
|
|
99
|
-
|
|
100
|
-
<br />
|
|
101
|
-
|
|
102
|
-
```ts
|
|
103
|
-
import { tokenize } from 'shaderkit'
|
|
104
|
-
|
|
105
|
-
const code = 'void main() { gl_Position = vec4(0, 0, 0, 1); }'
|
|
106
|
-
const tokens = tokenize(code)
|
|
107
|
-
|
|
108
|
-
console.log(tokens)
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
The output of the above code will be:
|
|
112
|
-
|
|
113
|
-
```json
|
|
114
|
-
[
|
|
115
|
-
{ "type": "keyword", "value": "void" },
|
|
116
|
-
{ "type": "whitespace", "value": " " },
|
|
117
|
-
{ "type": "identifier", "value": "main" },
|
|
118
|
-
{ "type": "symbol", "value": "(" },
|
|
119
|
-
{ "type": "symbol", "value": ")" },
|
|
120
|
-
{ "type": "whitespace", "value": " " },
|
|
121
|
-
{ "type": "symbol", "value": "{" },
|
|
122
|
-
{ "type": "whitespace", "value": " " },
|
|
123
|
-
{ "type": "keyword", "value": "gl_Position" },
|
|
124
|
-
{ "type": "whitespace", "value": " " },
|
|
125
|
-
{ "type": "symbol", "value": "=" },
|
|
126
|
-
{ "type": "whitespace", "value": " " },
|
|
127
|
-
{ "type": "keyword", "value": "vec4" },
|
|
128
|
-
{ "type": "symbol", "value": "(" },
|
|
129
|
-
{ "type": "int", "value": "0" },
|
|
130
|
-
{ "type": "symbol", "value": "," },
|
|
131
|
-
{ "type": "whitespace", "value": " " },
|
|
132
|
-
{ "type": "int", "value": "0" },
|
|
133
|
-
{ "type": "symbol", "value": "," },
|
|
134
|
-
{ "type": "whitespace", "value": " " },
|
|
135
|
-
{ "type": "int", "value": "0" },
|
|
136
|
-
{ "type": "symbol", "value": "," },
|
|
137
|
-
{ "type": "whitespace", "value": " " },
|
|
138
|
-
{ "type": "int", "value": "1" },
|
|
139
|
-
{ "type": "symbol", "value": ")" },
|
|
140
|
-
{ "type": "symbol", "value": ";" },
|
|
141
|
-
{ "type": "whitespace", "value": " " },
|
|
142
|
-
{ "type": "symbol", "value": "}" }
|
|
143
|
-
]
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
</details>
|
|
147
|
-
|
|
148
|
-
<details>
|
|
149
|
-
<summary>WGSL Example</summary>
|
|
150
|
-
|
|
151
|
-
<br />
|
|
152
|
-
|
|
153
|
-
```ts
|
|
154
|
-
import { tokenize } from 'shaderkit'
|
|
155
|
-
|
|
156
|
-
const code = '@vertex fn main() -> @builtin(position) vec4<f32> { return vec4(0, 0, 0, 1); }'
|
|
157
|
-
const tokens = tokenize(code)
|
|
158
|
-
|
|
159
|
-
console.log(tokens)
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
The output of the above code will be:
|
|
163
|
-
|
|
164
|
-
```json
|
|
165
|
-
[
|
|
166
|
-
{ "type": "symbol", "value": "@" },
|
|
167
|
-
{ "type": "keyword", "value": "vertex" },
|
|
168
|
-
{ "type": "whitespace", "value": " " },
|
|
169
|
-
{ "type": "keyword", "value": "fn" },
|
|
170
|
-
{ "type": "whitespace", "value": " " },
|
|
171
|
-
{ "type": "identifier", "value": "main" },
|
|
172
|
-
{ "type": "symbol", "value": "(" },
|
|
173
|
-
{ "type": "symbol", "value": ")" },
|
|
174
|
-
{ "type": "whitespace", "value": " " },
|
|
175
|
-
{ "type": "symbol", "value": "->" },
|
|
176
|
-
{ "type": "whitespace", "value": " " },
|
|
177
|
-
{ "type": "symbol", "value": "@" },
|
|
178
|
-
{ "type": "keyword", "value": "builtin" },
|
|
179
|
-
{ "type": "symbol", "value": "(" },
|
|
180
|
-
{ "type": "keyword", "value": "position" },
|
|
181
|
-
{ "type": "symbol", "value": ")" },
|
|
182
|
-
{ "type": "whitespace", "value": " " },
|
|
183
|
-
{ "type": "keyword", "value": "vec4" },
|
|
184
|
-
{ "type": "symbol", "value": "<" },
|
|
185
|
-
{ "type": "keyword", "value": "f32" },
|
|
186
|
-
{ "type": "symbol", "value": ">" },
|
|
187
|
-
{ "type": "whitespace", "value": " " },
|
|
188
|
-
{ "type": "symbol", "value": "{" },
|
|
189
|
-
{ "type": "whitespace", "value": " " },
|
|
190
|
-
{ "type": "keyword", "value": "return" },
|
|
191
|
-
{ "type": "whitespace", "value": " " },
|
|
192
|
-
{ "type": "keyword", "value": "vec4" },
|
|
193
|
-
{ "type": "symbol", "value": "(" },
|
|
194
|
-
{ "type": "int", "value": "0" },
|
|
195
|
-
{ "type": "symbol", "value": "," },
|
|
196
|
-
{ "type": "whitespace", "value": " " },
|
|
197
|
-
{ "type": "int", "value": "0" },
|
|
198
|
-
{ "type": "symbol", "value": "," },
|
|
199
|
-
{ "type": "whitespace", "value": " " },
|
|
200
|
-
{ "type": "int", "value": "0" },
|
|
201
|
-
{ "type": "symbol", "value": "," },
|
|
202
|
-
{ "type": "whitespace", "value": " " },
|
|
203
|
-
{ "type": "int", "value": "1" },
|
|
204
|
-
{ "type": "symbol", "value": ")" },
|
|
205
|
-
{ "type": "symbol", "value": ";" },
|
|
206
|
-
{ "type": "whitespace", "value": " " },
|
|
207
|
-
{ "type": "symbol", "value": "}" }
|
|
208
|
-
]
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
</details>
|
|
212
|
-
|
|
213
|
-
The following are the supported token types and their descriptions:
|
|
214
|
-
|
|
215
|
-
| Type | Description |
|
|
216
|
-
| ---------- | ------------------------------------------------------------------------- |
|
|
217
|
-
| whitespace | A sequence of one or more whitespace characters. |
|
|
218
|
-
| comment | A single-line or multi-line comment. |
|
|
219
|
-
| symbol | A symbol, such as an operator or punctuation mark. |
|
|
220
|
-
| bool | A boolean value, either true or false. |
|
|
221
|
-
| float | A floating-point number, represented by a sequence of digits and symbols. |
|
|
222
|
-
| int | An integer number, represented by a sequence of digits. |
|
|
223
|
-
| identifier | A user-defined identifier, such as a variable name or function name. |
|
|
224
|
-
| keyword | A keyword reserved by the language, such as if, else, for, etc. |
|
|
225
|
-
|
|
226
|
-
## Minify
|
|
227
|
-
|
|
228
|
-
Minifies a string of GLSL or WGSL code, returning a minified version of the input code.
|
|
229
|
-
|
|
230
|
-
```ts
|
|
231
|
-
const minified: string = minify(code: string, {
|
|
232
|
-
/** Whether to rename variables. Will call a MangleMatcher if specified. Default is `false`. */
|
|
233
|
-
mangle: boolean | ((token: Token, index: number, tokens: Token[]) => boolean)
|
|
234
|
-
/** A map to read and write renamed variables to when mangling. */
|
|
235
|
-
mangleMap: Map<string, string>
|
|
236
|
-
/** Whether to rename external variables such as uniforms or varyings. Default is `false`. */
|
|
237
|
-
mangleExternals: boolean
|
|
238
|
-
})
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
To shared mangled interfaces when using `mangleExternal`, declare and re-use a `mangleMap` between shaders:
|
|
242
|
-
|
|
243
|
-
```ts
|
|
244
|
-
const options = { mangle: true, mangleExternals: true, mangleMap: new Map() }
|
|
245
|
-
|
|
246
|
-
// #version 300 es\nin vec2 a;out vec2 b;void main(){b=a;}
|
|
247
|
-
minify(`#version 300 es\nin vec2 sstt;out vec2 c;void main(){c=sstt;}`, options)
|
|
248
|
-
|
|
249
|
-
// #version 300 es\nin vec2 b;out vec4 a[gl_MaxDrawBuffers];void main(){a[0]=b.sstt;}
|
|
250
|
-
minify(`#version 300 es\nin vec2 c;out vec4 data[gl_MaxDrawBuffers];void main(){data[0]=c.sstt;}`, options)
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## Parse
|
|
254
|
-
|
|
255
|
-
Parses a string of GLSL (WGSL is WIP) code into an [AST](#ast).
|
|
256
|
-
|
|
257
|
-
```ts
|
|
258
|
-
const ast: Program = parse(code: string)
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Generate
|
|
262
|
-
|
|
263
|
-
Generates a string of GLSL (WGSL is WIP) code from an [AST](#ast).
|
|
264
|
-
|
|
265
|
-
```ts
|
|
266
|
-
const code: string = generate(program: Program, {
|
|
267
|
-
target: 'GLSL' // | 'WGSL'
|
|
268
|
-
})
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
## Visit
|
|
272
|
-
|
|
273
|
-
Recurses through an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree), calling a visitor object on matching nodes.
|
|
274
|
-
|
|
275
|
-
```ts
|
|
276
|
-
visit(
|
|
277
|
-
program: Program,
|
|
278
|
-
visitors: {
|
|
279
|
-
Program: {
|
|
280
|
-
enter(node, ancestors) {
|
|
281
|
-
// Called before any descendant nodes are processed
|
|
282
|
-
},
|
|
283
|
-
exit(node, ancestors) {
|
|
284
|
-
// Called after all nodes are processed
|
|
285
|
-
}
|
|
286
|
-
},
|
|
287
|
-
Identifier(node, ancestors) {
|
|
288
|
-
// Called before any descendant nodes are processed (alias to enter)
|
|
289
|
-
}
|
|
290
|
-
} satisfies Visitors
|
|
291
|
-
)
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
## AST
|
|
295
|
-
|
|
296
|
-
An [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) loosely based on [ESTree](https://github.com/estree/estree) for GLSL and WGSL grammars.
|
|
297
|
-
|
|
298
|
-
### Node Objects
|
|
299
|
-
|
|
300
|
-
AST nodes extend `Node` objects which implement the following abstract interface:
|
|
301
|
-
|
|
302
|
-
```ts
|
|
303
|
-
interface Node {
|
|
304
|
-
type: string
|
|
305
|
-
}
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
The `type` field is a string representing the AST variant type which can determine the interface a node implements.
|
|
309
|
-
|
|
310
|
-
### Identifier
|
|
311
|
-
|
|
312
|
-
A variable identifier.
|
|
313
|
-
|
|
314
|
-
```ts
|
|
315
|
-
interface Identifier extends Node {
|
|
316
|
-
type: 'Identifier'
|
|
317
|
-
name: string
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### Literal
|
|
322
|
-
|
|
323
|
-
A shader literal representing a `bool`, `float`, `int`, or `uint` type.
|
|
324
|
-
|
|
325
|
-
```ts
|
|
326
|
-
interface Literal extends Node {
|
|
327
|
-
type: 'Literal'
|
|
328
|
-
value: string
|
|
329
|
-
}
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### ArraySpecifier
|
|
333
|
-
|
|
334
|
-
An array and its dimensions.
|
|
335
|
-
|
|
336
|
-
```ts
|
|
337
|
-
interface ArraySpecifier extends Node {
|
|
338
|
-
type: 'ArraySpecifier'
|
|
339
|
-
typeSpecifier: Identifier
|
|
340
|
-
dimensions: (Literal | Identifier | null)[]
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Program
|
|
345
|
-
|
|
346
|
-
Represents the root of an AST.
|
|
347
|
-
|
|
348
|
-
```ts
|
|
349
|
-
interface Program extends Node {
|
|
350
|
-
type: 'Program'
|
|
351
|
-
body: Statement[]
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
### ExpressionStatement
|
|
356
|
-
|
|
357
|
-
An expression as a standalone statement.
|
|
358
|
-
|
|
359
|
-
```ts
|
|
360
|
-
interface ExpressionStatement extends Node {
|
|
361
|
-
type: 'ExpressionStatement'
|
|
362
|
-
expression: Expression
|
|
363
|
-
}
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### BlockStatement
|
|
367
|
-
|
|
368
|
-
A block statement.
|
|
369
|
-
|
|
370
|
-
```ts
|
|
371
|
-
interface BlockStatement extends Node {
|
|
372
|
-
type: 'BlockStatement'
|
|
373
|
-
body: Statement[]
|
|
374
|
-
}
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
### DiscardStatement
|
|
378
|
-
|
|
379
|
-
A discard statement in fragment shaders.
|
|
380
|
-
|
|
381
|
-
```ts
|
|
382
|
-
interface DiscardStatement extends Node {
|
|
383
|
-
type: 'DiscardStatement'
|
|
384
|
-
}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
### PreprocessorStatement
|
|
388
|
-
|
|
389
|
-
A GLSL preprocessor statement with an optional value.
|
|
390
|
-
|
|
391
|
-
```ts
|
|
392
|
-
interface PreprocessorStatement extends Node {
|
|
393
|
-
type: 'PreprocessorStatement'
|
|
394
|
-
name: string
|
|
395
|
-
value: Expression[] | null
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### PrecisionQualifierStatement
|
|
400
|
-
|
|
401
|
-
A GLSL precision qualifier statement.
|
|
402
|
-
|
|
403
|
-
```ts
|
|
404
|
-
interface PrecisionQualifierStatement extends Node {
|
|
405
|
-
type: 'PrecisionQualifierStatement'
|
|
406
|
-
precision: PrecisionQualifier
|
|
407
|
-
typeSpecifier: Identifier
|
|
408
|
-
}
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### InvariantQualifierStatement
|
|
412
|
-
|
|
413
|
-
A GLSL invariant qualifier statement.
|
|
414
|
-
|
|
415
|
-
```ts
|
|
416
|
-
interface InvariantQualifierStatement extends Node {
|
|
417
|
-
type: 'InvariantQualifierStatement'
|
|
418
|
-
typeSpecifier: Identifier
|
|
419
|
-
}
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
### LayoutQualifierStatement
|
|
423
|
-
|
|
424
|
-
A layout qualifier statement.
|
|
425
|
-
|
|
426
|
-
```ts
|
|
427
|
-
interface LayoutQualifierStatement extends Node {
|
|
428
|
-
type: 'LayoutQualifierStatement'
|
|
429
|
-
layout: Record<string, string | boolean>
|
|
430
|
-
qualifier: StorageQualifier
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
### ReturnStatement
|
|
435
|
-
|
|
436
|
-
A return statement with an optional argument.
|
|
437
|
-
|
|
438
|
-
```ts
|
|
439
|
-
interface ReturnStatement extends Node {
|
|
440
|
-
type: 'ReturnStatement'
|
|
441
|
-
argument: Expression | null
|
|
442
|
-
}
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
### BreakStatement
|
|
446
|
-
|
|
447
|
-
A break statement.
|
|
448
|
-
|
|
449
|
-
```ts
|
|
450
|
-
interface BreakStatement extends Node {
|
|
451
|
-
type: 'BreakStatement'
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### ContinueStatement
|
|
456
|
-
|
|
457
|
-
A continue statement.
|
|
458
|
-
|
|
459
|
-
```ts
|
|
460
|
-
interface ContinueStatement extends Node {
|
|
461
|
-
type: 'ContinueStatement'
|
|
462
|
-
}
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
### IfStatement
|
|
466
|
-
|
|
467
|
-
An if-else statement.
|
|
468
|
-
|
|
469
|
-
```ts
|
|
470
|
-
interface IfStatement extends Node {
|
|
471
|
-
type: 'IfStatement'
|
|
472
|
-
test: Expression
|
|
473
|
-
consequent: Statement
|
|
474
|
-
alternate: Statement | null
|
|
475
|
-
}
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
### SwitchStatement
|
|
479
|
-
|
|
480
|
-
A switch statement.
|
|
481
|
-
|
|
482
|
-
```ts
|
|
483
|
-
interface SwitchStatement extends Node {
|
|
484
|
-
type: 'SwitchStatement'
|
|
485
|
-
discriminant: Expression
|
|
486
|
-
cases: SwitchCase[]
|
|
487
|
-
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
#### SwitchCase
|
|
491
|
-
|
|
492
|
-
A switch-case statement. `test` is null for a `default` case.
|
|
493
|
-
|
|
494
|
-
```ts
|
|
495
|
-
interface SwitchCase extends Node {
|
|
496
|
-
type: 'SwitchCase'
|
|
497
|
-
test: Expression | null
|
|
498
|
-
consequent: Statement[]
|
|
499
|
-
}
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
### WhileStatement
|
|
503
|
-
|
|
504
|
-
A while statement.
|
|
505
|
-
|
|
506
|
-
```ts
|
|
507
|
-
interface WhileStatement extends Node {
|
|
508
|
-
type: 'WhileStatement'
|
|
509
|
-
test: Expression
|
|
510
|
-
body: Statement
|
|
511
|
-
}
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
### DoWhileStatement
|
|
515
|
-
|
|
516
|
-
A do-while statement.
|
|
517
|
-
|
|
518
|
-
```ts
|
|
519
|
-
interface DoWhileStatement extends Node {
|
|
520
|
-
type: 'DoWhileStatement'
|
|
521
|
-
body: Statement
|
|
522
|
-
test: Expression
|
|
523
|
-
}
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### ForStatement
|
|
527
|
-
|
|
528
|
-
A for statement.
|
|
529
|
-
|
|
530
|
-
```ts
|
|
531
|
-
interface ForStatement extends Node {
|
|
532
|
-
type: 'ForStatement'
|
|
533
|
-
init: VariableDeclaration | Expression | null
|
|
534
|
-
test: Expression | null
|
|
535
|
-
update: Expression | null
|
|
536
|
-
body: Statement
|
|
537
|
-
}
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### FunctionDeclaration
|
|
541
|
-
|
|
542
|
-
A function declaration. `body` is null for overloads.
|
|
543
|
-
|
|
544
|
-
```ts
|
|
545
|
-
interface FunctionDeclaration extends Node {
|
|
546
|
-
type: 'FunctionDeclaration'
|
|
547
|
-
id: Identifier
|
|
548
|
-
qualifiers: PrecisionQualifier[]
|
|
549
|
-
typeSpecifier: Identifier | ArraySpecifier
|
|
550
|
-
params: FunctionParameter[]
|
|
551
|
-
body: BlockStatement | null
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
#### FunctionParameter
|
|
556
|
-
|
|
557
|
-
A function parameter within a function declaration.
|
|
558
|
-
|
|
559
|
-
```ts
|
|
560
|
-
interface FunctionParameter extends Node {
|
|
561
|
-
type: 'FunctionParameter'
|
|
562
|
-
id: Identifier | null
|
|
563
|
-
qualifiers: (ConstantQualifier | ParameterQualifier | PrecisionQualifier)[]
|
|
564
|
-
typeSpecifier: Identifier | ArraySpecifier
|
|
565
|
-
}
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
### VariableDeclaration
|
|
569
|
-
|
|
570
|
-
A variable declaration.
|
|
571
|
-
|
|
572
|
-
```ts
|
|
573
|
-
interface VariableDeclaration extends Node {
|
|
574
|
-
type: 'VariableDeclaration'
|
|
575
|
-
declarations: VariableDeclarator[]
|
|
576
|
-
}
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
#### VariableDeclarator
|
|
580
|
-
|
|
581
|
-
A variable declarator within a variable declaration.
|
|
582
|
-
|
|
583
|
-
```ts
|
|
584
|
-
interface VariableDeclarator extends Node {
|
|
585
|
-
type: 'VariableDeclarator'
|
|
586
|
-
id: Identifier
|
|
587
|
-
qualifiers: (ConstantQualifier | InterpolationQualifier | StorageQualifier | PrecisionQualifier)[]
|
|
588
|
-
typeSpecifier: Identifier | ArraySpecifier
|
|
589
|
-
layout: Record<string, string | boolean> | null
|
|
590
|
-
init: Expression | null
|
|
591
|
-
}
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### StructuredBufferDeclaration
|
|
595
|
-
|
|
596
|
-
A buffer interface declaration with optional layout and qualifiers.
|
|
597
|
-
|
|
598
|
-
```ts
|
|
599
|
-
interface StructuredBufferDeclaration extends Node {
|
|
600
|
-
type: 'StructuredBufferDeclaration'
|
|
601
|
-
id: Identifier | null
|
|
602
|
-
qualifiers: (InterfaceStorageQualifier | MemoryQualifier | LayoutQualifier)[]
|
|
603
|
-
typeSpecifier: Identifier | ArraySpecifier
|
|
604
|
-
layout: Record<string, string | boolean> | null
|
|
605
|
-
members: VariableDeclaration[]
|
|
606
|
-
}
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
### StructDeclaration
|
|
610
|
-
|
|
611
|
-
A struct declaration. Can be used as a type or constructor.
|
|
612
|
-
|
|
613
|
-
```ts
|
|
614
|
-
interface StructDeclaration extends Node {
|
|
615
|
-
type: 'StructDeclaration'
|
|
616
|
-
id: Identifier
|
|
617
|
-
members: VariableDeclaration[]
|
|
618
|
-
}
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
### ArrayExpression
|
|
622
|
-
|
|
623
|
-
An array initialization expression.
|
|
624
|
-
|
|
625
|
-
```ts
|
|
626
|
-
interface ArrayExpression extends Node {
|
|
627
|
-
type: 'ArrayExpression'
|
|
628
|
-
typeSpecifier: ArraySpecifier
|
|
629
|
-
elements: Expression[]
|
|
630
|
-
}
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
### UnaryExpression
|
|
634
|
-
|
|
635
|
-
A unary expression with a left or right handed operator.
|
|
636
|
-
|
|
637
|
-
```ts
|
|
638
|
-
interface UnaryExpression extends Node {
|
|
639
|
-
type: 'UnaryExpression'
|
|
640
|
-
operator: UnaryOperator
|
|
641
|
-
prefix: boolean
|
|
642
|
-
argument: Expression
|
|
643
|
-
}
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
#### UnaryOperator
|
|
647
|
-
|
|
648
|
-
```ts
|
|
649
|
-
type UnaryOperator = '-' | '+' | '!' | '~'
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
### UpdateExpression
|
|
653
|
-
|
|
654
|
-
An update expression with an optionally prefixed operator.
|
|
655
|
-
|
|
656
|
-
```ts
|
|
657
|
-
interface UpdateExpression extends Node {
|
|
658
|
-
type: 'UpdateExpression'
|
|
659
|
-
operator: UpdateOperator
|
|
660
|
-
argument: Expression
|
|
661
|
-
prefix: boolean
|
|
662
|
-
}
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
#### UpdateOperator
|
|
666
|
-
|
|
667
|
-
```ts
|
|
668
|
-
type UpdateOperator = '++' | '--'
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
### BinaryExpression
|
|
672
|
-
|
|
673
|
-
A binary expression with a left and right operand.
|
|
674
|
-
|
|
675
|
-
```ts
|
|
676
|
-
interface BinaryExpression extends Node {
|
|
677
|
-
type: 'BinaryExpression'
|
|
678
|
-
operator: BinaryOperator
|
|
679
|
-
left: Expression
|
|
680
|
-
right: Expression
|
|
681
|
-
}
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
#### BinaryOperator
|
|
685
|
-
|
|
686
|
-
```ts
|
|
687
|
-
type BinaryOperator =
|
|
688
|
-
| ','
|
|
689
|
-
| '=='
|
|
690
|
-
| '!='
|
|
691
|
-
| '<'
|
|
692
|
-
| '<='
|
|
693
|
-
| '>'
|
|
694
|
-
| '>='
|
|
695
|
-
| '<<'
|
|
696
|
-
| '>>'
|
|
697
|
-
| '+'
|
|
698
|
-
| '-'
|
|
699
|
-
| '*'
|
|
700
|
-
| '/'
|
|
701
|
-
| '%'
|
|
702
|
-
| '|'
|
|
703
|
-
| '^'
|
|
704
|
-
| '&'
|
|
705
|
-
```
|
|
706
|
-
|
|
707
|
-
### AssignmentExpression
|
|
708
|
-
|
|
709
|
-
An assignment expression.
|
|
710
|
-
|
|
711
|
-
```ts
|
|
712
|
-
interface AssignmentExpression extends Node {
|
|
713
|
-
type: 'AssignmentExpression'
|
|
714
|
-
operator: AssignmentOperator
|
|
715
|
-
left: Expression
|
|
716
|
-
right: Expression
|
|
717
|
-
}
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
#### AssignmentOperator
|
|
721
|
-
|
|
722
|
-
```ts
|
|
723
|
-
type AssignmentOperator = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '|=' | '^=' | '&='
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
### LogicalExpression
|
|
727
|
-
|
|
728
|
-
A logical operation between two expressions.
|
|
729
|
-
|
|
730
|
-
```ts
|
|
731
|
-
interface LogicalExpression extends Node {
|
|
732
|
-
type: 'LogicalExpression'
|
|
733
|
-
operator: LogicalOperator
|
|
734
|
-
left: Expression
|
|
735
|
-
right: Expression
|
|
736
|
-
}
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
#### LogicalOperator
|
|
740
|
-
|
|
741
|
-
```ts
|
|
742
|
-
type LogicalOperator = '||' | '&&' | '^^'
|
|
743
|
-
```
|
|
744
|
-
|
|
745
|
-
### MemberExpression
|
|
746
|
-
|
|
747
|
-
A member expression.
|
|
748
|
-
|
|
749
|
-
```ts
|
|
750
|
-
interface MemberExpression extends Node {
|
|
751
|
-
type: 'MemberExpression'
|
|
752
|
-
object: Expression
|
|
753
|
-
property: Expression
|
|
754
|
-
computed: boolean
|
|
755
|
-
}
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
### ConditionalExpression
|
|
759
|
-
|
|
760
|
-
A conditional expression or ternary.
|
|
761
|
-
|
|
762
|
-
```ts
|
|
763
|
-
interface ConditionalExpression extends Node {
|
|
764
|
-
type: 'ConditionalExpression'
|
|
765
|
-
test: Expression
|
|
766
|
-
alternate: Expression
|
|
767
|
-
consequent: Expression
|
|
768
|
-
}
|
|
769
|
-
```
|
|
770
|
-
|
|
771
|
-
### CallExpression
|
|
772
|
-
|
|
773
|
-
A function call expression or struct initialization.
|
|
774
|
-
|
|
775
|
-
```ts
|
|
776
|
-
interface CallExpression extends Node {
|
|
777
|
-
type: 'CallExpression'
|
|
778
|
-
callee: Expression
|
|
779
|
-
arguments: Expression[]
|
|
780
|
-
}
|
|
781
|
-
```
|
|
1
|
+
[](https://bundlephobia.com/package/shaderkit)
|
|
2
|
+
[](https://npmjs.com/package/shaderkit)
|
|
3
|
+
[](https://npmjs.com/package/shaderkit)
|
|
4
|
+
|
|
5
|
+
# shaderkit
|
|
6
|
+
|
|
7
|
+
Tools and IntelliSense for GLSL and WGSL.
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Tokenize](#tokenize)
|
|
13
|
+
- [Minify](#minify)
|
|
14
|
+
- [Parse](#parse)
|
|
15
|
+
- [Generate](#generate)
|
|
16
|
+
- [Visit](#visit)
|
|
17
|
+
- [AST](#ast)
|
|
18
|
+
- [Node Objects](#node-objects)
|
|
19
|
+
- [Identifier](#identifier)
|
|
20
|
+
- [Literal](#literal)
|
|
21
|
+
- [ArraySpecifier](#arrayspecifier)
|
|
22
|
+
- [Program](#program)
|
|
23
|
+
- Statements
|
|
24
|
+
- [ExpressionStatement](#expressionstatement)
|
|
25
|
+
- [BlockStatement](#blockstatement)
|
|
26
|
+
- [DiscardStatement](#discardstatement)
|
|
27
|
+
- [PreprocessorStatement](#preprocessorstatement)
|
|
28
|
+
- [PrecisionQualifierStatement](#precisionqualifierstatement)
|
|
29
|
+
- [InvariantQualifierStatement](#invariantqualifierstatement)
|
|
30
|
+
- [LayoutQualifierStatement](#layoutqualifierstatement)
|
|
31
|
+
- Control Flow
|
|
32
|
+
- [ReturnStatement](#returnstatement)
|
|
33
|
+
- [BreakStatement](#breakstatement)
|
|
34
|
+
- [ContinueStatement](#continuestatement)
|
|
35
|
+
- Choice
|
|
36
|
+
- [IfStatement](#ifstatement)
|
|
37
|
+
- [SwitchStatement](#switchstatement)
|
|
38
|
+
- [SwitchCase](#switchcase)
|
|
39
|
+
- Loops
|
|
40
|
+
- [WhileStatement](#whilestatement)
|
|
41
|
+
- [DoWhileStatement](#dowhilestatement)
|
|
42
|
+
- [ForStatement](#forstatement)
|
|
43
|
+
- Declarations
|
|
44
|
+
- [FunctionDeclaration](#functiondeclaration)
|
|
45
|
+
- [FunctionParameter](#functionparameter)
|
|
46
|
+
- [VariableDeclaration](#variabledeclaration)
|
|
47
|
+
- [VariableDeclarator](#variabledeclarator)
|
|
48
|
+
- [StructuredBufferDeclaration](#structuredbufferdeclaration)
|
|
49
|
+
- [StructDeclaration](#structdeclaration)
|
|
50
|
+
- Expressions
|
|
51
|
+
- [ArrayExpression](#arrayexpression)
|
|
52
|
+
- Unary Operations
|
|
53
|
+
- [UnaryExpression](#unaryexpression)
|
|
54
|
+
- [UnaryOperator](#unaryoperator)
|
|
55
|
+
- [UpdateExpression](#updateexpression)
|
|
56
|
+
- [UpdateOperator](#updateoperator)
|
|
57
|
+
- Binary Operations
|
|
58
|
+
- [BinaryExpression](#binaryexpression)
|
|
59
|
+
- [BinaryOperator](#binaryoperator)
|
|
60
|
+
- [AssignmentExpression](#assignmentexpression)
|
|
61
|
+
- [AssignmentOperator](#assignmentoperator)
|
|
62
|
+
- [LogicalExpression](#logicalexpression)
|
|
63
|
+
- [LogicalOperator](#logicaloperator)
|
|
64
|
+
- [MemberExpression](#memberexpression)
|
|
65
|
+
- [ConditionalExpression](#conditionalexpression)
|
|
66
|
+
- [CallExpression](#callexpression)
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
To install, use your preferred package manager:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install shaderkit
|
|
74
|
+
yarn add shaderkit
|
|
75
|
+
pnpm add shaderkit
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Or, use a CDN:
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<script type="module">
|
|
82
|
+
import * as shaderkit from 'https://unpkg.com/shaderkit'
|
|
83
|
+
</script>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Tokenize
|
|
87
|
+
|
|
88
|
+
Tokenizes a string of GLSL or WGSL code, returning an array of `Token` objects, where each `Token` object represents a single syntax feature in the input code.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
interface Token {
|
|
92
|
+
type: 'whitespace' | 'comment' | 'symbol' | 'bool' | 'float' | 'int' | 'identifier' | 'keyword'
|
|
93
|
+
value: string
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary>GLSL Example</summary>
|
|
99
|
+
|
|
100
|
+
<br />
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { tokenize } from 'shaderkit'
|
|
104
|
+
|
|
105
|
+
const code = 'void main() { gl_Position = vec4(0, 0, 0, 1); }'
|
|
106
|
+
const tokens = tokenize(code)
|
|
107
|
+
|
|
108
|
+
console.log(tokens)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The output of the above code will be:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
[
|
|
115
|
+
{ "type": "keyword", "value": "void" },
|
|
116
|
+
{ "type": "whitespace", "value": " " },
|
|
117
|
+
{ "type": "identifier", "value": "main" },
|
|
118
|
+
{ "type": "symbol", "value": "(" },
|
|
119
|
+
{ "type": "symbol", "value": ")" },
|
|
120
|
+
{ "type": "whitespace", "value": " " },
|
|
121
|
+
{ "type": "symbol", "value": "{" },
|
|
122
|
+
{ "type": "whitespace", "value": " " },
|
|
123
|
+
{ "type": "keyword", "value": "gl_Position" },
|
|
124
|
+
{ "type": "whitespace", "value": " " },
|
|
125
|
+
{ "type": "symbol", "value": "=" },
|
|
126
|
+
{ "type": "whitespace", "value": " " },
|
|
127
|
+
{ "type": "keyword", "value": "vec4" },
|
|
128
|
+
{ "type": "symbol", "value": "(" },
|
|
129
|
+
{ "type": "int", "value": "0" },
|
|
130
|
+
{ "type": "symbol", "value": "," },
|
|
131
|
+
{ "type": "whitespace", "value": " " },
|
|
132
|
+
{ "type": "int", "value": "0" },
|
|
133
|
+
{ "type": "symbol", "value": "," },
|
|
134
|
+
{ "type": "whitespace", "value": " " },
|
|
135
|
+
{ "type": "int", "value": "0" },
|
|
136
|
+
{ "type": "symbol", "value": "," },
|
|
137
|
+
{ "type": "whitespace", "value": " " },
|
|
138
|
+
{ "type": "int", "value": "1" },
|
|
139
|
+
{ "type": "symbol", "value": ")" },
|
|
140
|
+
{ "type": "symbol", "value": ";" },
|
|
141
|
+
{ "type": "whitespace", "value": " " },
|
|
142
|
+
{ "type": "symbol", "value": "}" }
|
|
143
|
+
]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
</details>
|
|
147
|
+
|
|
148
|
+
<details>
|
|
149
|
+
<summary>WGSL Example</summary>
|
|
150
|
+
|
|
151
|
+
<br />
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { tokenize } from 'shaderkit'
|
|
155
|
+
|
|
156
|
+
const code = '@vertex fn main() -> @builtin(position) vec4<f32> { return vec4(0, 0, 0, 1); }'
|
|
157
|
+
const tokens = tokenize(code)
|
|
158
|
+
|
|
159
|
+
console.log(tokens)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The output of the above code will be:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
[
|
|
166
|
+
{ "type": "symbol", "value": "@" },
|
|
167
|
+
{ "type": "keyword", "value": "vertex" },
|
|
168
|
+
{ "type": "whitespace", "value": " " },
|
|
169
|
+
{ "type": "keyword", "value": "fn" },
|
|
170
|
+
{ "type": "whitespace", "value": " " },
|
|
171
|
+
{ "type": "identifier", "value": "main" },
|
|
172
|
+
{ "type": "symbol", "value": "(" },
|
|
173
|
+
{ "type": "symbol", "value": ")" },
|
|
174
|
+
{ "type": "whitespace", "value": " " },
|
|
175
|
+
{ "type": "symbol", "value": "->" },
|
|
176
|
+
{ "type": "whitespace", "value": " " },
|
|
177
|
+
{ "type": "symbol", "value": "@" },
|
|
178
|
+
{ "type": "keyword", "value": "builtin" },
|
|
179
|
+
{ "type": "symbol", "value": "(" },
|
|
180
|
+
{ "type": "keyword", "value": "position" },
|
|
181
|
+
{ "type": "symbol", "value": ")" },
|
|
182
|
+
{ "type": "whitespace", "value": " " },
|
|
183
|
+
{ "type": "keyword", "value": "vec4" },
|
|
184
|
+
{ "type": "symbol", "value": "<" },
|
|
185
|
+
{ "type": "keyword", "value": "f32" },
|
|
186
|
+
{ "type": "symbol", "value": ">" },
|
|
187
|
+
{ "type": "whitespace", "value": " " },
|
|
188
|
+
{ "type": "symbol", "value": "{" },
|
|
189
|
+
{ "type": "whitespace", "value": " " },
|
|
190
|
+
{ "type": "keyword", "value": "return" },
|
|
191
|
+
{ "type": "whitespace", "value": " " },
|
|
192
|
+
{ "type": "keyword", "value": "vec4" },
|
|
193
|
+
{ "type": "symbol", "value": "(" },
|
|
194
|
+
{ "type": "int", "value": "0" },
|
|
195
|
+
{ "type": "symbol", "value": "," },
|
|
196
|
+
{ "type": "whitespace", "value": " " },
|
|
197
|
+
{ "type": "int", "value": "0" },
|
|
198
|
+
{ "type": "symbol", "value": "," },
|
|
199
|
+
{ "type": "whitespace", "value": " " },
|
|
200
|
+
{ "type": "int", "value": "0" },
|
|
201
|
+
{ "type": "symbol", "value": "," },
|
|
202
|
+
{ "type": "whitespace", "value": " " },
|
|
203
|
+
{ "type": "int", "value": "1" },
|
|
204
|
+
{ "type": "symbol", "value": ")" },
|
|
205
|
+
{ "type": "symbol", "value": ";" },
|
|
206
|
+
{ "type": "whitespace", "value": " " },
|
|
207
|
+
{ "type": "symbol", "value": "}" }
|
|
208
|
+
]
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
</details>
|
|
212
|
+
|
|
213
|
+
The following are the supported token types and their descriptions:
|
|
214
|
+
|
|
215
|
+
| Type | Description |
|
|
216
|
+
| ---------- | ------------------------------------------------------------------------- |
|
|
217
|
+
| whitespace | A sequence of one or more whitespace characters. |
|
|
218
|
+
| comment | A single-line or multi-line comment. |
|
|
219
|
+
| symbol | A symbol, such as an operator or punctuation mark. |
|
|
220
|
+
| bool | A boolean value, either true or false. |
|
|
221
|
+
| float | A floating-point number, represented by a sequence of digits and symbols. |
|
|
222
|
+
| int | An integer number, represented by a sequence of digits. |
|
|
223
|
+
| identifier | A user-defined identifier, such as a variable name or function name. |
|
|
224
|
+
| keyword | A keyword reserved by the language, such as if, else, for, etc. |
|
|
225
|
+
|
|
226
|
+
## Minify
|
|
227
|
+
|
|
228
|
+
Minifies a string of GLSL or WGSL code, returning a minified version of the input code.
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
const minified: string = minify(code: string, {
|
|
232
|
+
/** Whether to rename variables. Will call a MangleMatcher if specified. Default is `false`. */
|
|
233
|
+
mangle: boolean | ((token: Token, index: number, tokens: Token[]) => boolean)
|
|
234
|
+
/** A map to read and write renamed variables to when mangling. */
|
|
235
|
+
mangleMap: Map<string, string>
|
|
236
|
+
/** Whether to rename external variables such as uniforms or varyings. Default is `false`. */
|
|
237
|
+
mangleExternals: boolean
|
|
238
|
+
})
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
To shared mangled interfaces when using `mangleExternal`, declare and re-use a `mangleMap` between shaders:
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
const options = { mangle: true, mangleExternals: true, mangleMap: new Map() }
|
|
245
|
+
|
|
246
|
+
// #version 300 es\nin vec2 a;out vec2 b;void main(){b=a;}
|
|
247
|
+
minify(`#version 300 es\nin vec2 sstt;out vec2 c;void main(){c=sstt;}`, options)
|
|
248
|
+
|
|
249
|
+
// #version 300 es\nin vec2 b;out vec4 a[gl_MaxDrawBuffers];void main(){a[0]=b.sstt;}
|
|
250
|
+
minify(`#version 300 es\nin vec2 c;out vec4 data[gl_MaxDrawBuffers];void main(){data[0]=c.sstt;}`, options)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Parse
|
|
254
|
+
|
|
255
|
+
Parses a string of GLSL (WGSL is WIP) code into an [AST](#ast).
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const ast: Program = parse(code: string)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Generate
|
|
262
|
+
|
|
263
|
+
Generates a string of GLSL (WGSL is WIP) code from an [AST](#ast).
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
const code: string = generate(program: Program, {
|
|
267
|
+
target: 'GLSL' // | 'WGSL'
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Visit
|
|
272
|
+
|
|
273
|
+
Recurses through an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree), calling a visitor object on matching nodes.
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
visit(
|
|
277
|
+
program: Program,
|
|
278
|
+
visitors: {
|
|
279
|
+
Program: {
|
|
280
|
+
enter(node, ancestors) {
|
|
281
|
+
// Called before any descendant nodes are processed
|
|
282
|
+
},
|
|
283
|
+
exit(node, ancestors) {
|
|
284
|
+
// Called after all nodes are processed
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
Identifier(node, ancestors) {
|
|
288
|
+
// Called before any descendant nodes are processed (alias to enter)
|
|
289
|
+
}
|
|
290
|
+
} satisfies Visitors
|
|
291
|
+
)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## AST
|
|
295
|
+
|
|
296
|
+
An [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) loosely based on [ESTree](https://github.com/estree/estree) for GLSL and WGSL grammars.
|
|
297
|
+
|
|
298
|
+
### Node Objects
|
|
299
|
+
|
|
300
|
+
AST nodes extend `Node` objects which implement the following abstract interface:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
interface Node {
|
|
304
|
+
type: string
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The `type` field is a string representing the AST variant type which can determine the interface a node implements.
|
|
309
|
+
|
|
310
|
+
### Identifier
|
|
311
|
+
|
|
312
|
+
A variable identifier.
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
interface Identifier extends Node {
|
|
316
|
+
type: 'Identifier'
|
|
317
|
+
name: string
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Literal
|
|
322
|
+
|
|
323
|
+
A shader literal representing a `bool`, `float`, `int`, or `uint` type.
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
interface Literal extends Node {
|
|
327
|
+
type: 'Literal'
|
|
328
|
+
value: string
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### ArraySpecifier
|
|
333
|
+
|
|
334
|
+
An array and its dimensions.
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
interface ArraySpecifier extends Node {
|
|
338
|
+
type: 'ArraySpecifier'
|
|
339
|
+
typeSpecifier: Identifier
|
|
340
|
+
dimensions: (Literal | Identifier | null)[]
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Program
|
|
345
|
+
|
|
346
|
+
Represents the root of an AST.
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
interface Program extends Node {
|
|
350
|
+
type: 'Program'
|
|
351
|
+
body: Statement[]
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### ExpressionStatement
|
|
356
|
+
|
|
357
|
+
An expression as a standalone statement.
|
|
358
|
+
|
|
359
|
+
```ts
|
|
360
|
+
interface ExpressionStatement extends Node {
|
|
361
|
+
type: 'ExpressionStatement'
|
|
362
|
+
expression: Expression
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### BlockStatement
|
|
367
|
+
|
|
368
|
+
A block statement.
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
interface BlockStatement extends Node {
|
|
372
|
+
type: 'BlockStatement'
|
|
373
|
+
body: Statement[]
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### DiscardStatement
|
|
378
|
+
|
|
379
|
+
A discard statement in fragment shaders.
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
interface DiscardStatement extends Node {
|
|
383
|
+
type: 'DiscardStatement'
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### PreprocessorStatement
|
|
388
|
+
|
|
389
|
+
A GLSL preprocessor statement with an optional value.
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
interface PreprocessorStatement extends Node {
|
|
393
|
+
type: 'PreprocessorStatement'
|
|
394
|
+
name: string
|
|
395
|
+
value: Expression[] | null
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### PrecisionQualifierStatement
|
|
400
|
+
|
|
401
|
+
A GLSL precision qualifier statement.
|
|
402
|
+
|
|
403
|
+
```ts
|
|
404
|
+
interface PrecisionQualifierStatement extends Node {
|
|
405
|
+
type: 'PrecisionQualifierStatement'
|
|
406
|
+
precision: PrecisionQualifier
|
|
407
|
+
typeSpecifier: Identifier
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### InvariantQualifierStatement
|
|
412
|
+
|
|
413
|
+
A GLSL invariant qualifier statement.
|
|
414
|
+
|
|
415
|
+
```ts
|
|
416
|
+
interface InvariantQualifierStatement extends Node {
|
|
417
|
+
type: 'InvariantQualifierStatement'
|
|
418
|
+
typeSpecifier: Identifier
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### LayoutQualifierStatement
|
|
423
|
+
|
|
424
|
+
A layout qualifier statement.
|
|
425
|
+
|
|
426
|
+
```ts
|
|
427
|
+
interface LayoutQualifierStatement extends Node {
|
|
428
|
+
type: 'LayoutQualifierStatement'
|
|
429
|
+
layout: Record<string, string | boolean>
|
|
430
|
+
qualifier: StorageQualifier
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### ReturnStatement
|
|
435
|
+
|
|
436
|
+
A return statement with an optional argument.
|
|
437
|
+
|
|
438
|
+
```ts
|
|
439
|
+
interface ReturnStatement extends Node {
|
|
440
|
+
type: 'ReturnStatement'
|
|
441
|
+
argument: Expression | null
|
|
442
|
+
}
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### BreakStatement
|
|
446
|
+
|
|
447
|
+
A break statement.
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
interface BreakStatement extends Node {
|
|
451
|
+
type: 'BreakStatement'
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### ContinueStatement
|
|
456
|
+
|
|
457
|
+
A continue statement.
|
|
458
|
+
|
|
459
|
+
```ts
|
|
460
|
+
interface ContinueStatement extends Node {
|
|
461
|
+
type: 'ContinueStatement'
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### IfStatement
|
|
466
|
+
|
|
467
|
+
An if-else statement.
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
interface IfStatement extends Node {
|
|
471
|
+
type: 'IfStatement'
|
|
472
|
+
test: Expression
|
|
473
|
+
consequent: Statement
|
|
474
|
+
alternate: Statement | null
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### SwitchStatement
|
|
479
|
+
|
|
480
|
+
A switch statement.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
interface SwitchStatement extends Node {
|
|
484
|
+
type: 'SwitchStatement'
|
|
485
|
+
discriminant: Expression
|
|
486
|
+
cases: SwitchCase[]
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
#### SwitchCase
|
|
491
|
+
|
|
492
|
+
A switch-case statement. `test` is null for a `default` case.
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
interface SwitchCase extends Node {
|
|
496
|
+
type: 'SwitchCase'
|
|
497
|
+
test: Expression | null
|
|
498
|
+
consequent: Statement[]
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### WhileStatement
|
|
503
|
+
|
|
504
|
+
A while statement.
|
|
505
|
+
|
|
506
|
+
```ts
|
|
507
|
+
interface WhileStatement extends Node {
|
|
508
|
+
type: 'WhileStatement'
|
|
509
|
+
test: Expression
|
|
510
|
+
body: Statement
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### DoWhileStatement
|
|
515
|
+
|
|
516
|
+
A do-while statement.
|
|
517
|
+
|
|
518
|
+
```ts
|
|
519
|
+
interface DoWhileStatement extends Node {
|
|
520
|
+
type: 'DoWhileStatement'
|
|
521
|
+
body: Statement
|
|
522
|
+
test: Expression
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### ForStatement
|
|
527
|
+
|
|
528
|
+
A for statement.
|
|
529
|
+
|
|
530
|
+
```ts
|
|
531
|
+
interface ForStatement extends Node {
|
|
532
|
+
type: 'ForStatement'
|
|
533
|
+
init: VariableDeclaration | Expression | null
|
|
534
|
+
test: Expression | null
|
|
535
|
+
update: Expression | null
|
|
536
|
+
body: Statement
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### FunctionDeclaration
|
|
541
|
+
|
|
542
|
+
A function declaration. `body` is null for overloads.
|
|
543
|
+
|
|
544
|
+
```ts
|
|
545
|
+
interface FunctionDeclaration extends Node {
|
|
546
|
+
type: 'FunctionDeclaration'
|
|
547
|
+
id: Identifier
|
|
548
|
+
qualifiers: PrecisionQualifier[]
|
|
549
|
+
typeSpecifier: Identifier | ArraySpecifier
|
|
550
|
+
params: FunctionParameter[]
|
|
551
|
+
body: BlockStatement | null
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
#### FunctionParameter
|
|
556
|
+
|
|
557
|
+
A function parameter within a function declaration.
|
|
558
|
+
|
|
559
|
+
```ts
|
|
560
|
+
interface FunctionParameter extends Node {
|
|
561
|
+
type: 'FunctionParameter'
|
|
562
|
+
id: Identifier | null
|
|
563
|
+
qualifiers: (ConstantQualifier | ParameterQualifier | PrecisionQualifier)[]
|
|
564
|
+
typeSpecifier: Identifier | ArraySpecifier
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### VariableDeclaration
|
|
569
|
+
|
|
570
|
+
A variable declaration.
|
|
571
|
+
|
|
572
|
+
```ts
|
|
573
|
+
interface VariableDeclaration extends Node {
|
|
574
|
+
type: 'VariableDeclaration'
|
|
575
|
+
declarations: VariableDeclarator[]
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
#### VariableDeclarator
|
|
580
|
+
|
|
581
|
+
A variable declarator within a variable declaration.
|
|
582
|
+
|
|
583
|
+
```ts
|
|
584
|
+
interface VariableDeclarator extends Node {
|
|
585
|
+
type: 'VariableDeclarator'
|
|
586
|
+
id: Identifier
|
|
587
|
+
qualifiers: (ConstantQualifier | InterpolationQualifier | StorageQualifier | PrecisionQualifier)[]
|
|
588
|
+
typeSpecifier: Identifier | ArraySpecifier
|
|
589
|
+
layout: Record<string, string | boolean> | null
|
|
590
|
+
init: Expression | null
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### StructuredBufferDeclaration
|
|
595
|
+
|
|
596
|
+
A buffer interface declaration with optional layout and qualifiers.
|
|
597
|
+
|
|
598
|
+
```ts
|
|
599
|
+
interface StructuredBufferDeclaration extends Node {
|
|
600
|
+
type: 'StructuredBufferDeclaration'
|
|
601
|
+
id: Identifier | null
|
|
602
|
+
qualifiers: (InterfaceStorageQualifier | MemoryQualifier | LayoutQualifier)[]
|
|
603
|
+
typeSpecifier: Identifier | ArraySpecifier
|
|
604
|
+
layout: Record<string, string | boolean> | null
|
|
605
|
+
members: VariableDeclaration[]
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### StructDeclaration
|
|
610
|
+
|
|
611
|
+
A struct declaration. Can be used as a type or constructor.
|
|
612
|
+
|
|
613
|
+
```ts
|
|
614
|
+
interface StructDeclaration extends Node {
|
|
615
|
+
type: 'StructDeclaration'
|
|
616
|
+
id: Identifier
|
|
617
|
+
members: VariableDeclaration[]
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### ArrayExpression
|
|
622
|
+
|
|
623
|
+
An array initialization expression.
|
|
624
|
+
|
|
625
|
+
```ts
|
|
626
|
+
interface ArrayExpression extends Node {
|
|
627
|
+
type: 'ArrayExpression'
|
|
628
|
+
typeSpecifier: ArraySpecifier
|
|
629
|
+
elements: Expression[]
|
|
630
|
+
}
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### UnaryExpression
|
|
634
|
+
|
|
635
|
+
A unary expression with a left or right handed operator.
|
|
636
|
+
|
|
637
|
+
```ts
|
|
638
|
+
interface UnaryExpression extends Node {
|
|
639
|
+
type: 'UnaryExpression'
|
|
640
|
+
operator: UnaryOperator
|
|
641
|
+
prefix: boolean
|
|
642
|
+
argument: Expression
|
|
643
|
+
}
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
#### UnaryOperator
|
|
647
|
+
|
|
648
|
+
```ts
|
|
649
|
+
type UnaryOperator = '-' | '+' | '!' | '~'
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### UpdateExpression
|
|
653
|
+
|
|
654
|
+
An update expression with an optionally prefixed operator.
|
|
655
|
+
|
|
656
|
+
```ts
|
|
657
|
+
interface UpdateExpression extends Node {
|
|
658
|
+
type: 'UpdateExpression'
|
|
659
|
+
operator: UpdateOperator
|
|
660
|
+
argument: Expression
|
|
661
|
+
prefix: boolean
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
#### UpdateOperator
|
|
666
|
+
|
|
667
|
+
```ts
|
|
668
|
+
type UpdateOperator = '++' | '--'
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### BinaryExpression
|
|
672
|
+
|
|
673
|
+
A binary expression with a left and right operand.
|
|
674
|
+
|
|
675
|
+
```ts
|
|
676
|
+
interface BinaryExpression extends Node {
|
|
677
|
+
type: 'BinaryExpression'
|
|
678
|
+
operator: BinaryOperator
|
|
679
|
+
left: Expression
|
|
680
|
+
right: Expression
|
|
681
|
+
}
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
#### BinaryOperator
|
|
685
|
+
|
|
686
|
+
```ts
|
|
687
|
+
type BinaryOperator =
|
|
688
|
+
| ','
|
|
689
|
+
| '=='
|
|
690
|
+
| '!='
|
|
691
|
+
| '<'
|
|
692
|
+
| '<='
|
|
693
|
+
| '>'
|
|
694
|
+
| '>='
|
|
695
|
+
| '<<'
|
|
696
|
+
| '>>'
|
|
697
|
+
| '+'
|
|
698
|
+
| '-'
|
|
699
|
+
| '*'
|
|
700
|
+
| '/'
|
|
701
|
+
| '%'
|
|
702
|
+
| '|'
|
|
703
|
+
| '^'
|
|
704
|
+
| '&'
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### AssignmentExpression
|
|
708
|
+
|
|
709
|
+
An assignment expression.
|
|
710
|
+
|
|
711
|
+
```ts
|
|
712
|
+
interface AssignmentExpression extends Node {
|
|
713
|
+
type: 'AssignmentExpression'
|
|
714
|
+
operator: AssignmentOperator
|
|
715
|
+
left: Expression
|
|
716
|
+
right: Expression
|
|
717
|
+
}
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
#### AssignmentOperator
|
|
721
|
+
|
|
722
|
+
```ts
|
|
723
|
+
type AssignmentOperator = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '|=' | '^=' | '&='
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### LogicalExpression
|
|
727
|
+
|
|
728
|
+
A logical operation between two expressions.
|
|
729
|
+
|
|
730
|
+
```ts
|
|
731
|
+
interface LogicalExpression extends Node {
|
|
732
|
+
type: 'LogicalExpression'
|
|
733
|
+
operator: LogicalOperator
|
|
734
|
+
left: Expression
|
|
735
|
+
right: Expression
|
|
736
|
+
}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
#### LogicalOperator
|
|
740
|
+
|
|
741
|
+
```ts
|
|
742
|
+
type LogicalOperator = '||' | '&&' | '^^'
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
### MemberExpression
|
|
746
|
+
|
|
747
|
+
A member expression.
|
|
748
|
+
|
|
749
|
+
```ts
|
|
750
|
+
interface MemberExpression extends Node {
|
|
751
|
+
type: 'MemberExpression'
|
|
752
|
+
object: Expression
|
|
753
|
+
property: Expression
|
|
754
|
+
computed: boolean
|
|
755
|
+
}
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### ConditionalExpression
|
|
759
|
+
|
|
760
|
+
A conditional expression or ternary.
|
|
761
|
+
|
|
762
|
+
```ts
|
|
763
|
+
interface ConditionalExpression extends Node {
|
|
764
|
+
type: 'ConditionalExpression'
|
|
765
|
+
test: Expression
|
|
766
|
+
alternate: Expression
|
|
767
|
+
consequent: Expression
|
|
768
|
+
}
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### CallExpression
|
|
772
|
+
|
|
773
|
+
A function call expression or struct initialization.
|
|
774
|
+
|
|
775
|
+
```ts
|
|
776
|
+
interface CallExpression extends Node {
|
|
777
|
+
type: 'CallExpression'
|
|
778
|
+
callee: Expression
|
|
779
|
+
arguments: Expression[]
|
|
780
|
+
}
|
|
781
|
+
```
|