Skip to content

6. Tooling loop: formatter + tests

This chapter explains the contributor “inner loop” for making changes safely:

  • format code consistently
  • run tests quickly
  • prevent drift between syntax, compiler, and tooling

End-to-end checklist

Just like in the previous chapter, use this checklist to keep the pipeline aligned while you work:

Keep the pipeline aligned (to avoid language/tooling drift):

  • Syntax crate (loaves/kernel/incan_syntax/): lexer → parser → AST → diagnostics
  • Formatter (loaves/compiler/incan_format/): prints AST back (idempotent; never emits invalid syntax)
  • Semantic core (loaves/kernel/incan_lang/): canonical vocab / shared semantic helpers (avoid duplicating “meaning” in multiple layers)
  • Compiler (loaves/compiler/):
    • typechecker (incan_frontend/) validates and annotates
    • lowering (incan_ir/) turns AST into IR
    • emission (incan_emit/) generates correct Rust
  • Runtime/stdlib (loaves/stdlib/<component>/{src,rust}/): behavior that can live outside the compiler should live here

Rule of thumb: prefer pushing shared meaning “down” into incan_lang/incan_syntax/the stdlib facets, and keep the driver (incan_driver/) and the incan command line (loaves/toolchain/incan-cli/) focused on orchestration and pipeline wiring.

Formatter (incan fmt)

The formatter is part of the toolchain and should remain aligned with the parser/AST:

See:

Where it lives:

  • loaves/compiler/incan_format/src/

Testing (Rust tests + integration checks)

Depending on your change, you will usually run:

  • make test for the Rust unit/integration test suite (fast feedback)
  • make pre-commit for a fast local gate (fmt-check + cargo check)
  • make pre-commit-full before pushing (fmt-check + tests + clippy)
  • make smoke-test when you want extra confidence (build + tests + examples + benchmarks-incan)

See:

A practical workflow

When you add a feature:

  1. add/adjust a small Rust regression test (parse/typecheck/codegen)
  2. run make test
  3. run make pre-commit as a quick local sanity pass
  4. run make pre-commit-full before opening the PR
  5. run make smoke-test if the change touches the pipeline end-to-end (parser/typechecker/codegen/tooling)

Next

Next chapter: 07. Tooling loop: LSP.