Files
hakorune/archive/codex-solutions/mini_vm_core-codex-solution.nyash

775 lines
33 KiB
Plaintext
Raw Normal View History

using selfhost.vm.boxes.json_cur as MiniJson
using selfhost.common.mini_vm_scan as MiniVmScan
using selfhost.common.mini_vm_binop as MiniVmBinOp
using selfhost.common.mini_vm_compare as MiniVmCompare
using selfhost.vm.boxes.mini_vm_prints as MiniVmPrints
static box MiniVm {
_is_digit(ch) {
if ch == "0" { return 1 }
if ch == "1" { return 1 }
if ch == "2" { return 1 }
if ch == "3" { return 1 }
if ch == "4" { return 1 }
if ch == "5" { return 1 }
if ch == "6" { return 1 }
if ch == "7" { return 1 }
if ch == "8" { return 1 }
if ch == "9" { return 1 }
return 0
}
_str_to_int(s) { return new MiniVmScan()._str_to_int(s) }
_int_to_str(n) { return new MiniVmScan()._int_to_str(n) }
read_digits(json, pos) { return new MiniJson().read_digits_from(json, pos) }
// Read a JSON string starting at position pos (at opening quote); returns the decoded string
read_json_string(json, pos) { return new MiniJson().read_quoted_from(json, pos) }
// helper: find needle from position pos
index_of_from(hay, needle, pos) { return new MiniVmScan().index_of_from(hay, needle, pos) }
// helper: next non-whitespace character index from pos
next_non_ws(json, pos) { return new MiniJson().next_non_ws(json, pos) }
// ——— Helpers (as box methods) ———
// Minimal: Print(BinaryOp) with operator "+"; supports string+string and int+int
// try_print_binop_at moved to MiniVmBinOp
// Greedy fallback: detect BinaryOp int+int by pattern regardless of field order nuances
// try_print_binop_int_greedy moved to MiniVmBinOp
// Fallback: within the current Print's expression BinaryOp object, scan for two numeric values and sum
// try_print_binop_sum_any moved to MiniVmBinOp
// Deterministic: within the first Print.expression BinaryOp('+'),
// find exactly two numeric values from successive '"value":' fields and sum.
// Stops after collecting two ints; bounded strictly by the expression object.
// try_print_binop_sum_expr_values moved to MiniVmBinOp
// Simpler deterministic fallback: after the first BinaryOp '+',
// scan forward for two successive 'value' fields and sum their integer digits.
// This avoids brace matching and remains bounded by two finds.
// try_print_binop_sum_after_bop moved to MiniVmBinOp
// Direct typed BinaryOp(int+int) matcher using explicit left/right literal paths
try_print_binop_typed_direct(json) {
local k_left = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local k_right = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local lp = json.indexOf(k_left)
if lp < 0 { return -1 }
local ld = read_digits(json, lp + k_left.length())
if ld == "" { return -1 }
local rp = index_of_from(json, k_right, lp + k_left.length())
if rp < 0 { return -1 }
local rd = read_digits(json, rp + k_right.length())
if rd == "" { return -1 }
print(_int_to_str(_str_to_int(ld) + _str_to_int(rd)))
return rp + k_right.length()
}
// Tokenized typed extractor: search left/right blocks then type/value pairs
try_print_binop_typed_tokens(json) {
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = json.indexOf(k_bo)
if bpos < 0 { return -1 }
local lp = index_of_from(json, "\"left\":", bpos)
if lp < 0 { return -1 }
local kt = "\"type\":\"int\""
local kv = "\"value\":"
local tp1 = index_of_from(json, kt, lp)
if tp1 < 0 { return -1 }
local vp1 = index_of_from(json, kv, tp1)
if vp1 < 0 { return -1 }
local ld = read_digits(json, vp1 + kv.length())
if ld == "" { return -1 }
local rp = index_of_from(json, "\"right\":", lp)
if rp < 0 { return -1 }
local tp2 = index_of_from(json, kt, rp)
if tp2 < 0 { return -1 }
local vp2 = index_of_from(json, kv, tp2)
if vp2 < 0 { return -1 }
local rd = read_digits(json, vp2 + kv.length())
if rd == "" { return -1 }
print(_int_to_str(_str_to_int(ld) + _str_to_int(rd)))
return rp
}
// Fast value-pair extractor: find left/right then first value digits after each
try_print_binop_value_pairs(json) {
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = json.indexOf(k_bo)
if bpos < 0 { return -1 }
local kl = "\"left\":"
local kv = "\"value\":"
local lp = index_of_from(json, kl, bpos)
if lp < 0 { return -1 }
local v1 = index_of_from(json, kv, lp)
if v1 < 0 { return -1 }
local ld = read_digits(json, v1 + kv.length())
if ld == "" { return -1 }
local rp = index_of_from(json, "\"right\":", lp)
if rp < 0 { return -1 }
local v2 = index_of_from(json, kv, rp)
if v2 < 0 { return -1 }
local rd = read_digits(json, v2 + kv.length())
if rd == "" { return -1 }
print(_int_to_str(_str_to_int(ld) + _str_to_int(rd)))
return v2 + kv.length()
}
// Minimal: Print(Compare) for integers. Prints 1/0 for true/false.
// try_print_compare_at moved to MiniVmCompare
// Extract first Print literal from JSON v0 Program and return its string representation
parse_first_print_literal(json) {
// Find a Print statement
local k_print = "\"kind\":\"Print\""
local p = json.indexOf(k_print)
if p < 0 { return null }
// Find value type in the expression following Print
local k_type = "\"type\":\""
local tpos = json.indexOf(k_type)
if tpos < 0 { return null }
tpos = tpos + k_type.length()
// Read type name until next quote
local t_end = index_of_from(json, "\"", tpos)
if t_end < 0 { return null }
local ty = json.substring(tpos, t_end)
// Find value field
local k_val = "\"value\":"
local vpos = index_of_from(json, k_val, t_end)
if vpos < 0 { return null }
vpos = vpos + k_val.length()
if ty == "int" || ty == "i64" || ty == "integer" {
// read digits via MiniJson
local digits = new MiniJson().read_digits_from(json, vpos)
return digits
}
if ty == "string" {
// read quoted via MiniJson
local i = index_of_from(json, "\"", vpos)
if i < 0 { return null }
return new MiniJson().read_quoted_from(json, i)
}
// Other types not supported yet
return null
}
// helper: find balanced bracket range [ ... ] starting at idx (points to '[')
find_balanced_array_end(json, idx) { return new MiniVmScan().find_balanced_array_end(json, idx) }
// helper: find balanced object range { ... } starting at idx (points to '{')
find_balanced_object_end(json, idx) { return new MiniVmScan().find_balanced_object_end(json, idx) }
// Print all Print-Literal values within [start,end] (inclusive slice indices)
print_prints_in_slice(json, start, end) { return new MiniVmPrints().print_prints_in_slice(json, start, end) }
// Process top-level If with literal condition; print branch prints. Returns printed count.
process_if_once(json) { return new MiniVmPrints().process_if_once(json) }
print_all_print_literals(json) { return new MiniVmPrints().print_all_print_literals(json) }
parse_first_int(json) {
local key = "\"value\":{\"type\":\"int\",\"value\":"
local idx = json.lastIndexOf(key)
if idx < 0 { return "0" }
local start = idx + key.length()
return read_digits(json, start)
}
// Fallback: find first BinaryOp and return sum of two numeric values as string; empty if not found
parse_first_binop_sum(json) {
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = json.indexOf(k_bo)
if bpos < 0 { return "" }
// typed pattern inside left/right.literal.value: {"type":"int","value":<digits>}
local k_typed = "\"type\":\"int\",\"value\":"
// first number
local p1 = index_of_from(json, k_typed, bpos)
if p1 < 0 { return "" }
local d1 = read_digits(json, p1 + k_typed.length())
if d1 == "" { return "" }
// second number
local p2 = index_of_from(json, k_typed, p1 + k_typed.length())
if p2 < 0 { return "" }
local d2 = read_digits(json, p2 + k_typed.length())
if d2 == "" { return "" }
return _int_to_str(_str_to_int(d1) + _str_to_int(d2))
}
// Linear pass: sum all numbers outside of quotes (fast, finite)
sum_numbers_no_quotes(json) { return new MiniVmScan().sum_numbers_no_quotes(json) }
// Naive: sum all digit runs anywhere (for simple BinaryOp JSON)
sum_all_digits_naive(json) { return new MiniVmScan().sum_all_digits_naive(json) }
// Sum first two integers outside quotes; returns string or empty if not found
sum_first_two_numbers(json) { return new MiniVmScan().sum_first_two_numbers(json) }
// Sum two integers near a BinaryOp '+' token; bounded window to keep steps low
sum_two_numbers_near_plus(json) {
local k_plus = "\"operator\":\"+\""
local op = json.indexOf(k_plus)
if op < 0 { return "" }
local n = json.length()
local start = op - 120
if start < 0 { start = 0 }
local limit = op + 240
if limit > n { limit = n }
local i = start
local found = 0
local a = 0
loop (i < limit) {
local ch = json.substring(i, i+1)
if ch == "\"" {
// skip to next quote within window
local j = index_of_from(json, "\"", i+1)
if j < 0 || j > limit { break }
i = j + 1
continue
}
local d = read_digits(json, i)
if d {
if found == 0 {
a = _str_to_int(d)
found = 1
} else {
local b = _str_to_int(d)
return _int_to_str(a + b)
}
i = i + d.length()
continue
}
i = i + 1
}
return ""
}
// Fallback: sum all bare numbers (not inside quotes) in the JSON; return string or empty if none
sum_all_numbers(json) {
local cur = new MiniJson()
local i = 0
local n = json.length()
local sum = 0
loop (i < n) {
local ch = json.substring(i, i+1)
if ch == "\"" {
// skip quoted string
local s = cur.read_quoted_from(json, i)
i = i + s.length() + 2
continue
}
// try digits
local d = cur.read_digits_from(json, i)
if d != "" { sum = sum + _str_to_int(d) i = i + d.length() continue }
i = i + 1
}
if sum == 0 { return "" }
return _int_to_str(sum)
}
// (reserved) helper for future robust binop scan
run(json) {
// entry: attempt minimal quick shapes first, then broader routes
// Quick path: Program-level Print of a single Literal string/int
if json.indexOf("\"kind\":\"Program\"") >= 0 && json.indexOf("\"kind\":\"Print\"") >= 0 {
// Literal string
if json.indexOf("\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"string\"") >= 0 {
local ks = "\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"string\",\"value\":\""
local ps = json.indexOf(ks)
if ps >= 0 {
local si = ps + ks.length()
local sj = json.indexOf("\"", si)
if sj >= 0 { print(json.substring(si, sj)) return 0 }
}
}
// Literal int
if json.indexOf("\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\"") >= 0 {
local ki = "\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local pi = json.indexOf(ki)
if pi >= 0 {
local ii = pi + ki.length()
// digits until closing brace
local ie = json.indexOf("}", ii)
if ie < 0 { ie = ii }
local d = json.substring(ii, ie)
if d { print(d) return 0 }
}
}
}
// Single-purpose fast path for smoke: if BinaryOp '+' exists, try expression-bounded extractor first.
if json.indexOf("\"BinaryOp\"") >= 0 && json.indexOf("\"operator\":\"+\"") >= 0 {
// Bind to first Print and extract value×2 within expression bounds
local k_print = "\"kind\":\"Print\""
local p = index_of_from(json, k_print, 0)
if p >= 0 {
local np0 = new MiniVmBinOp().try_print_binop_sum_expr_values(json, json.length(), p)
if np0 > 0 { return 0 }
}
// Typed direct inside BinaryOp object (fast and finite)
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = json.indexOf(k_bo)
if bpos >= 0 {
local k_lint = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local li = index_of_from(json, k_lint, bpos)
if li >= 0 {
local ld = read_digits(json, li + k_lint.length())
if ld != "" {
local k_rint = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local ri = index_of_from(json, k_rint, li + k_lint.length())
if ri >= 0 {
local rd = read_digits(json, ri + k_rint.length())
if rd != "" { print(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) return 0 }
}
}
}
}
// As a final bounded fallback under BinaryOp '+', sum first two numbers outside quotes
{
local s2 = sum_first_two_numbers(json)
if s2 { print(s2) return 0 }
}
// (skip near-operator windowed scan to avoid high step counts under PyVM)
}
// Prefer If(literal) branch handling first
local ifc = process_if_once(json)
if ifc > 0 { return 0 }
// Quick conservative path: if BinaryOp exists, sum bare numbers outside quotes
// (limited to simple BinaryOp(int,int) JSON)
if json.indexOf("\"BinaryOp\"") >= 0 {
// Prefer expression-bounded scan first
local k_print = "\"kind\":\"Print\""
local p = index_of_from(json, k_print, 0)
if p >= 0 {
// Deterministic: sum the first two numbers from successive 'value' fields
local np0 = new MiniVmBinOp().try_print_binop_sum_expr_values(json, json.length(), p)
if np0 > 0 { return 0 }
}
// Brace-free deterministic fallback tied to the first BinaryOp
{
local np1 = new MiniVmBinOp().try_print_binop_sum_after_bop(json)
if np1 > 0 { return 0 }
}
// avoid global number-sum fallback to keep steps bounded
}
// 0) direct typed BinaryOp '+' fast-path (explicit left/right literal ints)
local k_bo = "\"kind\":\"BinaryOp\""
local k_plus = "\"operator\":\"+\""
if json.indexOf(k_bo) >= 0 && json.indexOf(k_plus) >= 0 {
local np = try_print_binop_typed_direct(json)
if np > 0 { return 0 }
np = try_print_binop_typed_tokens(json)
if np > 0 { return 0 }
np = try_print_binop_value_pairs(json)
if np > 0 { return 0 }
// (skip bounded-window fallback around '+')
}
// 0) quick path: BinaryOp(int+int) typed fast-path
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = json.indexOf(k_bo)
if bpos >= 0 {
// typed left/right ints inside BinaryOp
local k_lint = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local li = index_of_from(json, k_lint, bpos)
if li >= 0 {
local ld = read_digits(json, li + k_lint.length())
if ld != "" {
local k_rint = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local ri = index_of_from(json, k_rint, li + k_lint.length())
if ri >= 0 {
local rd = read_digits(json, ri + k_rint.length())
if rd != "" {
print(_int_to_str(_str_to_int(ld) + _str_to_int(rd)))
return 0
}
}
}
}
// fallback: sum two numeric values within the first Print.expression BinaryOp object
local k_print = "\"kind\":\"Print\""
local p = index_of_from(json, k_print, 0)
if p >= 0 {
local k_expr = "\"expression\":{"
local epos = index_of_from(json, k_expr, p)
if epos > 0 {
local obj_start = index_of_from(json, "{", epos)
local obj_end = find_balanced_object_end(json, obj_start)
if obj_start > 0 && obj_end > 0 {
local k_bo2 = "\"kind\":\"BinaryOp\""
local b2 = index_of_from(json, k_bo2, obj_start)
if b2 > 0 && b2 < obj_end {
local k_v = "\"value\":"
local p1 = index_of_from(json, k_v, obj_start)
local d1 = ""
loop (p1 > 0 && p1 < obj_end) {
d1 = new MiniJson().read_digits_from(json, p1 + k_v.length())
if d1 != "" { break }
p1 = index_of_from(json, k_v, p1 + k_v.length())
}
if d1 != "" {
local p2 = index_of_from(json, k_v, p1 + k_v.length())
local d2 = ""
loop (p2 > 0 && p2 < obj_end) {
d2 = new MiniJson().read_digits_from(json, p2 + k_v.length())
if d2 != "" { break }
p2 = index_of_from(json, k_v, p2 + k_v.length())
}
if d2 != "" {
local ai = _str_to_int(d1)
local bi = _str_to_int(d2)
print(_int_to_str(ai + bi))
return 0
}
}
}
}
}
}
// fallback: parse-first within BinaryOp scope by scanning two numeric values
local ssum = new MiniVmBinOp().parse_first_binop_sum(json)
if ssum { print(ssum) return 0 }
}
// Attempt expression-local BinaryOp sum via existing helper on first Print
{
local k_print = "\"kind\":\"Print\""
local p = index_of_from(json, k_print, 0)
if p >= 0 {
local np = new MiniVmBinOp().try_print_binop_sum_any(json, json.length(), p)
if np > 0 { return 0 }
}
}
// 0-c) quick path: Compare(lhs int, rhs int)
local k_cp = "\"kind\":\"Compare\""
local cpos = json.indexOf(k_cp)
if cpos >= 0 {
// operation
local k_op = "\"operation\":\""
local opos = index_of_from(json, k_op, cpos)
if opos > 0 {
local oi = opos + k_op.length()
local oj = index_of_from(json, "\"", oi)
if oj > 0 {
local op = json.substring(oi, oj)
// lhs value
local k_lhs = "\"lhs\":{\"kind\":\"Literal\""
local hl = index_of_from(json, k_lhs, oj)
if hl > 0 {
local k_v = "\"value\":"
local hv = index_of_from(json, k_v, hl)
if hv > 0 {
local a = read_digits(json, hv + k_v.length())
// rhs value
local k_rhs = "\"rhs\":{\"kind\":\"Literal\""
local hr = index_of_from(json, k_rhs, hl)
if hr > 0 {
local rv = index_of_from(json, k_v, hr)
if rv > 0 {
local b = read_digits(json, rv + k_v.length())
if a && b {
local ai = _str_to_int(a)
local bi = _str_to_int(b)
local res = 0
if op == "<" { if ai < bi { res = 1 } }
if op == "==" { if ai == bi { res = 1 } }
if op == "<=" { if ai <= bi { res = 1 } }
if op == ">" { if ai > bi { res = 1 } }
if op == ">=" { if ai >= bi { res = 1 } }
if op == "!=" { if ai != bi { res = 1 } }
print(res)
return 0
}
}
}
}
}
}
}
}
// Scan global prints (flat programs)
local pc = print_all_print_literals(json)
// 2) as a robustness fallback, handle first BinaryOp sum within first Print.expression
if pc == 0 {
local k_print = "\"kind\":\"Print\""
local p = index_of_from(json, k_print, 0)
if p >= 0 {
local k_expr = "\"expression\":{"
local epos = index_of_from(json, k_expr, p)
if epos > 0 {
local obj_start = index_of_from(json, "{", epos)
local obj_end = find_balanced_object_end(json, obj_start)
if obj_start > 0 && obj_end > 0 {
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = index_of_from(json, k_bo, obj_start)
if bpos > 0 && bpos < obj_end {
// sum two numeric values inside this expression object
local cur = new MiniJson()
local k_v = "\"value\":"
local p1 = index_of_from(json, k_v, obj_start)
local d1 = ""
loop (p1 > 0 && p1 < obj_end) {
d1 = cur.read_digits_from(json, p1 + k_v.length())
if d1 != "" { break }
p1 = index_of_from(json, k_v, p1 + k_v.length())
}
if d1 != "" {
local p2 = index_of_from(json, k_v, p1 + k_v.length())
local d2 = ""
loop (p2 > 0 && p2 < obj_end) {
d2 = cur.read_digits_from(json, p2 + k_v.length())
if d2 != "" { break }
p2 = index_of_from(json, k_v, p2 + k_v.length())
}
if d2 != "" {
local ai = _str_to_int(d1)
local bi = _str_to_int(d2)
print(_int_to_str(ai + bi))
pc = 1
}
}
}
}
}
}
}
if pc == 0 {
// last resort: typed pattern-wide sum, then safe number sum outside quotes, else single int literal
local s = new MiniVmBinOp().parse_first_binop_sum(json)
if s { print(s) } else {
local ts = sum_numbers_no_quotes(json)
if ts { print(ts) } else {
local n = parse_first_int(json)
print(n)
}
}
}
return 0
}
// Pure helper: collect minimal print outputs (literals only) into an array
collect_prints(json) {
// Ported from self-contained smoke (Hardened minimal scanner)
local out = new ArrayBox()
local pos = 0
local guard = 0
// DEV trace: flip to 1 for one-run diagnosis; keep 0 for normal
local trace = 0
if trace == 1 { print("[collect][start] method entry") }
local k_print = "\"kind\":\"Print\""
loop (true) {
guard = guard + 1
if guard > 200 {
if trace == 1 { print("[collect][guard_break] guard="+guard) }
if trace == 1 { print("[collect][loop_exit] guard="+guard+" out.size="+out.size()) }
if trace == 1 { print("[collect][return] out.size="+out.size()) }
return out
}
local p = index_of_from(json, k_print, pos)
if trace == 1 { print("[collect][loop] pos="+pos+" p="+p+" guard="+guard) }
if p < 0 {
if trace == 1 { print("[collect][p_break] p="+p) }
if trace == 1 { print("[collect][loop_exit] guard="+guard+" out.size="+out.size()) }
if trace == 1 { print("[collect][return] out.size="+out.size()) }
return out
}
// bound current Print slice to [this, next)
local obj_start = p
local next_p = index_of_from(json, k_print, p + k_print.length())
local obj_end = json.length()
if next_p > 0 { obj_end = next_p }
if trace == 1 { print("[collect][p] "+p) print("[collect][next_p] "+next_p) print("[collect][slice_end] "+obj_end) }
if trace == 1 {
local k_expr = "\"expression\":{"
local epos_dbg = index_of_from(json, k_expr, obj_start)
print("[scan][expr] "+epos_dbg)
local fc_dbg = index_of_from(json, "\"kind\":\"FunctionCall\"", obj_start)
print("[scan][fc] "+fc_dbg)
local bo_dbg = index_of_from(json, "\"kind\":\"BinaryOp\"", obj_start)
print("[scan][bo] "+bo_dbg)
local cp_dbg = index_of_from(json, "\"kind\":\"Compare\"", obj_start)
print("[scan][cp] "+cp_dbg)
local ts_dbg = index_of_from(json, "\"type\":\"string\"", obj_start)
print("[scan][ts] "+ts_dbg)
local ti_dbg = index_of_from(json, "\"type\":\"int\"", obj_start)
print("[scan][ti] "+ti_dbg)
// positions for tight patterns used by branches
local ks_pat = "\"type\":\"string\",\"value\":\""
print("[scan][ks] "+index_of_from(json, ks_pat, obj_start))
local ki_pat = "\"type\":\"int\",\"value\":"
print("[scan][ki] "+index_of_from(json, ki_pat, obj_start))
}
// 1) FunctionCall echo/itoa (single literal or empty args)
{
// Limit search within Print.expression object for stability
local k_expr = "\"expression\":{"
local epos = index_of_from(json, k_expr, obj_start)
if epos > 0 { if epos < obj_end {
local expr_start = index_of_from(json, "{", epos)
if expr_start > 0 { if expr_start < obj_end {
local expr_end = new MiniVmScan().find_balanced_object_end(json, expr_start)
if expr_end > 0 { if expr_end <= obj_end {
if trace == 1 { print("[collect][expr] "+expr_start+","+expr_end) }
local k_fc = "\"kind\":\"FunctionCall\""
local fcp = index_of_from(json, k_fc, expr_start)
if trace == 1 { print("[collect][fc_in_expr] "+fcp+" (bounds "+expr_start+","+expr_end+")") }
if fcp > 0 { if fcp < expr_end {
if trace == 1 { print("[collect][fc_found] entering function call handler") }
local kn = "\"name\":\""
local np = index_of_from(json, kn, fcp)
if trace == 1 { print("[collect][name_search] "+np+" (obj_end "+obj_end+")") }
if np > 0 { if np < obj_end {
local ni = np + kn.length()
local nj = index_of_from(json, "\"", ni)
if trace == 1 { print("[collect][name_bounds] "+ni+","+nj+" (expr_end "+expr_end+")") }
if nj > 0 { if nj <= expr_end {
local fname = json.substring(ni, nj)
if trace == 1 { print("[collect][fname] '"+fname+"'") }
local ka = "\"arguments\":["
local ap = index_of_from(json, ka, nj)
if ap <= 0 {
local ka0 = "\"arguments\":"
local ap0 = index_of_from(json, ka0, nj)
if ap0 >= 0 { if ap0 < expr_end { ap = ap0 } }
}
if ap >= 0 { if ap < expr_end {
// detect empty args [] quickly: no type token inside balanced array
local arr_start = index_of_from(json, "[", ap)
if arr_start >= 0 { if arr_start < expr_end {
local arr_end = new MiniVmScan().find_balanced_array_end(json, arr_start)
if arr_end >= 0 { if arr_end <= expr_end {
local kt = "\"type\":\""
local atpos = index_of_from(json, kt, arr_start)
if trace == 1 { print("[collect][empty_check] atpos="+atpos+" arr_bounds=["+arr_start+","+arr_end+"]") }
if atpos < 0 || atpos >= arr_end {
if trace == 1 { print("[collect][empty_args] fname='"+fname+"'") }
if fname == "echo" { out.push("") pos = obj_end continue }
if fname == "itoa" { out.push("0") pos = obj_end continue }
}
}}}}
// string arg
local ks = "\"type\":\"string\",\"value\":\""
local ps = index_of_from(json, ks, ap)
if ps > 0 { if ps < expr_end {
local si = ps + ks.length()
local sj = index_of_from(json, "\"", si)
if sj > 0 { if sj <= expr_end {
local sval = json.substring(si, sj)
if fname == "echo" { out.push(sval) pos = obj_end + 1 continue }
}}
}}
// int arg
local ki = "\"type\":\"int\",\"value\":"
local pi = index_of_from(json, ki, ap)
if pi > 0 { if pi < expr_end {
local ival = read_digits(json, pi + ki.length())
if ival != "" { if fname == "itoa" { out.push(ival) pos = obj_end + 1 continue } else { if fname == "echo" { out.push(ival) pos = obj_end + 1 continue } } }
}}
}}
}}
}}
}}}
}}
}}
}
// 2) BinaryOp(int '+' int)
{
local k_expr = "\"expression\":{"
local epos = index_of_from(json, k_expr, obj_start)
if epos > 0 { if epos < obj_end {
local k_bo = "\"kind\":\"BinaryOp\""
local bpos = index_of_from(json, k_bo, epos)
if bpos > 0 { if bpos < obj_end {
if index_of_from(json, "\"operator\":\"+\"", bpos) > 0 {
local k_l = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local k_r = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
local lp = index_of_from(json, k_l, bpos)
if lp > 0 { if lp < obj_end {
local ld = read_digits(json, lp + k_l.length())
if ld != "" {
local rp = index_of_from(json, k_r, lp + k_l.length())
if rp > 0 { if rp < obj_end {
local rd = read_digits(json, rp + k_r.length())
if rd != "" { if trace == 1 { print("[hit][bo-typed] "+ld+"+"+rd) } out.push(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) pos = p + k_print.length() continue }
}}
}
}}
// fallback: two successive 'value' digits within expression bounds
local k_v = "\"value\":"
local v1 = index_of_from(json, k_v, epos)
if v1 > 0 { if v1 < obj_end {
local d1 = new MiniJson().read_digits_from(json, v1 + k_v.length())
if d1 != "" {
local v2 = index_of_from(json, k_v, v1 + k_v.length())
if v2 > 0 { if v2 < obj_end {
local d2 = new MiniJson().read_digits_from(json, v2 + k_v.length())
if d2 != "" { if trace == 1 { print("[hit][bo-fallback] "+d1+"+"+d2) } out.push(_int_to_str(_str_to_int(d1) + _str_to_int(d2))) pos = p + k_print.length() continue }
}}
}
}}
}
}}
}}
}
// 3) Compare(lhs/rhs ints)
{
local k_cp = "\"kind\":\"Compare\""
local cpos = index_of_from(json, k_cp, obj_start)
if cpos > 0 { if cpos < obj_end {
local k_op = "\"operation\":\""
local opos = index_of_from(json, k_op, cpos)
if opos > 0 { if opos < obj_end {
local oi = opos + k_op.length()
local oj = index_of_from(json, "\"", oi)
if oj > 0 { if oj <= obj_end {
local op = json.substring(oi, oj)
local k_v = "\"value\":"
local lhs_v = index_of_from(json, k_v, oj)
if lhs_v > 0 { if lhs_v < obj_end {
local la = read_digits(json, lhs_v + k_v.length())
if la != "" {
local rhs_v = index_of_from(json, k_v, lhs_v + k_v.length())
if rhs_v > 0 { if rhs_v < obj_end {
local rb = read_digits(json, rhs_v + k_v.length())
if rb != "" {
local ai = _str_to_int(la)
local bi = _str_to_int(rb)
local res = 0
if op == "<" { if ai < bi { res = 1 } }
if op == "==" { if ai == bi { res = 1 } }
if op == "<=" { if ai <= bi { res = 1 } }
if op == ">" { if ai > bi { res = 1 } }
if op == ">=" { if ai >= bi { res = 1 } }
if op == "!=" { if ai != bi { res = 1 } }
out.push(_int_to_str(res))
pos = p + k_print.length()
continue
}
}}
}
}}
}}
}}
}}
}
// (FunctionCall branch moved earlier)
// 4) Literal string
{
local ks = "\"type\":\"string\",\"value\":\""
local ps = index_of_from(json, ks, obj_start)
if ps > 0 { if ps < obj_end {
local si = ps + ks.length()
local sj = index_of_from(json, "\"", si)
if sj > 0 { if sj <= obj_end {
if trace == 1 { print("[hit][str]") }
out.push(json.substring(si, sj)) pos = p + k_print.length() continue
}}
}}
}
// 5) Literal int
{
local ki = "\"type\":\"int\",\"value\":"
local pi = index_of_from(json, ki, obj_start)
if pi > 0 { if pi < obj_end {
local digits = read_digits(json, pi + ki.length())
if digits != "" { if trace == 1 { print("[hit][i-lit] "+digits) } out.push(digits) pos = p + k_print.length() continue }
}}
}
// Unknown: skip this Print object entirely to avoid stalls and mis-detection
// Use coarse slice end (next Print position) when available; fallback to k_print-length step
pos = obj_end + 1
if pos <= p { pos = p + k_print.length() }
}
if trace == 1 { print("[collect][loop_exit] guard="+guard+" out.size="+out.size()) }
if trace == 1 { print("[collect][return] out.size="+out.size()) }
return out
}
}