feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune
ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v), q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)). ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no longer uses, nor anything it calls, and the argument that fills it - including an argument for a parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8cf4b3fed6
commit
71735b10a2
151 changed files with 58668 additions and 54719 deletions
|
|
@ -537,6 +537,33 @@ function migrate_case() -> void {
|
|||
if ran == "2 names, first a" { ok(lbl) } else { bad2(lbl, `ran [{ran}]`) }
|
||||
}
|
||||
|
||||
# ludic migrate state --prune: a state nothing uses leaves the functions that take it and the calls
|
||||
# that pass it; an argument for a parameter the callee no longer has goes too (a package's verb that
|
||||
# dropped a state), and the program then builds and runs
|
||||
function migrate_prune_case() -> void {
|
||||
let lbl = "ludic migrate state --prune: unused states and the arguments that fill them go, the same output"
|
||||
let work = `{tmp_dir()}/migprune`
|
||||
shell(`rm -rf {work} && mkdir -p {work}`)
|
||||
var src = "program Prune {\n state Log { lines: []string = new []string }\n state Bag { items: []int = new []int }\n"
|
||||
src = src + " function head<T>(xs: []T) -> T { return xs[0] }\n"
|
||||
src = src + " function put(b: mut Bag, v: int) -> void { push(b.items, v) }\n"
|
||||
src = src + " function add(log_st: mut Log, b: mut Bag, v: int) -> void { put(log_st, b, v) }\n"
|
||||
src = src + " function outer(log_st: mut Log, b: mut Bag) -> void { add(log_st, b, 4) }\n"
|
||||
src = src + " function top(log_st: Log, b: Bag) -> int { return head(log_st, b.items) }\n"
|
||||
src = src + " function said(log_st: mut Log, b: Bag) -> int {\n push(log_st.lines, \"x\")\n return len(log_st.lines)\n }\n"
|
||||
src = src + " entry (log_st: mut Log, b: mut Bag) {\n outer(log_st, b)\n print(`{top(log_st, b)} {said(log_st, b)}`)\n }\n}\n"
|
||||
write_file(`{work}/prune.ludic`, src)
|
||||
if not shq(`bin/ludic migrate state --prune {work}/prune.ludic > {work}/out.txt 2>&1`) { bad2(lbl, capture_line(`tail -1 {work}/out.txt`)); return }
|
||||
let got = read_file(`{work}/prune.ludic`)
|
||||
if not s_contains(got, "function add(b: mut Bag, v: int) -> void { put(b, v) }") or not s_contains(got, "function outer(b: mut Bag) -> void { add(b, 4) }") or not s_contains(got, "function top(b: Bag) -> int { return head(b.items) }") or not s_contains(got, "function said(log_st: mut Log) -> int") or not s_contains(got, "entry (log_st: mut Log, b: mut Bag)") or not s_contains(got, "{top(b)} {said(log_st)}") {
|
||||
bad2(lbl, `rewrote it as [{got}]`)
|
||||
return
|
||||
}
|
||||
if not shq(`bin/ludicc {work}/prune.ludic -o {work}/prune > {work}/cc.txt 2>&1`) { bad2(lbl, capture_line(`grep -i error {work}/cc.txt | head -1`)); return }
|
||||
let ran = capture_line(`{work}/prune`)
|
||||
if ran == "4 1" { ok(lbl) } else { bad2(lbl, `ran [{ran}]`) }
|
||||
}
|
||||
|
||||
# expect_eq on strings: the text is compared, and a failure prints both (the spec fails on purpose)
|
||||
function expect_str_case() -> void {
|
||||
let lbl = "testing_strings.ludic (expect_eq compares strings by content, a null only equal to a null, and prints both on a failure)"
|
||||
|
|
@ -995,6 +1022,7 @@ function cmd_dev_test() -> int {
|
|||
migrate_foreign_case()
|
||||
reject_case("rejected/runtime_type_clash", "PadButton is the runtime's enum", "a program's type named like one of the runtime's is refused")
|
||||
migrate_case()
|
||||
migrate_prune_case()
|
||||
vis_report_case("rejected/uses_missing", "uses: examples/rejected/uses_valley/items/index.ludic:3: items.inv_add used from", "LUDIC_VIS_REPORT=1 lists a uses violation and builds")
|
||||
feat_case("lang/checked", "", "7.5 3 12 hi 2 ok", "checked.ludic (L4: literals take their slot's kind, string(p), []string as []pointer, null, named args)")
|
||||
reject_case("rejected/wrong_arity", "this call to area leaves out h, which has no default", "a call with the wrong number of arguments is refused")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue