hv1: early-exit at main (no plugin init); tokenizer: Stage-3 single-quote + full escapes (\/ \b \f \' \r fix); builder: route BinOp via SSOT emit_binop_to_dst; hv1 verify canary route (builder→Core); docs: phase-20.39 updates

This commit is contained in:
nyash-codex
2025-11-04 20:46:43 +09:00
parent 31ce798341
commit 44a5158a14
53 changed files with 2237 additions and 179 deletions

View File

@ -183,6 +183,46 @@ static box LoopFormBox {
return MirSchemaBox.module(MirSchemaBox.fn_main(blocks))
}
// Extended param variant: allow custom compare op ("Lt"/"Le"/"Gt"/"Ge") via opts
// and negative step (handled by passing negative string for step)
loop_count_param_ex(init, limit, step, cmp) {
local cmpop = "" + cmp
if cmpop == null || cmpop == "" { cmpop = "Lt" }
// Preheader
local pre = new ArrayBox()
pre.push(MirSchemaBox.inst_const(1, init))
pre.push(MirSchemaBox.inst_const(2, limit))
pre.push(MirSchemaBox.inst_const(3, step))
pre.push(MirSchemaBox.inst_jump(1))
// Header
local header = new ArrayBox()
local inc = new ArrayBox(); inc.push(MirSchemaBox.phi_incoming(0, 1)); inc.push(MirSchemaBox.phi_incoming(3, 12))
header.push(MirSchemaBox.inst_phi(10, inc))
header.push(MirSchemaBox.inst_compare(cmpop, 10, 2, 11))
header.push(MirSchemaBox.inst_branch(11, 2, 4))
// Body
local body = new ArrayBox()
body.push(MirSchemaBox.inst_binop("Add", 10, 3, 12))
body.push(MirSchemaBox.inst_jump(3))
// Latch
local latch = new ArrayBox(); latch.push(MirSchemaBox.inst_jump(1))
// Exit
local exit = new ArrayBox(); exit.push(MirSchemaBox.inst_ret(10))
local blocks = new ArrayBox()
blocks.push(MirSchemaBox.block(0, pre))
blocks.push(MirSchemaBox.block(1, header))
blocks.push(MirSchemaBox.block(2, body))
blocks.push(MirSchemaBox.block(3, latch))
blocks.push(MirSchemaBox.block(4, exit))
return MirSchemaBox.module(MirSchemaBox.fn_main(blocks))
}
// Unified entry — build(mode, limit, skip_value, break_value)
// mode:
// - "count" : counting loop that returns final i (uses loop_count)
@ -218,7 +258,13 @@ static box LoopFormBox {
local step = opts.get("step")
local skip_v = opts.get("skip")
local break_v = opts.get("break")
if mode == "count" { if init == null { init = 0 } if step == null { step = 1 } return me.loop_count_param(init, limit, step) }
if mode == "count" {
if init == null { init = 0 }
if step == null { step = 1 }
local cmp = opts.get("cmp") // optional: "Lt"/"Le"/"Gt"/"Ge"
if cmp == null { cmp = "Lt" }
return me.loop_count_param_ex(init, limit, step, cmp)
}
if mode == "sum_bc" { return me.loop_counter(limit, skip_v, break_v) }
print("[loopform/unsupported-mode] " + mode)
return null