Compiler17 min read

Compiler Coverage

Generated status map of the BWSL compiler feature surface.

Reading Time
17 min
Word Count
2,902
Sections
5
Try It Live

Turn the guide into code

Take the key idea from this page into the playground and validate it in a real shader instead of leaving it as theory.

Open Playground

This page is generated from the compiler repository feature inventory. It tracks the implemented language and tooling surface, while keeping public guidance centered on source-declared resources {} blocks and compiler-emitted reflection.

stable
77
compiler-sourced features
provisional
4
compiler-sourced features
implementation-defined
5
compiler-sourced features

Badge Legend

stable

Implemented, tested, and intended as supported user-facing behavior.

provisional

Implemented, but syntax, validation, or guidance may still change.

implementation-defined

Real compiler behavior that is not yet a polished language rule.

Stable

stable

Pipeline files

pipeline Name { ... } with imports, using declarations, attributes, resources, variants, compute graphs, constants, constraints, enums, structs, helper functions, and passes. Source files may also contain file-scope modules next to pipelines.

The source file is organized around render and compute pipeline construction instead of standalone shader entry points.

stable

Module files

File-scope module Name { ... } declarations in module-only or mixed module/pipeline source files, module imports, using declarations, constants, functions, structs, enums, and module-qualified Name::member access.

Shader libraries are first-class BWSL source units, not preprocessor includes.

stable

Submodules

File-scope submodule Name extends Parent { ... } declarations that fold additional constants, functions, structs, enums, imports, and using declarations into an existing parent module namespace.

Lets large shader libraries split implementation across files while preserving a single importable parent namespace.

stable

Import system

Embedded standard-library modules, import Math, comma-separated imports, import PBR as BRDF, using ModuleName for unqualified lookup, and compiler module search paths.

Keeps reusable shader code modular while preserving compiler-controlled symbol resolution and scoped local aliases.

stable

Lexical structure

ASCII identifiers, whitespace, line comments, nestable block comments, strings, integers, floats, scientific notation, hex, binary, unsigned suffixes, operators, decorators, and declaration keywords including using and as.

The lexer intentionally handles shader-specific ambiguity such as 0..10 ranges and value.x member access.

stable

Core scalar/vector/matrix types

bool, int, uint, float, int2/3/4, uint2/3/4, float2/3/4, mat2/3/4, void.

Uses concise GPU-native type names while targeting SPIR-V, Metal, HLSL, GLSL, and GLES.

stable

Resource types

texture2D, texture3D, textureCube, texture2DArray, sampler, buffer<T>, cbuffer<T>, plus custom struct-backed resources, including imported module structs declared with Module.Type.

BWSL separates source-level resource names from backend binding layout and emits reflection as ABI.

stable

Structs

Pipeline/module structs, custom nominal types, nested structs, arrays in fields, positional constructors, struct returns, member chains, methods, and module-defined resource payload shapes.

Structs are used both as shader data types and as reflected resource payload shapes.

stable

Struct methods

Methods declared inside struct bodies, implicit self, bare field access, field mutation from non-const methods, const receivers, receiver-based dispatch, overloads, and module-scoped struct methods.

Brings data-local behavior to shader structs while preserving value-style struct usage and const receiver checks.

stable

Type aliases

using Alias = Type, including built-in types, local custom types, and module-qualified targets through real module names or import aliases.

Gives verbose or module-qualified shader types concise scoped names without creating new nominal types.

stable

Fixed-size arrays

Canonical Type[N] name declarations for locals, struct fields, shared memory, resources, arrays of structs, multidimensional arrays, array indexing, dynamic indexing, and array field access.

Array sizes are part of the type, and the legacy postfix declarator form Type name[N] is rejected to keep declarations unambiguous.

stable

Pointers

Type^, prefix address-of ^value, postfix dereference ptr^, pointer parameters, pointer control flow, pointer-to-field and array-element patterns.

A shader language with explicit pointer syntax but a compact ^ design shared with XOR by position.

stable

Constructors and casts

Type constructors such as float3(...), splats, mixed vector construction, matrix construction, numeric conversions, scalar/vector casts.

Constructor calls double as explicit conversion syntax and are validated through the compiler type system.

stable

Expressions

Literals, identifiers, parenthesized expressions, calls, member access, array access, module qualification, enum qualification, ternary, assignments, and compound assignments.

Expression support is broad enough for production shader math without exposing backend-specific syntax.

stable

Operators

Arithmetic, comparison, logical, bitwise, shifts, unary plus/minus/not/bitwise-not, prefix/postfix increment/decrement, assignment and compound assignment.

BWSL keeps familiar C-family precedence while reserving skip as the continue-like statement.

stable

Swizzles

