feat(lang): 0.S - components take states in their header; migrate writes them, never inside a name, never outside the programs given, never into a package's state

- component Name (a: mut A, b: B) { ... }: every getter, default, function and event takes the
  header's states before the instance; a member's call to another passes them on; the glue is
  supplied them; the template never sees them; a read-only one is read-only in every member
- ludic migrate state: a component's members' needs go into its header (added to an existing one,
  mut added where now changed); a field read or a member call inside a component is the compiler's,
  so nothing is written inside a name and no ', )' is left; an entry point that declares states
  already gets the rest after them
- a program's module named like a package gets <Name>AppState; a program's own file its own state;
  a friend module's files go by directory; a package's settable var stays state
- it writes only under the programs and directories given (and runtime/ with --runtime), and
  refuses the whole run naming any other file that would have to change
- a name a package already moved into its state is rewritten through it; a read of the runtime's
  var through the runtime function that answers it (gl_w: gl_width())
- a state's instance supplied by the runtime is not a uses reference
- tests: state/component, rejected/state_component_ro, rendering/ui_render3d, migrate component
  and foreign cases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-25 17:11:15 +03:00
parent c167ecc714
commit ce80e64b24
23 changed files with 67967 additions and 61444 deletions

View file

@ -25,6 +25,26 @@ function cm_rewrite(c: int, f: Node, self_ty: pointer) -> void {
}
f.kids = kids
cm_rw(c, f.a)
state_params_onto(f, g_cm_ps[c]) # 0.S: its states, before the instance
}
# a member's call to another passes its states on (they are its own parameters), then the instance
function cm_member_args(c: int, rest: []Node) -> []Node {
let args = new []Node
var i = 0
while i < len(g_cm_ps[c]) {
let id = node(E_ID)
id.s = g_cm_ps[c][i].s
id.pos = -1
push(args, id)
i += 1
}
push(args, cm_self())
i = 0
while i < len(rest) {
push(args, rest[i])
i += 1
}
return args
}
function cm_is_keep(c: int, s: pointer) -> bool {
var i = 0
@ -73,20 +93,13 @@ function cm_rw(c: int, n: Node) -> void {
let callee = node(E_ID)
callee.s = cm_prefix(g_cm_name[c]) + "get_" + n.s
n.a = callee
n.kids = new []Node
push(n.kids, cm_self())
n.kids = cm_member_args(c, new []Node)
n.pos = -1 # a call the compiler wrote: nothing in the source to edit
return
}
if n.kind == E_CALL and n.a != null and n.a.kind == E_ID and cm_is_call(c, n.a.s) and not cm_is_keep(c, n.a.s) {
n.a.s = cm_prefix(g_cm_name[c]) + n.a.s
let args = new []Node
push(args, cm_self())
var i = 0
while i < len(n.kids) {
push(args, n.kids[i])
i += 1
}
n.kids = args
n.kids = cm_member_args(c, n.kids)
}
cm_rw(c, n.a)
cm_rw(c, n.b)