Phase 7f: len(x) works on strings too (retire slen)

`len` is now polymorphic — a slice's element count OR a string's byte length —
so the C-style `slen` (strlen) is gone: `slen(name)` -> `len(name)`. emit_len
branches on the operand type (slice header vs @strlen). Two reseeds: add the
string branch, then migrate the 19 slen calls and delete slen.

Reseeded (22565 lines); C-free fixpoint holds; goldens identical; 18/18; vocab +
doc-fences clean. (String slicing s[a..b] to replace substr is deferred to its
own phase.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-28 01:25:57 +03:00
parent 058cac88ec
commit 839a6bf0c0
11 changed files with 3555 additions and 3542 deletions

View file

@ -15,7 +15,7 @@ fn is_kw(v: ptr) -> bool { return is_id(v) }
fn perr(msg: ptr) -> void {
let e = file_stderr()
file_write(e, "ludicc(self): parse error: ", 27)
file_write(e, msg, slen(msg))
file_write(e, msg, len(msg))
file_write(e, "\n", 1)
os_exit(1)
}
@ -35,7 +35,7 @@ fn ptype() -> ptr {
pi = pi + 1
eat_op("]")
let el = ptype()
let out = mem_alloc(slen(el) + 3)
let out = mem_alloc(len(el) + 3)
poke8(out, 0, 91); poke8(out, 1, 93) # "[]"
var i = 0
while peek8(el, i) != 0 { poke8(out, 2 + i, peek8(el, i)); i = i + 1 }
@ -73,7 +73,7 @@ fn parse_hole(inner: ptr) -> Node { # re-lex+parse an embedded exp
return e
}
fn parse_interp(raw: ptr) -> Node {
let n = slen(raw)
let n = len(raw)
var acc: Node = null
let lit = mem_alloc(n + 1)
var lj = 0