fix(migrate): 0.R4 - --prune keeps a state declared after a plain parameter; a parameter named twice is refused
On Maroon Lake the prune gave home_keep_records(base_app_st, home_st, r: RunRecords, save_app_st) a second save_app_st at the front, and every call a second argument: a state declared after a plain parameter was not counted as declared. It is now, and a call to such a function is never given the state again. `ludic build --check` let the duplicate through and clang refused it; the checker now refuses a function that names two parameters alike (`add names two parameters n`). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
71735b10a2
commit
c35481f344
8 changed files with 47291 additions and 46599 deletions
|
|
@ -154,12 +154,26 @@ function ck_stmt(s: Node) -> void {
|
|||
}
|
||||
ck_walk(s)
|
||||
}
|
||||
# a name given to two parameters: the second would shadow the first, and nothing could reach it
|
||||
function ck_param_twice(d: Node, i: int) -> void {
|
||||
var j = 0
|
||||
while j < i {
|
||||
if d.kids[j].kind == N_PARAM and (d.kids[j].s == d.kids[i].s) {
|
||||
ck_err("arity", d.kids[i], `{d.s} names two parameters {d.kids[i].s}`)
|
||||
return
|
||||
}
|
||||
j += 1
|
||||
}
|
||||
}
|
||||
function ck_fn_body(d: Node) -> void {
|
||||
mg_enter(d, 0)
|
||||
let m = ck_mark()
|
||||
var i = 0
|
||||
while i < len(d.kids) {
|
||||
if d.kids[i].kind == N_PARAM { ck_bind_param(d.kids[i]) }
|
||||
if d.kids[i].kind == N_PARAM {
|
||||
ck_param_twice(d, i)
|
||||
ck_bind_param(d.kids[i])
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
ck_ret = d.ty
|
||||
|
|
|
|||
|
|
@ -559,8 +559,22 @@ function mg_list(set: pointer) -> []int {
|
|||
function mg_declared(n: Node, s: int) -> bool {
|
||||
if n.kind != N_FN { return false }
|
||||
var i = 0
|
||||
while i < len(n.kids) and n.kids[i].kind == N_PARAM and is_state_ty(n.kids[i].ty) {
|
||||
if (n.kids[i].ty == g_ms_name[s]) { return true }
|
||||
while i < len(n.kids) { # anywhere in the list: a state after a plain parameter is declared too
|
||||
if n.kids[i].kind == N_PARAM and (n.kids[i].ty == g_ms_name[s]) { return true }
|
||||
i += 1
|
||||
}
|
||||
return false
|
||||
}
|
||||
# a state declared after a plain parameter: every call already names it where it stands
|
||||
function mg_declared_late(n: Node, s: int) -> bool {
|
||||
if n.kind != N_FN { return false }
|
||||
var plain = false
|
||||
var i = 0
|
||||
while i < len(n.kids) {
|
||||
if n.kids[i].kind == N_PARAM {
|
||||
if not is_state_ty(n.kids[i].ty) { plain = true }
|
||||
else if plain and (n.kids[i].ty == g_ms_name[s]) { return true }
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
return false
|
||||
|
|
@ -972,7 +986,7 @@ function mg_calls() -> void {
|
|||
let passed = g_mc_passed[c] == 1
|
||||
var k = 0
|
||||
while k < len(need) {
|
||||
if not (mg_declared(callee, need[k]) and passed) {
|
||||
if not (mg_declared(callee, need[k]) and (passed or mg_declared_late(callee, need[k]))) {
|
||||
if len(text) > 0 { text = text + ", " }
|
||||
text = text + g_ms_param[need[k]]
|
||||
}
|
||||
|
|
|
|||
46913
selfhost/ludicc.seed.ll
46913
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue