refactor: List is slice-backed { items: []T; cap } — directly iterable

items is now a []T slice whose .len IS the live element count (cap = allocated
capacity), so a List iterates directly: `for xs.items (e) { ... }`. A
`len :: (self) -> i64 #get => items.len` accessor keeps `xs.len` reads working;
`.len` WRITES become `.items.len`. List stays 24 bytes (`[]T`=16 + cap=8).

- list.sx: append/ensure_capacity/deinit rewritten for the slice backing. deinit
  guards the free on `cap > 0` (true ownership) and resets via explicit
  ptr=null/len=0 (a `.{}` slice assignment yields a garbage len; `.[]` is the
  empty-slice literal but can't be assigned to a generic []T — both worked around).
- Compiler coupling updated: comptime_vm makeStringList/readStringList write/read
  items as a {ptr,len} fat pointer at field 0 + cap at field 1; control_flow
  listView views an `items: []T` slice (keeps the legacy {[*]T,len} shape too).
- Migrated List `.len` writes to `.items.len` in sched.sx + ui/{render,pipeline,
  glyph_cache} + platform/{sdl3,android,uikit}.
- Snapshots: List's type-table layout changed → ~40 .ir + memory/0800 (items now
  prints as a slice) regenerated; diagnostics/1183 retargeted to a genuine
  many-pointer (xs.items is a slice now). Example memory/0840 locks for-each.
This commit is contained in:
agra
2026-06-22 11:55:19 +03:00
parent 9d3a019670
commit 5cc45a2b38
58 changed files with 59733 additions and 59479 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -15,10 +15,9 @@ sum :: (s: []i64) -> i64 {
}
main :: () -> i32 {
xs : List(i64) = .{};
xs.append(10);
xs.append(20);
r := sum(xs.items); // [*]i64 → []i64 — needs xs.items[0..xs.len]
a : [4]i64 = .[10, 20, 30, 40];
mp : [*]i64 = xx @a[0]; // a genuine many-pointer (carries no length)
r := sum(mp); // [*]i64 → []i64 — rejected; needs mp[0..len]
print("{}\n", r);
return 0;
}

View File

@@ -1,5 +1,5 @@
error: a many-pointer '[*]T' does not coerce to a slice '[]T' implicitly (it carries no length) — slice it with a length: ptr[0..len]
--> examples/diagnostics/1183-diagnostics-many-pointer-to-slice-rejected.sx:21:10
--> examples/diagnostics/1183-diagnostics-many-pointer-to-slice-rejected.sx:20:10
|
21 | r := sum(xs.items); // [*]i64 → []i64 — needs xs.items[0..xs.len]
| ^^^^^^^^^^^^^
20 | r := sum(mp); // [*]i64 → []i64 — rejected; needs mp[0..len]
| ^^^^^^^

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,43 @@
// List is `{ items: []T; cap }` — `items` is a `[]T` slice whose `.len` IS the
// live element count, so a List is directly iterable with a `for`-each, and
// `xs.len` reads the live count via a `#get` accessor. Exercises append (incl.
// a realloc past the initial cap of 4), for-each, parallel for-with-index,
// empty iteration, direct `for xs` over the List, and truncation via items.len.
#import "modules/std.sx";
main :: () -> i64 {
xs : List(i64) = .{};
i := 0;
while i < 6 { xs.append((i + 1) * 10); i = i + 1; } // 10..60; grows 4 -> 8
print("len={} cap>={}\n", xs.len, if xs.cap >= 6 then 1 else 0); // len=6 cap>=1
// for-each over the items slice
sum := 0;
for xs.items (e) { sum = sum + e; }
print("foreach sum={}\n", sum); // 210
// parallel for with index
print("indexed:");
for xs.items, 0.. (e, ix) { if ix % 2 == 0 { print(" {}@{}", e, ix); } }
print("\n"); // 10@0 30@2 50@4
// direct `for xs` over the List value (listView path)
s2 := 0;
for xs (e) { s2 = s2 + e; }
print("for-list sum={}\n", s2); // 210
// len via #get used as a loop bound + indexing
acc := 0;
j := 0;
while j < xs.len { acc = acc + xs.items[j]; j = j + 1; }
print("indexed sum={}\n", acc); // 210
// truncate to empty via items.len, then iterate (zero iterations)
xs.items.len = 0;
cnt := 0;
for xs.items (e) { cnt = cnt + 1; }
print("after trunc: len={} iters={}\n", xs.len, cnt); // len=0 iters=0
return 0;
}

View File

@@ -1 +1 @@
List__i32{items: [*]i32@0xADDR, len: 5, cap: 8}
List__i32{items: [1, 3, 4, 1, 5], cap: 8}

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,6 @@
len=6 cap>=1
foreach sum=210
indexed: 10@0 30@2 50@4
for-list sum=210
indexed sum=210
after trunc: len=0 iters=0

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long