feat(lang): new Type { field: value } record initialisers
`new` accepted only a bare `new T` (every field its declared default) or
`new []T`, but the docs (kw-new) document `new Record { field: value, … }`
as the way to construct a record with non-default fields — a documented,
intended form the parser never accepted (`let o = new Point { x: 3 }` failed
with "expected newline or ';'").
Parse an optional `{ … }` override record after the type in a `new`
expression (reusing the existing `record()` parser that `spawn` uses), and
seed each field in emit_new_struct from that record when present, else from
the field's declared default. `new []T` and bare `new T` are unchanged.
Also mark the illustrative kw-import fence `# doc-check: skip` (its imports
are example paths that can't resolve in isolation), which makes `x check-docs`
fully green (398 fences, 0 drifted) — so it is now wired as a gate in
`x test-tools` and CI, guarding against future doc/compiler drift.
Reseed is a clean fixpoint (x bootstrap-cfree holds); x test (56),
x selfhost-test (29, golden renders unchanged) and x test-tools (30) green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e65e862244
commit
f5e9b5d6c2
7 changed files with 13209 additions and 13078 deletions
|
|
@ -407,7 +407,7 @@ function emit_expr(e: Node) -> Val {
|
|||
if e.kind == E_STR { return val(emit_str_const(e.s), "string") }
|
||||
if e.kind == E_NEW {
|
||||
if is_slice_ty(e.s) { return emit_new_slice(e.s) }
|
||||
return emit_new_struct(e.s)
|
||||
return emit_new_struct(e.s, e.a)
|
||||
}
|
||||
if e.kind == E_ID {
|
||||
let li = loc_find(e.s)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,23 @@ function emit_sizeof(llt: pointer) -> pointer {
|
|||
return emit_bind(`ptrtoint ptr {p} to i64`)
|
||||
}
|
||||
|
||||
function emit_new_struct(name: pointer) -> Val {
|
||||
# the value expression a `new T { ... }` record supplies for field `fname`,
|
||||
# or null when the record omits it (so the field keeps its declared default).
|
||||
function rec_field(rec: Node, fname: pointer) -> Node {
|
||||
if (rec == null) { return null }
|
||||
var i = 0
|
||||
while i < len(rec.kids) {
|
||||
let fi = rec.kids[i]
|
||||
if (fi.s == fname) { return fi.a }
|
||||
i = i + 1
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
# `new T` / `new T { field: value, ... }` — allocate a record and seed each
|
||||
# field: a value from the override record if given, else the field's declared
|
||||
# default. `rec` is the E_REC of overrides (or null for the bare `new T`).
|
||||
function emit_new_struct(name: pointer, rec: Node) -> Val {
|
||||
let s = layout_node(name) # a struct or a property — same shape
|
||||
if (s == null) { perr("unknown record type in new") }
|
||||
let lty = layout_ty(name)
|
||||
|
|
@ -23,6 +39,8 @@ function emit_new_struct(name: pointer) -> Val {
|
|||
var v = "0"
|
||||
if (lt == "ptr") { v = "null" }
|
||||
if (fd.a != null) { let dv = emit_expr(fd.a); v = dv.code }
|
||||
let ov = rec_field(rec, fd.s) # explicit override wins over the default
|
||||
if (ov != null) { let dv = emit_expr(ov); v = dv.code }
|
||||
emit(" store "); emit(lt); emit(" "); emit(v); emit(", ptr "); emit(addr); emit("\n")
|
||||
f = f + 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ function p_primary() -> Node {
|
|||
if (t.text == "true") { let n = node(E_BOOL); n.ival = 1; pi = pi + 1; return n }
|
||||
if (t.text == "false") { let n = node(E_BOOL); n.ival = 0; pi = pi + 1; return n }
|
||||
if (t.text == "null") { pi = pi + 1; return node(E_NULL) }
|
||||
if (t.text == "new") { pi = pi + 1; let n = node(E_NEW); n.s = ptype(); return n }
|
||||
if (t.text == "new") { pi = pi + 1; let n = node(E_NEW); n.s = ptype(); if is_op("{") { n.a = record() }; return n }
|
||||
let n = node(E_ID); n.s = t.text; pi = pi + 1; return n
|
||||
}
|
||||
if is_op("(") { pi = pi + 1; skipnl(); let e = expr(); skipnl(); eat_op(")"); return e }
|
||||
|
|
|
|||
26256
selfhost/ludicc.seed.ll
26256
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue