{"id":50816080,"url":"https://github.com/ydah/zwgsl","last_synced_at":"2026-06-13T09:33:51.008Z","repository":{"id":343487285,"uuid":"1176996302","full_name":"ydah/zwgsl","owner":"ydah","description":"Ruby-inspired shading language that compiles to WGSL and GLSL ES 3.0, with HM-style inference, pattern matching, an LSP server, and a WebGPU playground.","archived":false,"fork":false,"pushed_at":"2026-05-15T13:28:43.000Z","size":487,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-15T14:32:17.596Z","etag":null,"topics":["compiler","glsl","graphics-programming","lsp","playground","programming-language","shader","shading-language","type-inference","webgpu","wgsl","zig"],"latest_commit_sha":null,"homepage":"https://ydah.github.io/zwgsl/","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ydah.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-09T15:34:14.000Z","updated_at":"2026-05-15T13:28:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ydah/zwgsl","commit_stats":null,"previous_names":["ydah/zwgsl"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ydah/zwgsl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ydah%2Fzwgsl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ydah%2Fzwgsl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ydah%2Fzwgsl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ydah%2Fzwgsl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ydah","download_url":"https://codeload.github.com/ydah/zwgsl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ydah%2Fzwgsl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34279898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","glsl","graphics-programming","lsp","playground","programming-language","shader","shading-language","type-inference","webgpu","wgsl","zig"],"created_at":"2026-06-13T09:33:47.110Z","updated_at":"2026-06-13T09:33:51.003Z","avatar_url":"https://github.com/ydah.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zwgsl\n\nA Ruby-inspired shading language that compiles to WGSL (WebGPU) and GLSL ES 3.0.\nBuilt with Zig for fast compilation, a small runtime surface, and tooling that can\nship as a native library, an LSP server, or a browser wasm module.\n\nTry it in the [Playground](https://ydah.github.io/zwgsl/).\n\n## Why zwgsl?\n\nGPU shading languages are powerful, but the authoring experience is usually rigid:\nbraces everywhere, repetitive type annotations, and weak structure for reusable\nshader logic. `zwgsl` keeps shader code close to Ruby-style flow and expression\nsyntax while still targeting modern GPU backends.\n\n- `end` blocks instead of braces\n- layout-aware indentation and implicit statement separators\n- method chains, postfix conditionals, and implicit returns\n- `let` bindings, `where` clauses, `type`, `match`, `trait`, and `impl`\n- WGSL-first output with a retained GLSL ES 3.0 path\n\n## Features\n\n- Ruby-like syntax with `def`, `do`, `end`, symbols, method calls, and postfix `if` / `unless`\n- Indentation-sensitive layout resolver that inserts virtual indent / dedent / statement separators\n- `let` bindings and function-local `where` clauses\n- HM-style local type inference with let-generalization\n- Algebraic data types and constructor registration\n- Pattern matching with constructor, wildcard, binding, literal, and guarded arms\n- Dependent dimension matching for `Vec(N)`, `Mat(M, N)`, and tensor-style type applications\n- Generic structs, constructor inference, and phantom-type-safe annotations\n- `trait` / `impl` support with compile-time specialization and inline trait methods in WGSL output\n- Multi-stage WGSL pipeline with entry-point-aware HIR and SSA-style CFG MIR: `AST -\u003e HIR -\u003e MIR -\u003e WGSL`\n- WGSL sampler lowering for uniforms, function parameters, and immutable local aliases\n- Source-aware LSP support: diagnostics, hover with lowering previews, completion, signature help, goto-definition, document symbols, semantic tokens\n- Browser playground with Monaco, wasm compilation, and compiler-backed worker tooling\n- C API surface for embedding the compiler in other tools\n\n## Documentation\n\n- [Language Reference](docs/language.md)\n- [Grammar Summary](docs/spec.md)\n- [Feature Matrix](docs/feature-matrix.md)\n- [Builtins](docs/builtins.md)\n- [C API](docs/c-api.md)\n- [Gotchas](docs/gotchas.md)\n- [Migration From WGSL And GLSL](docs/migration.md)\n- [Design Notes](docs/design-notes.md)\n- [Architecture](docs/architecture.md)\n- [Roadmap](ROADMAP.md)\n- [Security Policy](SECURITY.md)\n- [Editor Setup](docs/editor-setup.md)\n- [Examples](examples/README.md)\n- [Contributing](CONTRIBUTING.md)\n\n## Quick Example\n\n`zwgsl` source:\n\n```ruby\nversion \"300 es\"\nprecision :fragment, :highp\n\nuniform :model_matrix, Mat4\nuniform :view_matrix, Mat4\nuniform :projection_matrix, Mat4\nuniform :light_pos, Vec3\nuniform :base_color, Vec4\n\ndef phong_strength(normal: Vec3, light_dir: Vec3) -\u003e Float\n  max(dot(normal.normalize, light_dir.normalize), 0.0)\nend\n\nvertex do\n  input :position, Vec3, location: 0\n  input :normal, Vec3, location: 1\n  varying :v_normal, Vec3\n  varying :v_world_pos, Vec3\n\n  def main\n    world_pos = model_matrix * vec4(position, 1.0)\n    self.v_normal = mat3(model_matrix) * normal\n    self.v_world_pos = world_pos.xyz\n    gl_Position = projection_matrix * view_matrix * world_pos\n  end\nend\n\nfragment do\n  varying :v_normal, Vec3\n  varying :v_world_pos, Vec3\n  output :frag_color, Vec4, location: 0\n\n  def main\n    light_dir = light_pos - v_world_pos\n    light = phong_strength(v_normal, light_dir)\n    frag_color = vec4(base_color.rgb * (0.2 + 0.8 * light), base_color.a)\n  end\nend\n```\n\nCompiled WGSL vertex output:\n\n```wgsl\nstruct VertexInput {\n    @location(0) position: vec3f,\n    @location(1) normal: vec3f,\n}\n\nstruct VertexOutput {\n    @builtin(position) gl_Position: vec4f,\n    @location(0) v_normal: vec3f,\n    @location(1) v_world_pos: vec3f,\n}\n\n@group(0) @binding(0) var\u003cuniform\u003e model_matrix: mat4x4f;\n@group(0) @binding(1) var\u003cuniform\u003e view_matrix: mat4x4f;\n@group(0) @binding(2) var\u003cuniform\u003e projection_matrix: mat4x4f;\nstruct _zwgsl_uniform_light_pos {\n    @align(16) value: vec3f,\n}\n@group(0) @binding(3) var\u003cuniform\u003e light_pos: _zwgsl_uniform_light_pos;\n@group(0) @binding(4) var\u003cuniform\u003e base_color: vec4f;\n\nvar\u003cprivate\u003e gl_Position: vec4f;\nvar\u003cprivate\u003e position: vec3f;\nvar\u003cprivate\u003e normal: vec3f;\nvar\u003cprivate\u003e v_normal: vec3f;\nvar\u003cprivate\u003e v_world_pos: vec3f;\n\nfn _zwgsl_vertex_main() {\n    let world_pos: vec4f = model_matrix * vec4f(position, 1.0);\n    v_normal = mat3x3f(model_matrix[0].xyz, model_matrix[1].xyz, model_matrix[2].xyz) * normal;\n    v_world_pos = world_pos.xyz;\n    gl_Position = projection_matrix * view_matrix * world_pos;\n}\n\n@vertex\nfn main(input: VertexInput) -\u003e VertexOutput {\n    position = input.position;\n    normal = input.normal;\n    _zwgsl_vertex_main();\n    var output: VertexOutput;\n    output.gl_Position = gl_Position;\n    output.v_normal = v_normal;\n    output.v_world_pos = v_world_pos;\n    return output;\n}\n```\n\nCompiled WGSL fragment output:\n\n```wgsl\nstruct FragmentInput {\n    @location(0) v_normal: vec3f,\n    @location(1) v_world_pos: vec3f,\n}\n\nstruct FragmentOutput {\n    @location(0) frag_color: vec4f,\n}\n\n@group(0) @binding(0) var\u003cuniform\u003e model_matrix: mat4x4f;\n@group(0) @binding(1) var\u003cuniform\u003e view_matrix: mat4x4f;\n@group(0) @binding(2) var\u003cuniform\u003e projection_matrix: mat4x4f;\nstruct _zwgsl_uniform_light_pos {\n    @align(16) value: vec3f,\n}\n@group(0) @binding(3) var\u003cuniform\u003e light_pos: _zwgsl_uniform_light_pos;\n@group(0) @binding(4) var\u003cuniform\u003e base_color: vec4f;\n\nvar\u003cprivate\u003e v_normal: vec3f;\nvar\u003cprivate\u003e v_world_pos: vec3f;\nvar\u003cprivate\u003e frag_color: vec4f;\n\nfn phong_strength(normal: vec3f, light_dir: vec3f) -\u003e f32 {\n    return max(dot(normalize(normal), normalize(light_dir)), 0.0);\n}\n\nfn _zwgsl_fragment_main() {\n    let light_dir: vec3f = light_pos.value - v_world_pos;\n    let light: f32 = phong_strength(v_normal, light_dir);\n    frag_color = vec4f(base_color.rgb * (0.2 + 0.8 * light), base_color.a);\n}\n\n@fragment\nfn main(input: FragmentInput) -\u003e FragmentOutput {\n    v_normal = input.v_normal;\n    v_world_pos = input.v_world_pos;\n    _zwgsl_fragment_main();\n    var output: FragmentOutput;\n    output.frag_color = frag_color;\n    return output;\n}\n```\n\n## Advanced Examples\n\nPattern matching over ADTs ([Open in Playground](https://ydah.github.io/zwgsl/?sample=adt-match)):\n\n```ruby\ntype Shape\n  Circle(radius: Float)\n  Rect(width: Float, height: Float)\n  Point\nend\n\ndef area(shape: Shape) -\u003e Float\n  match shape\n  when Circle(radius)\n    3.14159 * radius * radius\n  when Rect(width, height)\n    width * height\n  when Point\n    0.0\n  end\nend\n\ncompute do\n  def main\n    value: Float = area(Circle(2.0))\n  end\nend\n```\n\nDependent dimensions that lower to fixed-size WGSL types ([Open in Playground](https://ydah.github.io/zwgsl/?sample=dependent-dimensions)):\n\n```ruby\ncompute do\n  def main\n    transform: Mat(4, 4) = mat4(1.0)\n    value: Vec(4) = vec4(1.0)\n    energy: Float = dot(value, value)\n  end\nend\n```\n\nTrait-constrained specialization:\n\n```ruby\ntrait Numeric\n  def add(other: Self) -\u003e Self end\n  def mul(other: Self) -\u003e Self end\nend\n\nimpl Numeric for Float\n  def add(other: Self) -\u003e Self\n    self + other\n  end\n\n  def mul(other: Self) -\u003e Self\n    self * other\n  end\nend\n\ndef lerp(a: T, b: T, t: Float) -\u003e T where T: Numeric\n  a.mul(1.0 - t).add(b.mul(t))\nend\n\ncompute do\n  def main\n    value: Float = lerp(1.0, 2.0, 0.5)\n  end\nend\n```\n\n## Installation\n\n### From Source\n\nRequires Zig 0.15.x.\n\n```sh\ngit clone https://github.com/ydah/zwgsl\ncd zwgsl\nzig build -Doptimize=ReleaseFast\n```\n\n### Test Suite\n\n```sh\nzig build test\nbash script/validate_generated_wgsl.sh\nzig build benchmark\n```\n\n`script/validate_generated_wgsl.sh` validates generated WGSL fixtures when\n`naga`, `tint`, or `WGSL_VALIDATOR` is available.\nUse `WGSL_VALIDATOR_REQUIRED=1 bash script/validate_generated_wgsl.sh` or\n`bash script/validate_generated_wgsl.sh --require-validator` when a missing\nexternal validator should fail the run.\n`zig build benchmark` prints CSV compile-time measurements for representative\nexamples.\n\n### CLI\n\n```sh\nzig build\nzig-out/bin/zwgsl compile --target wgsl examples/hello_triangle.zw\nzig-out/bin/zwgsl check examples/hello_triangle.zw\nzig-out/bin/zwgsl fmt --check examples/hello_triangle.zw\nzig-out/bin/zwgsl source-map --stage vertex examples/hello_triangle.zw\nzig-out/bin/zwgsl lsp\n```\n\nUse `--target glsl-es-300` for GLSL ES 3.0 output, `--stage` to select a\nsingle generated stage, and `-o` / `--output` to write compile output to a file.\nUse `zwgsl fmt --write \u003cinput.zw\u003e` to rewrite a source file in place.\nUse `zwgsl source-map` to emit a JSON mapping from generated WGSL lines back to\nsource lines when debugging output.\n\n### Browser Wasm Build\n\n```sh\nzig build wasm\n```\n\nThat installs `zig-out/bin/zwgsl.wasm`, which the playground syncs into\n`playground/src/generated/zwgsl.wasm` so Vite can fingerprint the asset.\n\n## Artifacts\n\n`zig build` installs:\n\n- `zig-out/lib/libzwgsl.a`\n- `zig-out/lib/libzwgsl.dylib` or the platform equivalent shared library\n- `zig-out/include/zwgsl.h`\n- `zig-out/bin/zwgsl`\n- `zig-out/bin/zwgsl-lsp`\n\nThe repository also includes a `Dockerfile`, a Homebrew formula template under\n`packaging/homebrew/`, and an npm compiler package scaffold under\n`packages/compiler/`.\n\nTagged releases attach a Linux x86_64 CLI/LSP/library archive, a standalone\n`zwgsl.wasm` asset, and an `@zwgsl/compiler` npm package tarball with checksum\nfiles for each asset.\n\n## C API\n\nSee [C API](docs/c-api.md) for ABI/versioning, options, ownership, and C++\nintegration notes.\n\n```c\n#include \"zwgsl.h\"\n\nZwgslOptions options = zwgsl_options_default();\noptions.target = ZWGSL_TARGET_WGSL;\n\nZwgslResult result = zwgsl_compile(source, source_len, options);\n\nif (result.error_count == 0) {\n    if (result.vertex_source != NULL) {\n        puts(result.vertex_source);\n    }\n    if (result.fragment_source != NULL) {\n        puts(result.fragment_source);\n    }\n    if (result.compute_source != NULL) {\n        puts(result.compute_source);\n    }\n}\n\nzwgsl_free(\u0026result);\n```\n\n## LSP\n\nThe server entry point is `zwgsl-lsp`, implemented under `src/lsp/`.\nSee [Editor Setup](docs/editor-setup.md) for Neovim, Helix, VS Code, and Zed\nconfiguration notes, including the local VS Code extension in `editors/vscode`.\n\nCurrent editor-facing features:\n\n- incremental `didChange` with full-document change compatibility\n- diagnostics from compiler errors and warnings\n- hover with source-aware type / declaration info and method lowering previews\n- completion for locals, declarations, stage builtins, constructors, fields, and methods\n- signature help for functions, constructors, and supported builtins\n- code actions for common stage declaration, unused uniform, and type/constructor casing fixes\n- goto-definition for values, functions, and type declarations\n- document symbols for stages, declarations, functions, types, traits, and impls\n- document formatting through the same formatter used by `zwgsl fmt`\n- rename for resolved document-local symbols\n- semantic tokens for keywords, functions, variables, uniforms, varyings, builtins, constructors, traits, types, numbers, strings, comments, operators, and properties\n\n## Playground\n\nThe playground lives under `playground/` and uses Monaco plus the real wasm compiler build.\n\n```sh\ncd playground\nnpm install\nnpm run dev\n```\n\nThe repository also includes a GitHub Pages workflow that publishes the production\nbuild to `https://ydah.github.io/zwgsl/` when Pages is enabled with `GitHub Actions`\nas the publishing source.\n\nCurrent capabilities:\n\n- Monaco language registration for `zwgsl`\n- sample selector backed by repository examples and focused feature fixtures, with `?sample=\u003cid\u003e` direct links and `?source=\u003cbase64url\u003e` share links\n- live WGSL compilation through `zwgsl.wasm`\n- output tabs for combined WGSL, stage-specific WGSL, diagnostics, and generated resource layout\n- compiler-backed diagnostics, hover, completion, signature help, and goto-definition from the wasm build\n- WebGPU preview surface with animated `iTime` / `iResolution` uniforms, persisted generated controls with color pickers, sampler placeholders, and 2D texture upload\n- `npm run sync-wasm` to refresh the generated wasm asset from `zig-out/bin/zwgsl.wasm`\n\nFor a GitHub Pages build, set the base path before running Vite:\n\n```sh\ncd playground\nPLAYGROUND_BASE_PATH=/zwgsl/ npm run build\n```\n\n## Architecture\n\nSee [Architecture](docs/architecture.md) for the responsibilities of the\nfrontend, HIR/MIR WGSL path, retained GLSL path, diagnostics, and tooling entry\npoints.\n\n```mermaid\nflowchart TD\n    Source[\"Source (.zw)\"] --\u003e Lexer\n    Lexer --\u003e LayoutResolver[\"Layout Resolver\"]\n    LayoutResolver --\u003e Parser\n    Parser --\u003e AST\n\n    AST --\u003e HM[\"HM Inference + Sema\"]\n    HM --\u003e TypedAST[\"Typed AST\"]\n\n    TypedAST --\u003e HIR\n    TypedAST --\u003e IR\n\n    HIR --\u003e MIR\n    MIR --\u003e WGSLEmitter[\"WGSL Emitter\"]\n    WGSLEmitter --\u003e WGSL[\"WGSL / WebGPU\"]\n\n    IR --\u003e GLSLEmitter[\"GLSL Emitter\"]\n    GLSLEmitter --\u003e GLSL[\"GLSL ES 3.0\"]\n```\n\n## Project Status\n\nImplemented behavior is tracked here and in the [Feature Matrix](docs/feature-matrix.md).\nForward-looking work is tracked separately in the [Roadmap](ROADMAP.md).\n\n| Area | Status |\n| --- | --- |\n| Package version | 0.1.0 |\n| Verified Zig | 0.15.2 in CI; requires Zig 0.15.x |\n| Verified Node.js | 24 in CI for the playground |\n| Lexer + layout resolver | Implemented |\n| Parser + source positions | Implemented |\n| `let` / `where` | Implemented |\n| HM-style local inference | Implemented for local bindings and let-generalization |\n| ADTs + pattern matching | Implemented |\n| Dependent dimensions | Implemented for `Vec(N)` / `Mat(M, N)` matching and WGSL type lowering |\n| Generic structs + phantom tags | Implemented |\n| `trait` / `impl` specialization | Implemented as compile-time static dispatch with inline trait methods in WGSL output |\n| WGSL pipeline | Implemented as `AST -\u003e HIR -\u003e MIR -\u003e WGSL`, with entry-point HIR and SSA-style CFG-based MIR lowering |\n| GLSL ES 3.0 backend | Implemented |\n| LSP | Implemented |\n| Playground | Implemented |\n\n## Repository Layout\n\n```text\nsrc/\n  ast.zig\n  compiler.zig\n  hir.zig\n  hir_builder.zig\n  ir.zig\n  ir_builder.zig\n  layout.zig\n  lsp/\n  mir.zig\n  mir_builder.zig\n  parser.zig\n  sema.zig\n  typeclass.zig\n  wgsl_emitter.zig\ntests/\n  fixtures/\nexamples/\neditors/\n  vscode/\nplayground/\ninclude/\n```\n\n## License\n\nLicensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fydah%2Fzwgsl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fydah%2Fzwgsl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fydah%2Fzwgsl/lists"}