Vector .x/.y/.z/.w, .r/.g/.b/.a, multi-component swizzles, swizzle reads and writes, swizzles on function results.

The implementation tracks swizzles through composite lowering across backends.

stable

Control flow

Blocks, if/else, else if, single-statement bodies, C-style for, while, range for, collection for, foreach, loop, switch, return, break, skip, discard.

Includes several shader-friendly loop forms and conditional jump variants without macros.

stable

Conditional returns

return if (cond); and return expr if (cond);.

Concise early-exit syntax maps to guarded IR control flow.

stable

Conditional break/skip

break if (cond); and skip if (cond);.

Makes branch-heavy shader loops less noisy while preserving structured control flow.

stable

Range loops

for (i in 0..n), inclusive 0..=n, and stepped by ranges.

Gives shader code a compact iteration syntax that still lowers to backend loops.

stable

Collection loops

for (item in values) and implicit for (values) using it.

Provides high-level iteration syntax over compiler-recognized collections and arrays.

stable

Multi-range foreach

foreach (x in 0..w, y in 0..h).

Directly expresses nested grid expansion patterns common in shader generation.

stable

Loop statement

loop (count), loop { ... }, and loop { ... } until (cond).

Offers count-driven and post-condition loops in a single construct.

stable

Switch

switch (expr), multi-value case, default, variant-specialized switch pruning, fallthrough-related behavior covered by regression tests.

Supports shader-friendly finite branching without requiring chained if ladders, including compile-time selection for variant switches.

stable

Discard

discard; in fragment-style control flow.

Maps directly to fragment kill/discard behavior across targets.

stable

Functions

name :: (params) -> return_type { ... }, pipeline/pass/module/enum scopes, overloads by parameter types, custom return types.

The :: declaration form distinguishes definitions from calls and makes module qualification visually consistent.

stable

Function overloading

Overloads keyed by parameter types, including module functions and methods.

Provides library ergonomics without backend preprocessor tricks.

stable

Recursion rejection

Recursive calls are rejected by the test suite.

Keeps lowering finite and shader-target friendly.

stable

Pass-block-returning functions

name :: (...) -> pass_block { pass { ... } }, direct pass "Name" = helper() instantiation, module-qualified helpers, attribute/resource/variant mappings, compile-time constant arguments, and graphics or compute pass bodies.

Packages reusable complete pass shapes while letting caller pipelines bind their own interface names and variants.

stable

Stage assignment

vertex = func(), fragment = func(), compile-time ternary selection, and parameter substitution.

Makes shader variants compositional without duplicating full pass blocks.

stable

Pass-stage reuse

vertex = "OtherPass".vertex and fragment = "OtherPass".fragment.

Lets one pass reuse stage code from another pass by name.

stable

Depth-only passes

fragment = null.

Explicitly models graphics passes that only need vertex/depth output.

stable

Type-pattern dispatch

Generic bodies with float2: expr, float3: { ... }, and default: arms.

Compile-time dispatch by concrete shader type gives generic code backend-static output.

stable

Enums

Plain enums, optional integer underlying type, explicit values, auto values, module-qualified enum access.

Enums can be used both as shader constants and variant choices.

stable

Payload enums

Sum-type variants such as Sphere(float radius) and Box(float3 size).

This is uncommon in shader languages and enables algebraic data modeling in GPU code.

stable

Enum methods

Methods declared inside enum bodies, optional eval, implicit self.

Brings behavior near data definitions without requiring global helper naming conventions.

stable

Shader pipelines

Passes with graphics stages or compute stages, pass-scoped resources/attributes/functions/constants.

The language describes multi-pass pipelines, not just individual shader functions.

stable

Graphics passes

vertex { ... } plus optional fragment { ... }, use attributes, use resources, pass-level outputs { ... }, varyings through output.* and input.*.

Varyings and fragment color outputs are declared from source instead of duplicated in backend-specific shader interfaces.

stable

Compute passes

compute "Name" [x, y, z] { ... }, workgroup size, compute-only validation, no attributes.

Compute entry metadata lives in the source next to the shader body.

stable

Attributes

Pipeline attributes { name: type }, first attribute must be position, pass-level use attributes { ... }.

Vertex layout is declared in BWSL source, then selected per pass.

stable

Attribute decorators

@compressed(...) and @instance.

Supports engine-oriented vertex packing and instancing directly in the language surface.

stable

Optional attributes

use attributes { normal? } introduces variants.has_normal.

Pass inputs and variant specialization are connected automatically.

stable

Pipeline resources block

resources { viewProj: mat4; colorTex: texture2D; particles: buffer<Particle>; frame: RenderTypes.FrameData; }, selected per pass with use resources.

Resource names are validated at source level instead of only through external config.

stable

Optional resources

use resources { colorTex?, colorSampler? } introduces variants.has_resource_colorTex and related facts.

Resource availability becomes part of the variant system automatically.

stable

Resource reflection

Binding JSON/reflection generated by compiler options; resource stage and access usage collected from IR.

The compiler, not the source author, owns the final ABI mapping.

stable

Shader built-in namespaces

attributes.*, input.*, output.*, resources.*, variants.*, and self.

These namespaces provide a compact, target-independent shader ABI.

stable

Vertex built-ins

input.vertex_id, input.instance_id; output.position.

Backend-specific names like gl_VertexIndex are hidden behind BWSL names.

stable

Fragment built-ins

input.position for fragment coordinates, default output.color, output.depth, discard.

Fragment coordinates, default color output, and depth writes are backend-normalized.

stable

Fragment color outputs

Pass-level outputs { name: type } declarations, declaration-order locations, explicit @location(n), and fragment writes to declared output.name fields.

Multiple render targets are source-declared while output.depth remains a separate depth builtin.

stable

Compute built-ins

input.global_id, input.local_id, input.workgroup_id, input.num_workgroups, input.local_index.

Mirrors common compute concepts across Metal, HLSL, GLSL, and SPIR-V.

stable

User varyings

Any non-builtin output.name from vertex can be read as input.name in fragment, with optional @flat and @noperspective interpolation decorators on vertex output writes.

Varying declarations and interpolation modes are inferred from use instead of requiring duplicate interface blocks.

stable

Shared memory

shared Type[N] name in compute stages.

First-class group-shared storage with tests for reductions, tiling, and atomics.

stable

Barriers

barrier(), memoryBarrier(), storageBarrier() for compute-oriented synchronization.

Abstracts target-specific barrier spellings and SPIR-V opcodes.

stable

Atomics

atomic_add, atomic_min, atomic_max, atomic_and, atomic_or, atomic_xor, atomic_exchange, atomic_cmp_exchange.

Exposes a compact atomic catalog that lowers to backend-specific intrinsics.

stable

Texture and image operations

sample, sample_lod, sample_bias, sample_grad, sample_cmp, offset variants, gather, load, store, texture_size, texture_levels.

Supports both combined and explicit texture/sampler call shapes where implemented.

stable

Derivatives

ddx, ddy, fine/coarse variants, fwidth, fine/coarse variants, fragment-only.

Normalizes derivative spelling across shader targets.

stable

Math intrinsics

lerp, smoothstep, saturate, fract, step, clamp, sign, abs, min, max, floor, ceil, round, trunc, mod, fmod, fma, pow, sqrt, rsqrt, rcp, exp, exp2, log, log2, log10, frexp, ldexp, modf.

The source names are BWSL names; backend aliases like mix and frac are rejected as source-level compatibility aliases.

stable

Trig intrinsics

sin, cos, tan, asin, acos, atan, atan2, sincos, sinh, cosh, tanh, degrees, radians.

Includes paired and hyperbolic functions tested through backend output and equivalence cases.

stable

Vector and matrix intrinsics

dot, cross, normalize, length, distance, reflect, refract, faceforward, transpose, determinant, inverse.

Handles matrix/vector semantics through IR rather than textual backend substitution.

stable

Bit and packing intrinsics

count_bits, reverse_bits, first_bit_low, first_bit_high, bitfield_extract, bitfield_insert, pack/unpack_unorm*, pack/unpack_snorm*, pack/unpack_half2x16, f32tof16, f16tof32, asfloat, asint, asuint.

Provides portable bit manipulation and packing used by compressed vertex formats and GPU data paths.

stable

Boolean reductions and classification

any, all, isnan, isinf, isfinite, isnormal.

Covers vector boolean reduction and floating classification in a backend-neutral way.

stable

Select intrinsic

select(false_value, true_value, condition).

Documents the exact argument order, avoiding target-specific mix/select ambiguity.

stable

Variants block

variants { name: bool = false; mode: Enum = EnumValue; rules { ... } }.

Variants are first-class compile-time specialization inputs rather than preprocessor defines.

stable

Variant rules

require lhs -> rhs; and conflict lhs, rhs;, validated against selected variants.

Lets source declare legal feature combinations for shader specialization.

stable

Variant specialization

CLI -variant name=value, reflection, compile-time pruning of variants.* if/ternary/switch selectors and stage selection.

Ties configuration, code elimination, reflection, and pass input optionality together.

stable

Diagnostic JSON and error codes

Human-readable diagnostics include BWSL... codes, source ranges, token details, pass/stage context, and resolved module-file paths. -errors-json emits schema-versioned JSON for single-file, batch, and watch integrations.

Gives tools stable identifiers and structured locations without parsing terminal-oriented compiler output.

stable

AST JSON export

