Your first Dazzle program
A Dazzle project is a folder with a dazzle.toml manifest. One manifest is one module. dz new makes one:
dz new hellohello/ dazzle.toml src/ main.dz .gitignoreThe manifest
Section titled “The manifest”[module]name = "hello"sources = ["src/**/*.dz"]
[dependencies]std = { open = true }
[build]output = "executable"sources lists the module’s files. Folders under src/ are organisation only: every file sees every other file’s declarations without an import, and declaration order never matters. std = { open = true } makes the standard library’s names, like String and List, usable without a std:: prefix. Modules has the rest.
The program
Section titled “The program”src/main.dz has a function, a call of it, and a test beside it:
fn main() { println!("{}", greeting("world"))}
fn greeting(name: &str) -> String { return format!("Hello, {}!", name)}
// `dz test` runs every `#[test]`; `dz run` and `dz build` leave them out.#[test]fn greets_by_name() { if greeting("Dazzle").as_str() != "Hello, Dazzle!" { panic!("the greeting should name who it greets") }}Run it from the project folder:
cd hellodz rundz checks the program, writes C++17, compiles it with your C++ compiler, and runs it, which prints Hello, world!. dz test runs the test. To see the C++ it wrote, run dz cpp and look in build/cpp/.
The dz command
Section titled “The dz command”| Command | Does |
|---|---|
dz new <dir> |
create a project there: a manifest and a hello world |
dz run [dir] |
build and run |
dz build [dir] |
build an executable into build/bin/ |
dz check [dir] |
analyse only: every diagnostic, no C++ compiler needed (--format=json for JSON) |
dz fix [dir] |
apply the fixes the compiler is certain of (--dry-run to list them) |
dz explain <code> |
what a diagnostic means, with a wrong and a right program |
dz test [dir] [filter] |
run the #[test] functions, each in its own process |
dz bench [dir] |
time the #[bench] functions (release mode by default) |
dz fmt <file> |
format in place (--stdout to print instead, --check to only report) |
dz expand <file> |
the file with every macro invocation expanded |
dz cpp [dir] |
write the generated C++ to build/cpp/ |
dz placements [dir] |
where each allocation goes, a region or the heap, and why (--format=json for JSON) |
dz lsp |
the language server, on stdio |
dir defaults to the current directory. run, build, cpp, test and bench take a build mode: --debug (the default, -O0 -g), --release (-O2 with link-time optimisation) or --shipping (-O3). --track-memory records every allocation and reports leaks and bad frees when the program exits.
A test, beside the code
Section titled “A test, beside the code”Tests are part of the language. Put a #[test] function next to what it covers:
fn clamp01(x: f32) -> f32 { if x < 0 { return 0 } if x > 1 { return 1 } return x}
#[test]fn clamp_keeps_values_in_range() { assert(clamp01(2) == 1) assert(clamp01(-3) == 0, "negative values clamp to zero")}dz test runs each test in its own process, so one crash does not hide the others. A normal build leaves every test out.
Examples to start from
Section titled “Examples to start from”ownership |
a growable array from scratch: own, the three special members, copies and moves; no C++ needed |
raylib |
a raylib window, with raylib compiled from source by dz |
rgfw |
a window from RGFW, a single-header C library |
breakout |
a small game: the rules are plain Dazzle, drawn with raylib |
stb |
a ray tracer that saves its image as a PNG with stb_image_write; no window |
sokol |
a particle fountain on sokol_app, sokol_gfx and sokol_gl |
box2d |
rigid-body physics with Box2D, drawn with sokol: two C libraries in one project |
miniaudio |
a synthesizer, generated sample by sample and played with miniaudio |
sdl3 |
a real-time 3D scene in GLSL, on SDL3 built by its own CMake |
Take the tour, starting with errors.
