diff options
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 |
