commit b280ec862a18b1cedc49854477f5297ea99a9146
parent f5dbc20f05f0180d5dc05a8d6f31d2746ee65d33
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Tue, 21 Apr 2026 07:12:34 -0700
LISP.md: reorder staged plan — argv/tests/primitives before extensions
Split the old step 4 reader claim into a core (done) and extensions
bucket, and sequence post-eval work so the test harness lands before
the feature surface grows. New order: TAIL → argv → tests → primitives
→ reader ext → eval ext → GC → pmatch → REPL → source-loc table →
end-to-end.
Diffstat:
| M | LISP.md | | | 40 | ++++++++++++++++++++++++++++------------ |
1 file changed, 28 insertions(+), 12 deletions(-)
diff --git a/LISP.md b/LISP.md
@@ -474,24 +474,40 @@ coverage before the next begins.
3. **Strings + symbol interning.** Heap strings, 4096-slot intern table,
symbol allocator. Two `(intern "foo")` calls return `eq?` pointers.
~400 LOC.
-4. **Reader.** End-to-end `source → sexpr`, plus the source-location
- side table. Test: parse a 200-LOC Scheme file; print the tree back
- and diff; inject a syntax error and confirm `line:col` in the
- diagnostic. ~850 LOC.
+4. **Reader (core).** End-to-end `source → sexpr` for lists, decimal
+ fixnums, interned symbols, `;` comments, with line/col tracking for
+ diagnostics. Extended syntax (quotes, strings, `#t`/`#f`, `#\char`,
+ `#( … )`, improper `.` tail, hex/negative fixnums) and the
+ source-location side table land in later steps. ~500 LOC.
5. **Printer.** `display`, `write`, minimal `format`. Closes a
read-print cycle. ~300 LOC.
6. **Eval (non-tail).** Self-evaluators, lookup, `if`, `begin`,
`lambda`, `define`, application via P1 `CALL`. ~600 LOC.
7. **`TAIL` integration.** Rewrite tail-position `eval` calls to P1
`TAIL`. Stress: loop of 10^6 self-calls with flat P1 stack.
-8. **Primitives (40).** Mechanical once the FFI harness exists. ~500
- LOC.
-9. **Mark-sweep GC.** Mark bitmap, root discipline, sweep, size-classed
- free lists. Stress: cons-churn allocating 1000× heap in flight.
- ~500 LOC.
-10. **`pmatch` + records-via-vectors.** ~300 LOC.
-11. **REPL.** `--repl` flag, line reader, eval-print loop. ~100 LOC.
-12. **End-to-end.** Run a 200-LOC Scheme test program exercising all
+8. **`argv[1]` file read.** Replace the embedded `src_text` blob with a
+ syscall path: open and read the file named on the command line into
+ a heap string; `error` on `argc < 2`.
+9. **Test harness (`tests/lisp/`).** Add `.scm` fixtures plus `make
+ test-lisp` (single arch) and `make test-lisp-all` (tri-arch diff);
+ pass = exit 0 and expected stdout. Locks in regression coverage
+ before the feature surface grows.
+10. **Primitives (~40).** Mechanical once the FFI harness exists.
+ ~500 LOC.
+11. **Reader extensions.** `'`/`` ` ``/`,`/`,@`, strings, `#t`/`#f`,
+ `#\char`, `#( … )`, improper `.` tail, hex and negative fixnums.
+ Source-location side table explicitly deferred to step 16.
+12. **Eval extensions.** `set!`, `let`/`let*`/`letrec`, `cond`,
+ `quasiquote`; inner `define` → `letrec`-shape rewrite.
+13. **Mark-sweep GC.** Mark bitmap, root discipline, sweep, size-classed
+ free lists. Stress: cons-churn allocating 1000× heap in flight.
+ ~500 LOC.
+14. **`pmatch` + records-via-vectors.** ~300 LOC.
+15. **REPL.** `--repl` flag, line reader, eval-print loop. ~100 LOC.
+16. **Source-location side table.** Pair-pointer → `(line . col)` hash
+ populated by the reader, consulted by `error`, swept alongside
+ pairs so dead entries drop. ~200 LOC.
+17. **End-to-end.** Run a 200-LOC Scheme test program exercising all
features; diff tri-arch output.
Rough rollup: ~4,600 P1 LOC (includes source-location side table),