commit 6408a180a619872e0e96da5be7871cb7ad81ad54
parent 4ea652af1d9ea5e7dc9869386da837c95ff76f49
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 23 Apr 2026 06:54:52 -0700
Describe m1m bootstrap path
Diffstat:
| M | post.md | | | 34 | ++++++++++++++++++++++++++++++++++ |
1 file changed, 34 insertions(+), 0 deletions(-)
diff --git a/post.md b/post.md
@@ -134,6 +134,40 @@ M0 to TCC (but no promises). Mostly it's just a cute base to work on.
(defn p1exe (src) (link (p1compile src)))
```
+That's the first trick: define only the tiny slice of generated P1 `DEFINE`s
+needed to write `m1m` in portable P1, then use `m1m` to describe the full P1
+surface in macros instead of by hand.
+
+```
+;; Bootstrap P1 in two steps.
+(define P1-min (catm P1-min.M1 m1m.M1))
+(define m1m (link (M0 P1-min)))
+(define P1 (m1m (catm P1-backend.M1M P1.M1M)))
+
+;; Now P1 is the portable executable substrate.
+(defn p1compile (src) (M0 (catm P1 (m1m src))))
+(defn p1exe (src) (link (p1compile src)))
+
+;; Build the language that will host the rest of the climb.
+(define scheme (p1exe scheme.M1))
+
+;; Scheme is small, but not just an evaluator: it is also the minimal shell
+;; language, with enough file I/O and spawn/wait to drive the build.
+(define cc-p1
+ (scheme cc.scm))
+
+(defn c->p1 (src)
+ (scheme cc.scm src))
+
+(defn cexe (src)
+ (p1exe (c->p1 src)))
+
+;; The Scheme driver compiles the pinned tcc-boot sources through cc-p1,
+;; then invokes M1/hex2 for each generated P1 unit.
+(define tcc-boot
+ (scheme build-tcc-boot.scm cc.scm tcc-boot-sources))
+```
+
So, what does P1 code with the macro expansion base look like?
```