boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs

commit 8e6c12f7c9592d655124146d115a456b531a6b9a
parent e25b794c8b51b72531be053c2f73e2f7d47374df
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 21 Apr 2026 17:10:54 -0700

lisp: concat prelude in make

Diffstat:
MMakefile | 45+++++++++++++++++++++++++++++++++++++--------
Asrc/prelude.scm | 23+++++++++++++++++++++++
2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/Makefile b/Makefile @@ -34,7 +34,11 @@ endif # Per-program runtime arguments. The lisp interpreter reads its script # from argv[1] (docs/LISP.md step 8). Default to its smoke fixture so # `make run-all` stays a smoke test. -RUN_ARGS_lisp ?= tests/lisp/00-identity.scm +# +# Lisp fixtures get src/prelude.scm cat'd in front of them (see the +# $(COMBINED_DIR) rule below) so map/filter/fold are in scope without +# the prelude living inside lisp.M1. +RUN_ARGS_lisp ?= $(COMBINED_DIR)/00-identity.scm RUN_ARGS := $(RUN_ARGS_$(PROG)) # Map P1 ARCH -> Linux-platform tag for the container. @@ -69,8 +73,9 @@ RUNTIME_IMAGE_amd64 := $(ALPINE_IMAGE)@sha256:4d889c14e7d5a73929ab00be2ef8ff22 RUNTIME_IMAGE_riscv64 := $(ALPINE_IMAGE)@sha256:667d07bf2f6239f094f64b5682c8ffbe24c9f3139b1fb854f85caf931a3d7439 RUNTIME_IMAGE := $(RUNTIME_IMAGE_$(ARCH)) -OUT_DIR := build/$(ARCH) -TOOLS_DIR := $(OUT_DIR)/tools +OUT_DIR := build/$(ARCH) +TOOLS_DIR := $(OUT_DIR)/tools +COMBINED_DIR := $(OUT_DIR)/combined # stage0-posix uses mixed-case arch dirs (AArch64, AMD64) that don't match # our lowercase ARCH. Map them so build/upstream/ mirrors upstream layout. @@ -114,9 +119,15 @@ toolchain: $(TOOLS_DIR)/M0 populate-upstream: $(UPSTREAM_STAMP) -$(OUT_DIR) $(TOOLS_DIR): +$(OUT_DIR) $(TOOLS_DIR) $(COMBINED_DIR): mkdir -p $@ +# Prepend src/prelude.scm to every lisp fixture via plain cat, producing +# a standalone .scm the interpreter can eval with its single-argv +# contract. Host-side — no podman needed, it's just byte concatenation. +$(COMBINED_DIR)/%.scm: tests/lisp/%.scm src/prelude.scm | $(COMBINED_DIR) + cat src/prelude.scm $< > $@ + $(IMAGE_STAMP): | $(OUT_DIR) podman pull --platform $(PLATFORM) $(RUNTIME_IMAGE) @touch $@ @@ -167,7 +178,10 @@ $(OUT_DIR)/$(PROG): $(OUT_DIR)/$(PROG).hex2 $(UPSTREAM_DIR)/$(ARCH_DIR)/ELF-$(AR $(TOOLS_DIR)/catm $(OUT_DIR)/$(PROG).linked.hex2 $(UPSTREAM_DIR)/$(ARCH_DIR)/ELF-$(ARCH).hex2 $(OUT_DIR)/$(PROG).hex2 ; \ $(TOOLS_DIR)/hex2-0 $(OUT_DIR)/$(PROG).linked.hex2 $(OUT_DIR)/$(PROG)' -run: $(OUT_DIR)/$(PROG) | $(IMAGE_STAMP) +# $(RUN_ARGS) is listed as a prerequisite so that lisp's concat'd fixture +# is materialised before the interpreter runs. Empty for hello/demo and +# therefore a no-op there. +run: $(OUT_DIR)/$(PROG) $(RUN_ARGS) | $(IMAGE_STAMP) $(PODMAN) ./$(OUT_DIR)/$(PROG) $(RUN_ARGS) # `-` prefix: continue past non-zero exit. demo.M1 exits with the computed @@ -198,14 +212,29 @@ LISP_TESTS := \ tests/lisp/14-io.scm \ tests/lisp/14-tagpred.scm \ tests/lisp/15-pred.scm \ - tests/lisp/16-prelude.scm + tests/lisp/16-prelude.scm \ + tests/lisp/20-quote.scm \ + tests/lisp/21-neg-hex.scm \ + tests/lisp/22-char.scm \ + tests/lisp/23-vector.scm \ + tests/lisp/24-dotted.scm \ + tests/lisp/25-set.scm \ + tests/lisp/26-let.scm \ + tests/lisp/27-cond.scm \ + tests/lisp/28-quasi.scm \ + tests/lisp/29-innerdef.scm + +# Build the prelude-prefixed twin of every fixture and feed that to the +# interpreter; .expected still lives next to the original .scm. +LISP_TESTS_COMBINED := $(patsubst tests/lisp/%.scm,$(COMBINED_DIR)/%.scm,$(LISP_TESTS)) -test-lisp: | $(IMAGE_STAMP) +test-lisp: $(LISP_TESTS_COMBINED) | $(IMAGE_STAMP) @$(MAKE) --no-print-directory PROG=lisp ARCH=$(ARCH) build/$(ARCH)/lisp @pass=0; fail=0; \ for scm in $(LISP_TESTS); do \ expected="$${scm%.scm}.expected"; \ - actual=$$($(PODMAN) ./build/$(ARCH)/lisp "$$scm" || true); \ + combined="$(COMBINED_DIR)/$$(basename $$scm)"; \ + actual=$$($(PODMAN) ./build/$(ARCH)/lisp "$$combined" || true); \ want=$$(cat "$$expected" 2>/dev/null || printf ''); \ if [ "$$actual" = "$$want" ]; then \ echo " PASS [$(ARCH)] $$scm"; \ diff --git a/src/prelude.scm b/src/prelude.scm @@ -0,0 +1,23 @@ +;; Prelude: map / filter / fold. Concatenated ahead of every user script +;; by the Makefile (cat src/prelude.scm $user.scm > combined.scm) so the +;; interpreter keeps its single-argv contract and lisp.M1 stays free of +;; embedded Scheme source. +(define map + (lambda (f xs) + (if (null? xs) + (quote ()) + (cons (f (car xs)) (map f (cdr xs)))))) + +(define filter + (lambda (p xs) + (if (null? xs) + (quote ()) + (if (p (car xs)) + (cons (car xs) (filter p (cdr xs))) + (filter p (cdr xs)))))) + +(define fold + (lambda (f acc xs) + (if (null? xs) + acc + (fold f (f acc (car xs)) (cdr xs)))))