selfhost: port append + spread — N_SPREAD parser + rt_ensure builtin

This commit is contained in:
2026-05-12 16:04:17 +09:00
parent f67c07cbae
commit ce5d66e18a
7 changed files with 525 additions and 15 deletions

View File

@@ -345,6 +345,35 @@ probe_ww_compile(const char *bin)
" dec(&c); dec(&c); dec(&c);\n"
" return c.x;\n"
"};", 2 },
/* append(s, v, ...) builtin — Hare's rt::ensure model.
* Each value: PUSHQ AX, ADDQ $1 to s.len, LEAQ s/MOVQ esz
* args for rt_ensure, then write into the freshly-grown
* slot. Returns s.len = 3 after appending three u8s. */
{ "use os;\n"
"fn main() i32 = {\n"
" let s: []u8;\n"
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
" append(s, 65u8, 66u8, 67u8);\n"
" return s.len: i32;\n"
"};", 3 },
/* append(s, items...) spread variant — wraps the per-value
* body in a counted loop over items.len. Combined with
* single-value appends in the same fn. dst ends up with
* [1, 10, 20, 30] — sum = 61. */
{ "use os;\n"
"fn main() i32 = {\n"
" let src: []i64;\n"
" src.ptr = nil; src.len = 0; src.cap = 0;\n"
" append(src, 10i64, 20i64, 30i64);\n"
" let dst: []i64;\n"
" dst.ptr = nil; dst.len = 0; dst.cap = 0;\n"
" append(dst, 1i64);\n"
" append(dst, src...);\n"
" let total: i64 = 0i64;\n"
" let i: i32 = 0;\n"
" for (i < dst.len) { total += dst[i]; i += 1; };\n"
" return total: i32;\n"
"};", 61 },
/* switch with multi-expr cases + default. Lowers to a chain
* of CMPQ + JE; the scrutinee lands in a fresh 8B local slot
* (".sw_N") so case bodies can spill SP without losing it.

View File

@@ -159,6 +159,25 @@ main(void)
" return -1;\n"
"};\n"
"fn main() i32 = { return classify(2); };" },
{ "append",
"use os;\n"
"fn main() i32 = {\n"
" let s: []u8;\n"
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
" append(s, 65u8, 66u8, 67u8);\n"
" return s.len: i32;\n"
"};" },
{ "append_spread",
"use os;\n"
"fn main() i32 = {\n"
" let src: []i64;\n"
" src.ptr = nil; src.len = 0; src.cap = 0;\n"
" append(src, 10i64, 20i64);\n"
" let dst: []i64;\n"
" dst.ptr = nil; dst.len = 0; dst.cap = 0;\n"
" append(dst, src...);\n"
" return dst.len: i32;\n"
"};" },
{ NULL, NULL },
};