- install rust/cargo
- install a C toolchain with
gcc - work from the repo root
- prefer the self-hosted compiler for feature work
- keep the Cranelift backend and self-hosted frontend healthy together
the smallest useful validation loop is:
cargo test -p pith-cli
./self-host/pith_main check <file>
make run-examples-self
make run-regressions-self
make bootstrap
if ./self-host/pith_main does not exist yet, build it first:
make self-host
recommended smoke loop for this repo:
cargo build --release
./target/release/pith run examples/hello.pith
make self-host
./self-host/pith_main check examples/hello.pith
make run-examples-self
make run-regressions-self
make bootstrap
- read the relevant subsystem before editing
- keep changes behavior-preserving unless the task explicitly changes semantics
- add or preserve stable error codes for new diagnostics
- validate the bootstrap and self-hosted paths for compiler changes
- prefer small helpers and explicit ownership over long inline flows
- prefer interpolation for direct value printing:
print("count: {items.len()}") - use
std.fmtwhen you need a reusable template, literal braces, or common collection display helpers - use
std.collectionshelpers likemap_list,filter_list,fold_list, andcount_byfor straightforward list transforms - use
std.io.string_buffer()for incremental text assembly in loops or builders - avoid long chains of
"..." + value.to_string()in user-facing examples unless interpolation would be awkward - inside a
testblock use the built-inassert(...)/assert_eq(...); a failingstd.testingcheck only tallies and will not fail the test (see docs/testing.md) - prefer
std.os.process.command(...)for child processes; usestd.iowhen you specifically need lower-level stream types - remember that collections are shared handles; reach for
std.collections.copy_list(...),copy_map(...), orcopy_set(...)when an example wants an independent top-level container - prefer typed results like
T!Ewhen callers need to inspect the error payload; keep bareT!for simpler string-error paths - use
catch,unwrap_or(...), andor_else(...)in examples when they make recovery intent clearer than manualis_errbranching
- native backend CLI:
cranelift/cli/src/main.rs - IR lowering and native code generation:
cranelift/codegen/src/ - self-hosted implementation:
self-host/ - runtime support:
cranelift/runtime/src/ - native tls and higher-level protocol work:
std/net/tls.pith,std/net/tls13.pith,std/net/http.pith,std/net/websocket.pith - language and diagnostic docs:
docs/
cargo test -p pith-cli
cargo build --release
./target/release/pith run examples/hello.pith
make self-host
./self-host/pith_main run examples/hello.pith
make run-examples-self
make run-regressions-self
make bootstrap
for tls-facing changes, add a live sanity check after the normal loop:
./self-host/pith_main run tests/live/test_tls_echo_live.pith