docs(20.39): add Next Steps and mark hv1 unify + string scanner fix DONE; loop count_param: accept swapped < / <= (cmp Gt/Ge); add canaries for swapped_lt/lte

This commit is contained in:
nyash-codex
2025-11-04 20:51:15 +09:00
parent 44a5158a14
commit 51bf7ff410
5 changed files with 113 additions and 26 deletions

View File

@ -79,8 +79,10 @@ static box LowerLoopCountParamBox {
cmp = (op == ">") ? "Gt" : "Ge"
} else { return null }
} else {
// swapped (Int on lhs, Var i on rhs): L > i / L >= i (ascending)
if op != ">" && op != ">=" { return null }
// swapped (Int on lhs, Var i on rhs):
// L > i / L >= i → ascendingi < L / i < L+1→ cmp="Lt"limit +1 for >=
// L < i / L <= i → descendingi > L / i >= L→ cmp="Gt" / "Ge"
if op != ">" && op != ">=" && op != "<" && op != "<=" { return null }
local k_lhs = s.indexOf("\"lhs\":{", k_cmp); if k_lhs < 0 { return null }
local k_lim_t2 = s.indexOf("\"type\":\"Int\"", k_lhs)
if k_lim_t2 >= 0 {
@ -91,8 +93,17 @@ static box LowerLoopCountParamBox {
limit = PatternUtilBox.find_local_int_before(s, lname3, k_cmp)
}
if limit == null { return null }
if op == ">=" { limit = StringHelpers.int_to_str(JsonFragBox._str_to_int(limit) + 1) }
cmp = "Lt"
if op == ">" {
cmp = "Lt"
} else if op == ">=" {
limit = StringHelpers.int_to_str(JsonFragBox._str_to_int(limit) + 1)
cmp = "Lt"
} else if op == "<" {
cmp = "Gt"
} else {
// op == "<="
cmp = "Ge"
}
}
// Body increment: Local i = Binary('+', Var i, Int step)
local k_body_i = s.indexOf("\"name\":\"" + varname + "\"", k_loop)

View File

@ -58,12 +58,19 @@ static box LowerLoopSimpleBox {
return null
}
} else {
// swapped: we expect op to be '>' or '>='
// swapped: L ? i
if op == ">" {
// L > i ≡ i < L
} else if op == ">=" {
// L >= i ≡ i <= L ≡ i < (L+1)
limit = StringHelpers.int_to_str(JsonFragBox._str_to_int(limit) + 1)
} else if op == "<" {
// L < i ≡ i > L → for simple ascending loop (init=0, step=1) this pattern is not canonical;
// we treat as descending form not supported by simple box
return null
} else if op == "<=" {
// L <= i ≡ i >= L — same reason as above
return null
} else {
return null
}