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:
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