boot2

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

commit cf5f560c7bb3255588cc29a42027e9c9b4bfaa05
parent b186d29846b5a79aecd11a685b1517b3a2360b10
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sat, 25 Apr 2026 06:40:07 -0700

Use %tail / %tailr at every scheme1 tail position

Replace %call+%eret (and the lone %callr in apply) with the frame-popping
%tail / %tailr ops in every position that returns the callee's value
unmodified: eval -> apply / eval_if, eval_if -> eval (both branches),
eval_args -> cons, apply -> prim entry, parse_one -> parse_list /
parse_atom, parse_atom -> intern / parse_int, register_primitives ->
sym_set_global. The eval -> sym_global call stays %call because its
result is checked for UNBOUND before returning. Establishes the
LISP-C.md ยง11 invariant ahead of `lambda`.

Diffstat:
Mscheme1/scheme1.P1pp | 36+++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/scheme1/scheme1.P1pp b/scheme1/scheme1.P1pp @@ -398,8 +398,7 @@ %addi(a1, a0, -35) %beqz(a1, &::hash) - %call(&parse_atom) - %eret + %tail(&parse_atom) ::lparen # Consume '(' and read items until ')'. @@ -407,8 +406,7 @@ %ld(t1, t0, 0) %addi(t1, t1, 1) %st(t1, t0, 0) - %call(&parse_list) - %eret + %tail(&parse_list) ::rparen %die(msg_unexp_rparen, 6) @@ -563,13 +561,12 @@ %ld(t1, sp, 8) %ld(t2, sp, 0) %sub(a1, t1, t2) - %call(&intern) - %eret + %tail(&intern) ::is_int %ld(a0, sp, 0) %ld(a1, sp, 8) - %call(&parse_int) + %tail(&parse_int) }) # parse_int(start_off=a0, end_off=a1) -> tagged fixnum in a0. Leaf. @@ -668,17 +665,16 @@ %ld(a1, sp, 8) %call(&eval_args) - # apply(fn, args) + # apply(fn, args) -- tail call %mov(a1, a0) %ld(a0, sp, 16) - %call(&apply) - %eret + %tail(&apply) ::do_if %ld(a0, sp, 0) %cdr(a0, a0) %ld(a1, sp, 8) - %call(&eval_if) + %tail(&eval_if) }) # eval_args(args=a0, env=a1) -> evaluated args list (cons-built). @@ -702,11 +698,10 @@ %ld(a1, sp, 8) %call(&eval_args) - # cons(val, rest) + # cons(val, rest) -- tail call %mov(a1, a0) %ld(a0, sp, 16) - %call(&cons) - %eret + %tail(&cons) ::nil %li(a0, %imm_val(%IMM.NIL)) @@ -735,7 +730,7 @@ ::prim %ld(t0, a0, 5) ; t0 = entry word (offset = -3 + 8) %ld(a0, sp, 0) ; args list -> a0 - %callr(t0) + %tailr(t0) }) # ========================================================================= @@ -773,22 +768,21 @@ %li(t0, %imm_val(%IMM.FALSE)) %beq(a0, t0, &::else_branch) - # then-branch: eval(cadr(rest), env) + # then-branch: tail-eval(cadr(rest), env) %ld(a0, sp, 0) %cdr(a0, a0) %car(a0, a0) %ld(a1, sp, 8) - %call(&eval) - %eret + %tail(&eval) ::else_branch - # else-branch: eval(caddr(rest), env) + # else-branch: tail-eval(caddr(rest), env) %ld(a0, sp, 0) %cdr(a0, a0) %cdr(a0, a0) %car(a0, a0) %ld(a1, sp, 8) - %call(&eval) + %tail(&eval) }) # ========================================================================= @@ -825,7 +819,7 @@ %call(&intern) %untag_sym(a0, a0) ; idx %ld(a1, sp, 0) ; HEAP-tagged prim ptr - %call(&sym_set_global) + %tail(&sym_set_global) }) # prim_sys_exit_entry(args=a0). Args is a one-element list whose car is