diff options
| author | 2026-10-14 07:55:08 +0000 | |
|---|---|---|
| committer | 2026-10-14 07:55:08 +0000 | |
| commit | d8da21a406f449d277c42b91d4c9bf8b20bd0dcc (patch) | |
| tree | 79a4dbf6839eaee19aa626f1aa3981d5b0c19377 /ONBOARD.md | |
| parent | build: embed images with #embed, keep everything generated in build/ (diff) | |
embed: tests, editor support and docs; js vm file access; test fixes
embed declarations get accept and reject fixtures, a run-only image check
through zc0, an lsp keyword hover and the grammar keyword. errors point at
the declaration and still declare the name, so its uses are not reported
again. zc0 tracks byte-string globals and lays embedded arrays out one word
per element, the way its own indexing reads them.
the command-line javascript vm reaches node's file system for the file
syscalls, so include and embed work there; other embedders opt in.
the web build is self-contained in build/web with its examples. README,
BORROW and BOOTSTRAP-OWNERSHIP describe the new build and ownership rules,
and ONBOARD.md is a reading and verification order for the code.
the suite passes the map header to mklayout, the wasm fuzz program uses
the include format, and lsp drivers scale their deadlines on hosts
without the arm64 jit (ZC_TEST_TIMEOUT_SCALE). LLVM_CONFIG selects an
llvm with headers for the llvm section.
Diffstat (limited to 'ONBOARD.md')
| -rw-r--r-- | ONBOARD.md | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/ONBOARD.md b/ONBOARD.md new file mode 100644 index 0000000..7b0c045 --- /dev/null +++ b/ONBOARD.md @@ -0,0 +1,187 @@ +# onboarding + +a reading and verification order for getting from a fresh checkout to working +knowledge of tinyvm and zc. each step names what to read, what to run, and what +you should be able to answer afterwards. the steps build on each other, so follow +them in order; the whole pass takes a few hours, most of it reading. + +the order was recorded while learning the code from scratch, starting with the +markdown files (the fastest way in) and only then the sources. + +## 0. the shape of the repository + +read `README.md` from the top through "build and run", then skim its section +headings. list the tree: + +```sh +ls; ls src src/*; ls tests docs docs/design +``` + +- the root holds entry points only: `Makefile`, `tinyvm.sh`, `tinyvm.bat`, the + markdown files. +- `src/` holds every source: `core/` (the c vm), `micro/` (the portable vm), + `runtime/` and `compiler/` (zc sources that become the genome), `lib/` (std, + icon, actor), `lsp/` (the language server, in zc), `tools/` (bootstrap and build + tools), `js/`, `web/`, `baremetal/`. +- `build/` holds everything generated and is not in git. nothing outside it is + ever written by a build or a test. + +you should be able to say: what the genome is (the compiler and runtime, compiled +to vm words, embedded in every core), and which files make it +(`src/runtime/rt.zc`, `src/core/core.zc`, `src/compiler/compiler.zc`). + +## 1. build it from nothing + +the cores embed their genome with c23 `#embed`, so you need clang 19 or gcc 15 +or later; `sh src/tools/findcc.sh` prints the compiler `make` will use. + +```sh +make clean +make +build/bin/zy < examples/hello.zc +``` + +watch the output of `make`: the default memory map is generated +(`build/core/map/`), zc0 compiles the genome sources (stage 0), a core built +around that image compiles the compiler again (stage 1) and again (stage 2), the +two self-compiled images are compared, and the first becomes +`build/core/genome.bin`. then `zy`, `zym` and `zclsp` are built around it. + +you should be able to say: why the bootstrap needs three stages, what `mkgenome` +protects against (a compiler's error report taken for an image), and how a core +finds its image (`src/core/genome.h`, `--embed-dir`). + +## 2. the language, by example + +read `docs/LEARN.md` while running its examples: + +```sh +for f in examples/learn/*.zc; do echo "== $f"; build/bin/zy < $f; done +python3 tests/drivers/learn.py build/bin/zy +``` + +then read the language parts of `README.md`: "zc, the language", "memory model", +"types", "o3", "code as data". run a few of the larger examples +(`examples/lang.zc`, `examples/bf.zc`, `examples/dump.zc`, `examples/tree.zc`). + +you should be able to write a small program that includes `rt`, allocates with +`rt.new(T)`, passes an owner to a `.d` parameter, and returns one with `.u`; and +explain why `include rt;` is required before `rt.put_n`. + +## 3. ownership, the analyzer's view + +read `docs/BORROW.md`, then `docs/BOOTSTRAP-OWNERSHIP.md` (how two missing rules +once stopped the compiler compiling itself). run the rejection suites and read a +few of the fixtures, each of which starts with the message it expects: + +```sh +bash tests/runerr.sh build/bin/zy tests/errors +bash tests/runerr.sh build/bin/zy tests/typeerrors +bash tests/runerr.sh build/bin/zy tests/langerrors +``` + +in `src/compiler/compiler.zc`, find the block that starts at +`//: the rules below are the heart of the analyzer` and read `recast`, +`argcheck`, `assigncheck` and `retcheck`, then `exit_vars` and the `lend_*` +helpers. + +you should be able to say what states a local can be in (plain, m, u, d, child, +borrow, dead) and what each of `rt.free(r); r = replacement;` and `g = m*x;` +does to them. + +## 4. the compiler's structure + +`src/compiler/compiler.zc` is about ten thousand lines and begins with an +overview. read the overview, then use the section markers to navigate: + +```sh +grep -n "^//: ----" src/compiler/compiler.zc +``` + +read in this order: interning and symbols, the lexer (`lex1`), expressions +(`primary`, `unary`, `bin`, `expr`), statements and keywords (`add_kw` and the +`kw_*` functions), functions (`fndef`, `fn_begin`, `prologue`), globals +(`gdecl2`, `kw_embed`), then `chk_unit` (check mode for the language server) and +`build_image` (image mode for `src/tools/build.zc`). + +you should be able to say where a new keyword is registered, how a keyword +works at the top level and inside a function, and how the compiler emits a +byte-string literal into the code stream. + +## 5. the vm cores + +read "the instruction set", "memory map and abi", "how the core works" and "the +microcore" in `README.md`, then `docs/design/memory.md`. in `src/core/core.c`, +find `main` and follow it to `run(GORG)`; in `src/micro/micro.c`, `micro_run`. + +```sh +build/bin/genmap --preset default --check | head +ZYTRACE=1 build/bin/zy < tests/programs/o3.zc 2>&1 | head -20 +``` + +you should be able to say where the genome is loaded, where the syscall gate is, +and which backends (interpreter, arm64 jit, llvm, microcore, javascript, wasm) +run the same image. + +## 6. the toolchain around it + +read "language server", "vscode extension", "javascript & typescript runtime" +and "web" in `README.md`, then `editors/vscode/README.md`. build the rest: + +```sh +make js web lspimage +node build/js/tinyvm.js examples/hello.zc +build/bin/zclsp < examples/opt_test.zc +``` + +skim `src/lsp/server.zc` from its overview: the check (`check_doc`), hovers +(`do_hover`), navigation, the formatter (`fm_*`). + +you should be able to say how the editor gets diagnostics (the real compiler in +check mode), and why the javascript and wasm servers need no native build. + +## 7. the libraries + +read `docs/ICON.md` and `docs/ACTOR.md`, then the headers of `src/lib/std.zc`, +`src/lib/icon.zc` and `src/lib/actor.zc`. run their fixtures: + +```sh +python3 tests/drivers/icon_test.py +python3 tests/drivers/actor_test.py build/bin/zy +``` + +you should be able to say how `include actor;` adds the `actor` keyword without +any actor code in the compiler (`run.syntax`, `run.statement_hook`). + +## 8. the tests + +read the header of `tests/test.sh` and `docs/design/test-coverage.md`. run the +quick suite, then the whole one when there is time: + +```sh +make check +make test JOBS=4 +``` + +the suite builds its own map, bootstrap and cores in a scratch directory, so it +does not depend on what is in `build/`. on a host without the arm64 jit the +language server is interpreted and slow; `ZC_TEST_TIMEOUT_SCALE` stretches the +drivers' deadlines (the suite sets it). `LLVM_CONFIG` selects an llvm with +headers for the llvm section. + +## 9. history and open work + +`docs/history/README.md` is the scrapbook of earlier stages, `TODO.md` the +maintenance checklist, and `TASKLIST.md` the record of past requests. read the +open items in `TODO.md` last: by then each one should point at code you have +seen. + +## checklist + +after the pass you should be able to do each of these without looking anything up: + +- rebuild from `make clean`, and say which file each step writes under `build/` +- add a keyword to the compiler and rebuild the genome +- write a program that the analyzer rejects, and predict the message +- build a run-only image (`make run PROG=...`) and say why its source must fit zc0 +- find a built-in's declaration from a hover in the editor or with the server |
