Flash

Setup

From clone to running compiler in two commands.

README · Vision · Tutorial · Reference · Cookbook · Setup · Versioning · Changelog · License

--- How to build and run the Flash compiler (`flashc`). ## Requirements - **Zig 0.16.0**, exactly. The version is hard-pinned (see `.zigversion`) and the build fails fast on any other version. Install from [ziglang.org/download](https://ziglang.org/download/) or with a version manager (zigup / zvm / anyzig). ## Build ```sh git clone https://github.com/ajhahnde/Flash.git cd Flash zig build ``` The `flashc` binary lands in `zig-out/bin/flashc`. ## Run ```sh # version zig-out/bin/flashc --version # inspect the token stream zig-out/bin/flashc --dump-tokens examples/clear.flash # reformat a .flash file in place (--check reports without writing) zig-out/bin/flashc fmt examples/hello.flash # transpile a .flash file to Zig (lowered source on stdout) zig build run -- examples/hello.flash # the same, written to a file instead of stdout zig-out/bin/flashc examples/hello.flash -o hello.zig # transpile a whole source tree: every .flash under src/ lands in gen/ as a # .zig twin mirroring its relative path; the first compile error stops the # build with a non-zero exit zig-out/bin/flashc build src gen ``` Compile errors print the offending source line with a `^` caret under the exact spot (and a `~` tail when the error spans more than one character): ``` flashc: broken.flash:2:9: error: unknown name 'nope' _ = nope.sys.write() ^~~~ ``` Pass `--plain-diagnostics` (any argument position) to get the bare one-line `file:line:col: error: message` form instead — handy for grep-style tooling that keys on one diagnostic per line. ### Tracing Zig errors back to Flash source The emitted Zig is compiled by the Zig toolchain, so a type error caught there is reported against the *generated* file. Pass `--anchors` (any argument position) and every lowered top-level constant and function is prefixed with a comment naming the Flash line it came from: ```sh zig-out/bin/flashc --anchors examples/hello.flash > hello.zig ``` ```zig // hello.flash:12 export fn main(...) callconv(.c) noreturn { ``` A Zig error inside that function now reads back to `hello.flash:12` by eye. The comment names the file only (no directories), and without the flag the emitted bytes are unchanged. ## Using Flash in your own project Flash compiles to readable Zig, so a Flash project is a Zig project with one extra step: transpile the Flash sources, then let `zig build` compile the result. A minimal layout: ``` my-project/ ├── build.zig — ordinary Zig build script (below) ├── src/ — your .flash sources └── gen/ — the transpiled .zig twins (generated, ignorable) ``` `flashc build src gen` keeps `gen/` mirrored to `src/`, and this `build.zig` wires the two steps together so `zig build` does both: ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); // Transpile every .flash file under src/ into gen/. Point the first // argument at your flashc binary (here: on PATH). const transpile = b.addSystemCommand(&.{ "flashc", "build", "src", "gen" }); // Compile the generated Zig as an ordinary executable. const exe = b.addExecutable(.{ .name = "my-app", .root_module = b.createModule(.{ .root_source_file = b.path("gen/main.zig"), .target = target, .optimize = optimize, }), }); exe.step.dependOn(&transpile.step); b.installArtifact(exe); } ``` A compile error in any Flash source stops the transpile step non-zero, so `zig build` halts with the Flash diagnostic — file, line, and caret — before the Zig compiler ever runs. For errors the Zig toolchain catches in the generated code, add `--anchors` to the `flashc build` command line and each generated declaration carries a comment naming its Flash origin. ## Test ```sh zig build test ``` Runs the per-module unit tests (lexer, parser, semantic checker, lowering, and the formatter), the integration suite (`tests/`), the build-driver harness (`zig build test-driver` — file outputs, exit codes, and flag composition), and the Flash-source test suite together. The latter can also run on its own: ```sh zig build test-flash ``` This transpiles each `.flash` file under `tests/flash/` with the freshly built `flashc` and runs the emitted Zig `test` blocks — Flash code testing itself through its own `test "name" { }` form. ## Self-hosting The compiler's maintained source is Flash, under `selfhost/`. By convention the handwritten Zig compiler under `src/` is *stage0* — the frozen bootstrap seed that keeps a clean clone buildable with nothing but a Zig toolchain — the compiler built from the Flash sources is *stage1* (`flashc-stage1`), and the compiler stage1 builds from those same sources is *stage2* (`flashc-stage2`). Six build steps drive and certify the bootstrap: ```sh # build flashc-stage1: stage0 transpiles every selfhost module and the # result is compiled as the self-hosted compiler zig build stage1 # build flashc-stage2: the same composition, with stage1 as the transpiler — # the self-hosted compiler compiling its own sources zig build stage2 # transpile each selfhost module and run its Flash test blocks # (also part of `zig build test`) zig build test-selfhost # transpile each standard-library module (std/) and run its Flash test # blocks (also part of `zig build test`) zig build test-std # transpile each language-server module (tools/lsp/) and run its Flash # test blocks (also part of `zig build test`) zig build test-lsp # build flashd, the Flash language server (diagnostics over stdio; see # editors/nvim/README.md for the editor wiring) zig build lsp # run flashc and flashc-stage1 over every example, probe, and test source # and assert byte-identical transpile, --dump-tokens, and fmt behaviour zig build diff-corpus # the bootstrap fixpoint: assert stage1 and stage2 emit byte-identical Zig # over every selfhost source and example, deterministically across runs zig build fixpoint ``` ## Shell helpers (optional) `flash.env.zsh` provides a `flash` verb dispatcher. Source it from your shell profile: ```sh echo "[[ -f $PWD/flash.env.zsh ]] && source $PWD/flash.env.zsh" >> ~/.zshrc # then, from anywhere: # flash build | flash test | flash tokens examples/clear.flash | flash clean ``` --- [← Prev: Reference](REFERENCE.md) · [Next: Versioning →](VERSIONING.md)