boot2

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

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:
Mscheme1/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'