Phase 7h: string slicing s[a..b] (retire substr)

`s[a..b]` is a fresh substring of the bytes [a, b) — the modern, end-based form
of the C-style `substr(s, start, count)`:

  substr(src, start, i - start)   -> src[start..i]
  substr(t, 2, len(t) - 2)        -> t[2..len(t)]
  substr(src, i, 2)               -> src[i..i + 2]

Mechanics: a new E_SLICE postfix (`base[lo..hi]`, distinct from `base[i]`
indexing) lowers to a @fn_str_slice prelude (malloc + copy + terminate), emitted
once into any program that slices. Two reseeds: add the syntax + prelude, then
migrate the 22 substr calls and delete substr. The migrator recognises the
common `count == end - start` shape and emits the clean `s[start..end]` rather
than `s[start..start + (end - start)]`.

examples/strings.ludic gains slicing (now prints 1..9). Reseeded (22673 lines);
C-free fixpoint holds; goldens identical; 18/18; vocab + doc-fences clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-28 01:35:24 +03:00
parent 0efa06dca2
commit 1b9789630a
14 changed files with 4049 additions and 3914 deletions

View file

@ -20,6 +20,7 @@ var loc_mut: []int # 1 = mutable (var / param / loop-var), 0 = immutab
var nloc: int = 0
var g_uses_str: bool = false # a `str + str` / `str == str` was emitted -> emit the prelude
var g_uses_intstr: bool = false # `str(int)` was emitted -> emit the int->string prelude
var g_uses_strslice: bool = false # `s[a..b]` was emitted -> emit the substring prelude
# loop targets for break/continue (innermost last)
var brk_lbl: []ptr
@ -57,7 +58,7 @@ fn llty(t: ptr) -> ptr {
}
fn is_slice_ty(t: ptr) -> bool { return peek8(t, 0) == 91 and peek8(t, 1) == 93 } # "[]"
fn slice_elem(t: ptr) -> ptr { return substr(t, 2, len(t) - 2) }
fn slice_elem(t: ptr) -> ptr { return t[2..len(t)] }
fn find_arch(name: ptr) -> Node {
var i = 0