commit d0d3057776b05d688243ddcc08503a6a2c5434ff
parent d58e86959f8f535523f43e86174c3db43f297b44
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 30 Apr 2026 18:26:10 -0700
scheme1: replace advance_walk(offset) with advance_walk(name)
Macro now takes a local name and uses %ldl/%stl internally, so call
sites are self-documenting without expanding to 3 lines each.
Diffstat:
| M | scheme1/scheme1.P1pp | | | 101 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
1 file changed, 46 insertions(+), 55 deletions(-)
diff --git a/scheme1/scheme1.P1pp b/scheme1/scheme1.P1pp
@@ -151,11 +151,30 @@
# Intern a special-form name and stash the tagged-symbol value in a
# labeled slot. `name` and `slot` are written as full label refs
# (`&foo`) so the macro can substitute them verbatim into %la sites.
-%macro intern_form(name, len, slot)
- %la(a0, name)
- %li(a1, len)
+# Pad the string `str` (including its M1 auto-null) to an 8-byte boundary.
+# Uses quoted-literal hex form required by riscv64 stage0 M0.
+%macro align8_pad(str)
+ %select((= (% (+ (strlen str) 1) 8) 0), ,
+ %select((= (% (+ (strlen str) 1) 8) 1), '00000000000000',
+ %select((= (% (+ (strlen str) 1) 8) 2), '000000000000',
+ %select((= (% (+ (strlen str) 1) 8) 3), '0000000000',
+ %select((= (% (+ (strlen str) 1) 8) 4), '00000000',
+ %select((= (% (+ (strlen str) 1) 8) 5), '000000',
+ %select((= (% (+ (strlen str) 1) 8) 6), '0000', '00')))))))
+%endm
+
+# Intern `str` into `slot` and declare its padded string data inline.
+# `key` is the label suffix; the data label :name_##key is emitted here.
+%macro intern_form(key, str, slot)
+ %la(a0, &name_ ## key)
+ %li(a1, (strlen str))
%call(&intern)
%st_global(a0, slot, t0)
+ %b(&@end)
+ :name_ ## key
+ str
+ %align8_pad(str)
+ :@end
%endm
# Special-form dispatch: pointer-compare the head symbol against `slot`'s
@@ -1208,30 +1227,30 @@
# these slots before falling through to ordinary application.
%fn(intern_special_forms, 0, {
- %intern_form(&name_quote, 5, &sym_quote)
- %intern_form(&name_if, 2, &sym_if)
- %intern_form(&name_lambda, 6, &sym_lambda)
- %intern_form(&name_define, 6, &sym_define)
- %intern_form(&name_begin, 5, &sym_begin)
- %intern_form(&name_cond, 4, &sym_cond)
- %intern_form(&name_else, 4, &sym_else)
- %intern_form(&name_arrow, 2, &sym_arrow)
- %intern_form(&name_let, 3, &sym_let)
- %intern_form(&name_letstar, 4, &sym_letstar)
- %intern_form(&name_let_values, 10, &sym_let_values)
- %intern_form(&name_letstar_values, 11, &sym_letstar_values)
- %intern_form(&name_and, 3, &sym_and)
- %intern_form(&name_or, 2, &sym_or)
- %intern_form(&name_when, 4, &sym_when)
- %intern_form(&name_case, 4, &sym_case)
- %intern_form(&name_setbang, 4, &sym_setbang)
- %intern_form(&name_define_record_type, 18, &sym_define_record_type)
- %intern_form(&name_pmatch, 6, &sym_pmatch)
- %intern_form(&name_do, 2, &sym_do)
- %intern_form(&name_unquote, 7, &sym_unquote)
- %intern_form(&name_guard, 5, &sym_guard)
- %intern_form(&name_underscore, 1, &sym_underscore)
- %intern_form(&name_dollar, 1, &sym_dollar)
+ %intern_form(quote, "quote", &sym_quote)
+ %intern_form(if, "if", &sym_if)
+ %intern_form(lambda, "lambda", &sym_lambda)
+ %intern_form(define, "define", &sym_define)
+ %intern_form(begin, "begin", &sym_begin)
+ %intern_form(cond, "cond", &sym_cond)
+ %intern_form(else, "else", &sym_else)
+ %intern_form(arrow, "=>", &sym_arrow)
+ %intern_form(let, "let", &sym_let)
+ %intern_form(letstar, "let*", &sym_letstar)
+ %intern_form(let_values, "let-values", &sym_let_values)
+ %intern_form(letstar_values, "let*-values", &sym_letstar_values)
+ %intern_form(and, "and", &sym_and)
+ %intern_form(or, "or", &sym_or)
+ %intern_form(when, "when", &sym_when)
+ %intern_form(case, "case", &sym_case)
+ %intern_form(setbang, "set!", &sym_setbang)
+ %intern_form(define_record_type, "define-record-type", &sym_define_record_type)
+ %intern_form(pmatch, "pmatch", &sym_pmatch)
+ %intern_form(do, "do", &sym_do)
+ %intern_form(unquote, "unquote", &sym_unquote)
+ %intern_form(guard, "guard", &sym_guard)
+ %intern_form(underscore, "_", &sym_underscore)
+ %intern_form(dollar, "$", &sym_dollar)
})
# eval_quote(rest=a0, env=a1) -> value (a0). rest is (datum); return datum.
@@ -6130,34 +6149,6 @@
# disassembly so trailing strings don't decode as bogus instructions.
:_text_end
-# Surface names. Length is hard-coded at the call site; no NUL needed
-# because intern takes (ptr, len). Padding bytes are written as
-# '00...' quoted-literal form (not bare `00 00`) -- the riscv64 stage0
-# M0 misparses bare hex tokens through express_number/Fail.
-:name_quote "quote" '0000'
-:name_if "if" '0000000000'
-:name_lambda "lambda" '00'
-:name_define "define" '00'
-:name_begin "begin" '0000'
-:name_cond "cond" '000000'
-:name_else "else" '000000'
-:name_arrow "=>" '0000000000'
-:name_let "let" '00000000'
-:name_letstar "let*" '000000'
-:name_let_values "let-values" '0000000000'
-:name_letstar_values "let*-values" '00000000'
-:name_and "and" '00000000'
-:name_or "or" '0000000000'
-:name_when "when" '000000'
-:name_case "case" '000000'
-:name_setbang "set!" '000000'
-:name_define_record_type "define-record-type" '0000000000'
-:name_pmatch "pmatch" '00'
-:name_do "do" '0000000000'
-:name_unquote "unquote"
-:name_guard "guard" '0000'
-:name_underscore "_" '000000000000'
-:name_dollar "$" '000000000000'
# Primitive surface names.
:name_sys_exit "sys-exit" '00000000000000'