-ast-json emits schema bwsl.ast.v2 with root/module/pipeline AST nodes, node counts, source positions, declaration type/name positions, and parsed doc comments from /// or / ... */.

Lets IDEs, code browsers, and documentation tools consume compiler-authored structure instead of maintaining a parallel parser.

stable

Batch compilation

Multiple positional files, recursive directory inputs, and -manifest inputs normalize into a deduplicated job list. Batch mode compiles every unit, mirrors directory outputs under -o, shares module source reads across the batch, and aggregates -errors-json results.

Makes whole-project shader validation and asset baking a first-class compiler workflow instead of an external loop over single-file invocations.

stable

Watch mode

-watch performs an initial build, polls source and imported module files, rescans directory and manifest inputs for added or removed .bwsl files, and emits one text or JSON build report per rebuild.

Gives editors and engines a portable hot-reload compiler process with parseable rebuild events.

stable

Standard modules

Embedded Math, Random, Noise, Color, Compression, Debug, Packing, PBR, Globals, PostFX, Sampling, SDF, and Spaces, usable through direct imports, import aliases, and using declarations.

Standard modules are available without a module search path, while their names are reserved so project files cannot accidentally override the compiler-provided library.

stable

Production-style examples

tests/from_engine and tests/prod_shaders cover world, character, shadow, postprocess, particles, UI, crowd, material preview.

The language is exercised against engine-shaped shaders, not only tiny grammar tests.

stable

Backend generation

SPIR-V first, cross-compilation to Metal, HLSL, GLSL 450, GLSL ES 300, and direct GLES path.

A single source language targets native and web graphics stacks.

stable

WASM compiler

Emscripten build exposing compile and symbol APIs.

Enables editor/browser integration for BWSL compilation and autocomplete.

stable

VS Code extension

tools/vscode-bwsl with .bwsl syntax highlighting, language configuration, and snippets.

Gives the language a bundled editor surface without requiring a separate extension repository.

stable

Specification draft and BNF grammar

docs/spec/ contains the canonical spec draft, and docs/spec/bwsl.bnf describes source syntax accepted by the current parser.

Keeps language changes reviewable next to the compiler and test suite while giving tooling authors an exact grammar reference.

stable

Diagnostics and conformance tests

Error tests for missing semicolons, bad intrinsics, stage misuse, unknown imports, pointer ternary rejection, recursion, duplicate compute blocks, oversized arrays.

The test suite documents both accepted and intentionally rejected behavior.

stable

Fuzz regression corpus

More than 200 fuzz-found .bwsl regression files.

Maturity is backed by adversarial parser/lowering coverage, not just examples.

Provisional

provisional

Stage-returning functions

Functions returning vertex_function, fragment_function, and parsed compute_function return types. Vertex and fragment stage assignment is exercised heavily; compute functions are parsed but not exposed through the normal compute "Name" [x,y,z] pass grammar.

Treats shader stage bodies as composable compile-time values.

provisional

Eval blocks and eval statements

eval { ... }, eval declarations, eval if, eval for, eval while, eval loop, eval function declarations, compile-time expansion.

BWSL already has compile-time shader generation, but the README says it is moving toward a cleaner comptime model.

provisional

Compile-time evaluator

Scalar constant evaluation, local eval bindings, substitutions, expansion budget, variant-aware cloning.

Enables parser-driven specialization today, with planned migration out of parser logic.

provisional

Compute graph

Pipeline-level compute_graph { node "Pass" { inputs { ... } outputs { ... } } }, dependency validation, topological order, barrier derivation.

Starts to encode pass/resource scheduling in source, but public semantics are not settled.

Implementation-Defined

implementation-defined

Constants

const at module, pipeline, pass, and local scopes; compile-time evaluated scalar constants where possible.

Constants participate in parser-time and specialization flows, enabling stage selection and variant pruning.

implementation-defined

Parameter syntax

Canonical Type name, plus accepted name: Type, module-qualified types, pointers, arrays, and anonymous parameters in some contexts.

Eases authoring and migration while the spec can standardize a canonical style.

implementation-defined

Flag enums

Explicit-valued integer enums support bitwise operations, with flag-like auto values using powers of two.

Gives shader authors bitmask types without separate macro constants.

implementation-defined

Pattern-match arms

Variant arms, payload bindings, _ wildcard, default, expression bodies, block bodies, implicit match on self.

Adds algebraic-data-style matching to shader code while lowering to ordinary IR.

implementation-defined

Wave/subgroup operations

wave_sum, wave_product, wave_min, wave_max, wave_all, wave_any, wave_broadcast, wave_read_first.

Gives cross-backend subgroup operations under one naming scheme.

Generation

Generated by bun scripts/generate-compiler-reference.ts from compiler-reference/features.md.