SJON Reference
PNGine source is SJON: S-expression forms validated against the WebGPU
schema in schema/pngine.sjon.
Each form maps to a WebGPU resource or operation.
PNGine is a host of the SJON language:
SJON owns the syntax, validation, cross-reference resolution, expressions and
sugar lowering, while PNGine owns the schema above, the pngine/* lowering
hooks (the compiler steps that expand sugar into ordinary forms), and bytecode
emission. For the language itself (reader syntax, value kinds, how a schema is
written), see the
SJON documentation.
Quick Reference
Section titled “Quick Reference”Every named form also requires its :name; the column below lists what else the
form cannot compile without.
| Form | Purpose | Required |
|---|---|---|
(shader-module …) |
Named WGSL module | :code |
(buffer …) |
GPU buffer | :usage, and a size from :size, :data, :index-of or :file |
(texture …) |
GPU texture | :size, :format, :usage |
(texture-view …) |
Explicit view over a texture | :texture |
(sampler …) |
Texture sampler | - |
(query-set …) |
Occlusion / timestamp queries | :type, :count |
(bind-group-layout …) |
Explicit bind group layout | - (an (entry …) per binding is usual; an empty layout is legal WebGPU) |
(pipeline-layout …) |
Explicit pipeline layout | :bind-group-layouts |
(bind-group …) |
Resource binding | :layout |
(render-pipeline …) |
Render pipeline | :layout, (vertex …) |
(compute-pipeline …) |
Compute pipeline | :layout, (compute …) |
(render-pass …) |
Render pass | an attachment (a pass with attachments alone is a clear-only pass) |
(compute-pass …) |
Compute pass | :pipeline, one (dispatch …) |
(render-bundle …) |
Pre-recorded draw sequence | :color-formats, one (draw …) |
(frame …) |
Frame execution | :perform |
(data …) |
Embedded data / shapes | :float32, a shape sub-form, or :file |
(queue …) |
Queue operations | - (an empty queue is legal; several actions are usual) |
(image-bitmap …) |
Decoded image → texture | :data |
(wasm-call …) |
WASM function call | :file, :func, :returns |
(init …) |
One-shot compute init (sugar) | :buffer, :module, :workgroups |
(pass-graph …) |
Shader-art (pass …) sugar |
one (pass …) |
(define …) |
Compile-time constant | :value |
(limits …) |
Raised device limits (singleton) | - |
(canvas …) |
Canvas alpha mode (singleton) | - |
Categories
Section titled “Categories”Shader Resources
Section titled “Shader Resources”(shader-module …)- Named WGSL module
GPU Resources
Section titled “GPU Resources”(buffer …)- GPU buffer for vertex/uniform/storage/index data(texture …)- GPU texture resource(texture-view …)- Explicit view, required to sample 1d/3d/array/cube textures(sampler …)- Texture sampler configuration(image-bitmap …)- Decoded image → texture(query-set …)- GPU occlusion and timestamp queries
Pipelines
Section titled “Pipelines”(render-pipeline …)- Render pipeline configuration(compute-pipeline …)- Compute pipeline configuration(bind-group-layout …)- Explicit bind group layout(pipeline-layout …)- Compose layouts at@group0..N(bind-group …)- Resource binding to shaders
Passes
Section titled “Passes”(render-pass …)- Render pass with draw commands(compute-pass …)- Compute pass with dispatch(render-bundle …)- Pre-recorded draws replayed by a pass(pass-graph …)- Fullscreen shader-art sugar
Data & Queue
Section titled “Data & Queue”(data …)- Embedded float arrays, shape generators, image files, or WASM-generated bytes(queue …)- Buffer writes, copies, and query resolves(wasm-call …)- Call WASM module functions each frame
Control Flow
Section titled “Control Flow”(frame …)- Frame execution with pass ordering(init …)- One-shot compute init (once per loaded payload)(define …)- Compile-time constant
Device Configuration
Section titled “Device Configuration”(limits …)- Raise WebGPU device limits (e.g. large workgroups)(canvas …)- Canvas alpha mode
Concepts
Section titled “Concepts”- References - Bare identifier resolution and special values
- Expressions - Compile-time arithmetic and constants
Not in the schema
Section titled “Not in the schema”A few capabilities are deliberately absent today:
- Multi-file documents. There is no include or import form; keep every
shader, resource, pipeline, pass and frame in a single
.sjonfile. - Shader fragment composition.
(shader-module …)holds one self-contained WGSL module as opaque text; there is no fragment/imports mechanism. Repeat shared helper code in each module that needs it. - Timeline / scene scheduling. SJON models a frame loop; drive scene changes from the JavaScript API instead.
Syntax Overview
Section titled “Syntax Overview”(form-name :key value :flag true (sub-form positional :key value) [array of items])
; comments start with a semicolonValue Types
Section titled “Value Types”| Type | Example | Description |
|---|---|---|
| String | "WGSL code" / """multi-line""" |
Quoted / triple-quoted text |
| Number | 123, 0.5 |
Decimal or float |
| Boolean | true, false |
Boolean values |
| Symbol | myName, triangle-list |
Bare identifier (enum or cross-ref) |
| Array | [a b c] |
Space-separated list |
| Sub-form | (vertex :module code :entry vs) |
Positional nested form |
| Expression | (* NUM 16) |
Compile-time arithmetic |
Bare Identifier Resolution
Section titled “Bare Identifier Resolution”Resources are referenced by name. SJON’s validator resolves identifiers document-wide against the declared forms:
:pipeline mainPipeline ; resolves to a (render-pipeline …) or (compute-pipeline …):module shader ; resolves to a (shader-module …):buffer vertices ; resolves to a (buffer …)Names live in one namespace across every form kind, so a buffer and a texture
cannot share one, and the built-in spellings (canvas,
context-current-texture, preferred-canvas-format, pngine-inputs) cannot be
declared at all.
See References for complete resolution rules.