// step_runner.hako — Mini‑VM JSON v0 ステップ観測用の軽量箱（実行はしない）
using selfhost.vm.boxes.compare_ops as CompareOpsBox
using selfhost.shared.json.core.json_cursor as JsonCursorBox

static box StepRunnerBox {
  // 文字列ヘルパ
  // 文字列ヘルパ（JsonCursorBox に委譲）
  _index_of_from(hay, needle, pos) { return JsonCursorBox.index_of_from(hay, needle, pos) }
  // Delegate digit scanning to JsonCursorBox for consistency
  _read_digits(text, pos) { return JsonCursorBox.digits_from(text, pos) }
  _int(s) { local t = "" + s if t == "" { return 0 } local i = 0 local neg = 0 if t.substring(0,1) == "-" { neg = 1 i = 1 } local acc = 0 loop(i < t.length()) { local ch = t.substring(i, i+1) if ch < "0" || ch > "9" { break } acc = acc * 10 + (ch == "0" ? 0 : ch == "1" ? 1 : ch == "2" ? 2 : ch == "3" ? 3 : ch == "4" ? 4 : ch == "5" ? 5 : ch == "6" ? 6 : ch == "7" ? 7 : ch == "8" ? 8 : 9) i = i + 1 } if neg == 1 { acc = 0 - acc } return acc }

  // block 0 の instructions セグメント抽出
  _block0_segment(mjson) {
    local key = "\"instructions\":["
    local k = me._index_of_from(mjson, key, 0)
    if k < 0 { return "" }
    local lb = k + key.length() - 1
    // Delegate to JsonScanBox for robust end detection (escape-aware)
        local rb = JsonCursorBox.seek_array_end(mjson, lb)
    if rb < 0 { return "" }
    return mjson.substring(lb + 1, rb)
  }

  // compare の (lhs,rhs,kind,dst) を抽出
  parse_compare(seg) {
    local p = JsonCursorBox.index_of_from(seg, "\"op\":\"compare\"", 0)
    if p < 0 { return {} }
    local lhs = me._int(me._read_digits(seg, JsonCursorBox.index_of_from(seg, "\"lhs\":", p) + 6))
    local rhs = me._int(me._read_digits(seg, JsonCursorBox.index_of_from(seg, "\"rhs\":", p) + 6))
    local dst = me._int(me._read_digits(seg, JsonCursorBox.index_of_from(seg, "\"dst\":", p) + 6))
    // kind
    local kpos = JsonCursorBox.index_of_from(seg, "\"cmp\":\"", p)
    local kend = me._index_of_from(seg, "\"", kpos + 6)
    local kind = seg.substring(kpos + 6, kend)
    return { lhs: lhs, rhs: rhs, dst: dst, kind: kind }
  }

  // branch の cond/then/else を抽出
  parse_branch(seg) {
    local p = JsonCursorBox.index_of_from(seg, "\"op\":\"branch\"", 0)
    if p < 0 { return {} }
    local cond = me._int(me._read_digits(seg, JsonCursorBox.index_of_from(seg, "\"cond\":", p) + 7))
    local then_id = me._int(me._read_digits(seg, JsonCursorBox.index_of_from(seg, "\"then\":", p) + 7))
    local else_id = me._int(me._read_digits(seg, JsonCursorBox.index_of_from(seg, "\"else\":", p) + 7))
    return { cond: cond, then: then_id, else: else_id }
  }

  // compare を評価し cond==dst のときに bool を返す
  eval_branch_bool(mjson) {
    local seg = me._block0_segment(mjson)
    if seg == "" { return 0 }
    local cmp = me.parse_compare(seg)
    local br = me.parse_branch(seg)
    if cmp.get == null || br.get == null { return 0 }
    local kind = "" + cmp.get("kind")
    local lhs = cmp.get("lhs")
    local rhs = cmp.get("rhs")
    local dst = cmp.get("dst")
    local cond = br.get("cond")
    if cond != dst { return 0 } // 最小仕様: cond は直前 compare の dst
    local r = CompareOpsBox.eval(kind, lhs, rhs)
    return r
  }

  main(args) { return 0 }
}
