boot2

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

commit a7ada8d0d20a88c00a35a489c30c309c20a0b815
parent 321d9c2f70722de7735bff7c6ad54f90d5b5a2da
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Mon, 27 Apr 2026 17:14:56 -0700

scheme1: quote raw-byte padding for riscv64 M0

Bare `00` tokens in :name_*/:str_*/:msg_* padding tripped riscv64 M0's
Eval_Immediates: a token whose second char is '0' falls through to
express_number, which only accepts %/!/@/~ prefixes and Fails on '0'.
Switch every padding run to '00...' quoted-literal form (already the
project-wide convention per the M0 hex-byte memo).

Diffstat:
Mscheme1/scheme1.P1pp | 251++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 126 insertions(+), 125 deletions(-)

diff --git a/scheme1/scheme1.P1pp b/scheme1/scheme1.P1pp @@ -6258,132 +6258,133 @@ }) # Surface names. Length is hard-coded at the call site; no NUL needed -# because intern takes (ptr, len). Aligned padding via "\0" bytes is -# fine -- M0 emits ASCII verbatim. -:name_quote "quote" 00 00 -:name_if "if" 00 00 00 00 00 -:name_lambda "lambda" 00 -:name_define "define" 00 -:name_begin "begin" 00 00 -:name_cond "cond" 00 00 00 -:name_else "else" 00 00 00 -:name_arrow "=>" 00 00 00 00 00 -:name_let "let" 00 00 00 00 -:name_letstar "let*" 00 00 00 -:name_letrec "letrec" 00 +# 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_letrec "letrec" '00' :name_letrecstar "letrec*" -:name_let_values "let-values" 00 00 00 00 00 -:name_letstar_values "let*-values" 00 00 00 00 -:name_define_values "define-values" 00 00 -:name_and "and" 00 00 00 00 -:name_or "or" 00 00 00 00 00 -:name_when "when" 00 00 00 -:name_unless "unless" 00 -:name_case "case" 00 00 00 -:name_setbang "set!" 00 00 00 -:name_define_record_type "define-record-type" 00 00 00 00 00 -:name_pmatch "pmatch" 00 -:name_do "do" 00 00 00 00 00 -:name_case_lambda "case-lambda" 00 00 00 00 +:name_let_values "let-values" '0000000000' +:name_letstar_values "let*-values" '00000000' +:name_define_values "define-values" '0000' +:name_and "and" '00000000' +:name_or "or" '0000000000' +:name_when "when" '000000' +:name_unless "unless" '00' +: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_case_lambda "case-lambda" '00000000' :name_unquote "unquote" -:name_quasiquote "quasiquote" 00 00 00 00 00 -:name_unquote_splicing "unquote-splicing" 00 00 00 00 00 00 00 -:name_guard "guard" 00 00 -:name_underscore "_" 00 00 00 00 00 00 -:name_dollar "$" 00 00 00 00 00 00 +:name_quasiquote "quasiquote" '0000000000' +:name_unquote_splicing "unquote-splicing" '00000000000000' +:name_guard "guard" '0000' +:name_underscore "_" '000000000000' +:name_dollar "$" '000000000000' # Primitive surface names. -:name_sys_exit "sys-exit" 00 00 00 00 00 00 00 -:name_cons "cons" 00 00 00 -:name_car "car" 00 00 00 00 -:name_cdr "cdr" 00 00 00 00 -:name_nullq "null?" 00 00 -:name_pairq "pair?" 00 00 +:name_sys_exit "sys-exit" '00000000000000' +:name_cons "cons" '000000' +:name_car "car" '00000000' +:name_cdr "cdr" '00000000' +:name_nullq "null?" '0000' +:name_pairq "pair?" '0000' :name_stringq "string?" -:name_set_car "set-car!" 00 00 00 00 00 00 00 -:name_set_cdr "set-cdr!" 00 00 00 00 00 00 00 -:name_length "length" 00 -:name_list_ref "list-ref" 00 00 00 00 00 00 00 -:name_str_to_sym "string->symbol" 00 -:name_sym_to_str "symbol->string" 00 -:name_num_to_str "number->string" 00 -:name_str_to_num "string->number" 00 -:name_bv_append "bytevector-append" 00 00 00 00 00 00 -:name_booleanq "boolean?" 00 00 00 00 00 00 00 -:name_integerq "integer?" 00 00 00 00 00 00 00 +:name_set_car "set-car!" '00000000000000' +:name_set_cdr "set-cdr!" '00000000000000' +:name_length "length" '00' +:name_list_ref "list-ref" '00000000000000' +:name_str_to_sym "string->symbol" '00' +:name_sym_to_str "symbol->string" '00' +:name_num_to_str "number->string" '00' +:name_str_to_num "string->number" '00' +:name_bv_append "bytevector-append" '000000000000' +:name_booleanq "boolean?" '00000000000000' +:name_integerq "integer?" '00000000000000' :name_symbolq "symbol?" -:name_procedureq "procedure?" 00 00 00 00 00 -:name_zeroq "zero?" 00 00 -:name_not "not" 00 00 00 00 -:name_eqq "eq?" 00 00 00 00 -:name_equal "equal?" 00 -:name_plus "+" 00 00 00 00 00 00 -:name_minus "-" 00 00 00 00 00 00 -:name_mult "*" 00 00 00 00 00 00 -:name_eq "=" 00 00 00 00 00 00 -:name_lt "<" 00 00 00 00 00 00 -:name_gt ">" 00 00 00 00 00 00 -:name_quotient "quotient" 00 00 00 00 00 00 00 -:name_remainder "remainder" 00 00 00 00 00 00 +:name_procedureq "procedure?" '0000000000' +:name_zeroq "zero?" '0000' +:name_not "not" '00000000' +:name_eqq "eq?" '00000000' +:name_equal "equal?" '00' +:name_plus "+" '000000000000' +:name_minus "-" '000000000000' +:name_mult "*" '000000000000' +:name_eq "=" '000000000000' +:name_lt "<" '000000000000' +:name_gt ">" '000000000000' +:name_quotient "quotient" '00000000000000' +:name_remainder "remainder" '000000000000' :name_bit_and "bit-and" -:name_bit_or "bit-or" 00 +:name_bit_or "bit-or" '00' :name_bit_xor "bit-xor" :name_bit_not "bit-not" -:name_arith_shift "arithmetic-shift" 00 00 00 00 00 00 00 -:name_apply "apply" 00 00 +:name_arith_shift "arithmetic-shift" '00000000000000' +:name_apply "apply" '0000' :name_make_bv "make-bytevector" -:name_bv_length "bytevector-length" 00 00 00 00 00 00 -:name_string_length "string-length" 00 00 -:name_bv_u8_ref "bytevector-u8-ref" 00 00 00 00 00 00 -:name_bv_u8_set "bytevector-u8-set!" 00 00 00 00 00 +:name_bv_length "bytevector-length" '000000000000' +:name_string_length "string-length" '0000' +:name_bv_u8_ref "bytevector-u8-ref" '000000000000' +:name_bv_u8_set "bytevector-u8-set!" '0000000000' :name_bv_copy "bytevector-copy" -:name_bv_copy_b "bytevector-copy!" 00 00 00 00 00 00 00 -:name_bv_eq "bytevector=?" 00 00 00 - -:name_sys_read "sys-read" 00 00 00 00 00 00 00 -:name_sys_write "sys-write" 00 00 00 00 00 00 -:name_sys_close "sys-close" 00 00 00 00 00 00 -:name_sys_openat "sys-openat" 00 00 00 00 00 -:name_sys_clone "sys-clone" 00 00 00 00 00 00 -:name_sys_execve "sys-execve" 00 00 00 00 00 -:name_sys_waitid "sys-waitid" 00 00 00 00 00 -:name_sys_argv "sys-argv" 00 00 00 00 00 00 00 -:name_eof_object "eof-object" 00 00 00 00 00 -:name_eof_objectq "eof-object?" 00 00 00 00 - -:name_values "values" 00 -:name_call_with_values "call-with-values" 00 00 00 00 00 00 00 +:name_bv_copy_b "bytevector-copy!" '00000000000000' +:name_bv_eq "bytevector=?" '000000' + +:name_sys_read "sys-read" '00000000000000' +:name_sys_write "sys-write" '000000000000' +:name_sys_close "sys-close" '000000000000' +:name_sys_openat "sys-openat" '0000000000' +:name_sys_clone "sys-clone" '000000000000' +:name_sys_execve "sys-execve" '0000000000' +:name_sys_waitid "sys-waitid" '0000000000' +:name_sys_argv "sys-argv" '00000000000000' +:name_eof_object "eof-object" '0000000000' +:name_eof_objectq "eof-object?" '00000000' + +:name_values "values" '00' +:name_call_with_values "call-with-values" '00000000000000' :name_display "display" -:name_write "write" 00 00 -:name_error "error" 00 00 -:name_format "format" 00 +:name_write "write" '0000' +:name_error "error" '0000' +:name_format "format" '00' ;; The last three names are padded individually to 16 bytes (multiple ;; of 8) so subsequent 8-aligned data slots (prim_table $() rows, the ;; bss pointer slots) stay aligned. M0 appends a NUL to every "..." ;; string, so the listed length below counts the trailing NUL plus the ;; explicit 00 bytes. -;; "heap-mark" + NUL = 10 bytes; pad with 6 00 to reach 16. -;; "heap-rewind!"+ NUL = 13 bytes; pad with 3 00 to reach 16. -;; "heap-usage" + NUL = 11 bytes; pad with 5 00 to reach 16. -:name_heap_mark "heap-mark" 00 00 00 00 00 00 -:name_heap_rewind_bang "heap-rewind!" 00 00 00 -:name_heap_usage "heap-usage" 00 00 00 00 00 +;; "heap-mark" + NUL = 10 bytes; pad with 6 NUL to reach 16. +;; "heap-rewind!"+ NUL = 13 bytes; pad with 3 NUL to reach 16. +;; "heap-usage" + NUL = 11 bytes; pad with 5 NUL to reach 16. +:name_heap_mark "heap-mark" '000000000000' +:name_heap_rewind_bang "heap-rewind!" '000000' +:name_heap_usage "heap-usage" '0000000000' # Writer string constants. Lengths are hard-coded at the str_putn call # sites (write_to_bv branches). No NUL needed in the source bytes -- # str_putn takes (ptr, n). -:str_false "#f" 00 00 00 00 00 00 -:str_true "#t" 00 00 00 00 00 00 -:str_nil "()" 00 00 00 00 00 00 -:str_unspec "#!unspec" 00 00 00 00 00 00 00 00 -:str_unbound "#!unbound" 00 00 00 00 00 00 00 -:str_eof "#!eof" 00 00 00 -:str_closure "#<closure>" 00 00 00 00 00 00 -:str_prim "#<prim>" 00 -:str_td "#<rec-type>" 00 00 00 00 00 -:str_rec "#<record>" 00 00 00 00 00 00 00 -:str_unknown "#<unknown>" 00 00 00 00 00 00 +:str_false "#f" '000000000000' +:str_true "#t" '000000000000' +:str_nil "()" '000000000000' +:str_unspec "#!unspec" '0000000000000000' +:str_unbound "#!unbound" '00000000000000' +:str_eof "#!eof" '000000' +:str_closure "#<closure>" '000000000000' +:str_prim "#<prim>" '00' +:str_td "#<rec-type>" '0000000000' +:str_rec "#<record>" '00000000000000' +:str_unknown "#<unknown>" '000000000000' :str_error_prefix "scheme1: error: " # Primitive registration table. Each entry: 8-byte name_ptr (4-byte label @@ -6456,27 +6457,27 @@ &name_call_with_values %(0) $(16) &prim_call_with_values_entry %(0) :prim_table_end -:msg_usage "scheme1: usage: scheme1 SOURCE.scm" '0a' 00 -:msg_load_fail "scheme1: failed to read source" '0a' 00 -:msg_symtab_full "scheme1: symbol table full" '0a' 00 -:msg_unexp_rparen "scheme1: unexpected ')'" '0a' 00 -:msg_bad_hash "scheme1: bad #-syntax" '0a' 00 -:msg_unexp_eof "scheme1: unexpected EOF in form" '0a' 00 -:msg_unterm_list "scheme1: unterminated list" '0a' 00 -:msg_unbound "scheme1: unbound variable" '0a' 00 -:msg_not_proc "scheme1: not a procedure" '0a' 00 -:msg_heap_full "scheme1: heap exhausted" '0a' 00 -:msg_readbuf_full "scheme1: source buffer overflow" '0a' 00 -:msg_bv_oob "scheme1: bytevector index out of range" '0a' 00 -:msg_unterm_string "scheme1: unterminated string literal" '0a' 00 -:msg_bad_escape "scheme1: bad string escape" '0a' 00 -:msg_bad_char "scheme1: bad #\\ character literal" '0a' 00 -:msg_bad_number "scheme1: bad number literal" '0a' 00 -:msg_bad_ident "scheme1: bad identifier" '0a' 00 -:msg_internal_define "scheme1: internal define is not supported (use letrec)" '0a' 00 -:msg_pmatch_no_match "scheme1: pmatch: no clause matched" '0a' 00 -:msg_bad_unquote_pattern "scheme1: pmatch: malformed ,-pattern" '0a' 00 -:msg_case_lambda_no_match "scheme1: case-lambda: no clause matched arity" '0a' 00 +:msg_usage "scheme1: usage: scheme1 SOURCE.scm" '0a' '00' +:msg_load_fail "scheme1: failed to read source" '0a' '00' +:msg_symtab_full "scheme1: symbol table full" '0a' '00' +:msg_unexp_rparen "scheme1: unexpected ')'" '0a' '00' +:msg_bad_hash "scheme1: bad #-syntax" '0a' '00' +:msg_unexp_eof "scheme1: unexpected EOF in form" '0a' '00' +:msg_unterm_list "scheme1: unterminated list" '0a' '00' +:msg_unbound "scheme1: unbound variable" '0a' '00' +:msg_not_proc "scheme1: not a procedure" '0a' '00' +:msg_heap_full "scheme1: heap exhausted" '0a' '00' +:msg_readbuf_full "scheme1: source buffer overflow" '0a' '00' +:msg_bv_oob "scheme1: bytevector index out of range" '0a' '00' +:msg_unterm_string "scheme1: unterminated string literal" '0a' '00' +:msg_bad_escape "scheme1: bad string escape" '0a' '00' +:msg_bad_char "scheme1: bad #\\ character literal" '0a' '00' +:msg_bad_number "scheme1: bad number literal" '0a' '00' +:msg_bad_ident "scheme1: bad identifier" '0a' '00' +:msg_internal_define "scheme1: internal define is not supported (use letrec)" '0a' '00' +:msg_pmatch_no_match "scheme1: pmatch: no clause matched" '0a' '00' +:msg_bad_unquote_pattern "scheme1: pmatch: malformed ,-pattern" '0a' '00' +:msg_case_lambda_no_match "scheme1: case-lambda: no clause matched arity" '0a' '00' :name_ch_tab "tab" :name_ch_null "null"