using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.string_ops as StringOps
using selfhost.shared.common.mini_vm_scan as MiniVmScan
static box Main {
  // --- minimal helpers ---
  read_digits(s, pos) { return StringHelpers.read_digits(s, pos) }
  // --- core: collect Print outputs in order ---
  collect_prints(json) {
    local out = new ArrayBox()
    local pos = 0
    local guard = 0
    local k_print = "\"kind\":\"Print\""
    loop (true) {
      guard = guard + 1
      if guard > 200 { break }
      local p = StringOps.index_of_from(json, k_print, pos)
      if p < 0 { break }
      // bound current Print slice as [current_print, next_print)
      local obj_start = p
      local next_p = StringOps.index_of_from(json, k_print, p + k_print.length())
      local obj_end = json.length()
      if next_p > 0 { obj_end = next_p }

      // 1) BinaryOp(int '+' int)
      {
        local k_expr = "\"expression\":{"
        local epos = StringOps.index_of_from(json, k_expr, obj_start)
        if epos > 0 { if epos < obj_end {
          local k_bo = "\"kind\":\"BinaryOp\""
          local bpos = StringOps.index_of_from(json, k_bo, epos)
          if bpos > 0 { if bpos < obj_end {
            local opok = StringOps.index_of_from(json, "\"operator\":\"+\"", bpos)
            if opok > 0 {
              // typed left/right literal ints
              local k_l = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
              local k_r = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
              local lp = StringOps.index_of_from(json, k_l, bpos)
              if lp > 0 { if lp < obj_end {
                local ld = me.read_digits(json, lp + k_l.length())
                if ld != "" {
                  local rp = StringOps.index_of_from(json, k_r, lp + k_l.length())
                  if rp > 0 { if rp < obj_end {
                    local rd = me.read_digits(json, rp + k_r.length())
                    if rd != "" { out.push(_int_to_str(_str_to_int(ld) + _str_to_int(rd)))  pos = p + k_print.length()  continue }
                  }}
                }
              }}
              // fallback: scan two successive '"value":' digits within expression bounds
              local k_v = "\"value\":"
              local v1 = StringOps.index_of_from(json, k_v, epos)
              if v1 > 0 { if v1 < obj_end {
                local d1 = me.read_digits(json, v1 + k_v.length())
                if d1 != "" {
                  local v2 = StringOps.index_of_from(json, k_v, v1 + k_v.length())
                  if v2 > 0 { if v2 < obj_end {
                    local d2 = me.read_digits(json, v2 + k_v.length())
                    if d2 != "" { out.push(_int_to_str(_str_to_int(d1) + _str_to_int(d2)))  pos = p + k_print.length()  continue }
                  }}
                }
              }}
            }
          }}
        }}
      }

      // 2) Compare(lhs/rhs ints): prints 1/0
      {
        local k_cp = "\"kind\":\"Compare\""
        local cpos = StringOps.index_of_from(json, k_cp, obj_start)
        if cpos > 0 { if cpos < obj_end {
          local k_op = "\"operation\":\""
          local opos = StringOps.index_of_from(json, k_op, cpos)
          if opos > 0 { if opos < obj_end {
            local oi = opos + k_op.length()
            local oj = StringOps.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 = StringOps.index_of_from(json, k_v, oj)
              if lhs_v > 0 { if lhs_v < obj_end {
                local la = me.read_digits(json, lhs_v + k_v.length())
                if la != "" {
                  local rhs_v = StringOps.index_of_from(json, k_v, lhs_v + k_v.length())
                  if rhs_v > 0 { if rhs_v < obj_end {
                    local rb = me.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
                    }
                  }}
                }
              }}
            }}
          }}
        }}
      }

      // 3) FunctionCall echo/itoa (single literal arg)
      {
        local k_fc = "\"kind\":\"FunctionCall\""
        local fcp = StringOps.index_of_from(json, k_fc, obj_start)
        if fcp > 0 { if fcp < obj_end {
          local kn = "\"name\":\""
          local np = StringOps.index_of_from(json, kn, fcp)
          if np > 0 { if np < obj_end {
            local ni = np + kn.length()
            local nj = StringOps.index_of_from(json, "\"", ni)
            if nj > 0 { if nj <= obj_end {
              local fname = json.substring(ni, nj)
              local ka = "\"arguments\":["
              local ap = StringOps.index_of_from(json, ka, nj)
              if ap > 0 { if ap < obj_end {
                // string arg
                local ks = "\"type\":\"string\",\"value\":\""
                local ps = StringOps.index_of_from(json, ks, ap)
                if ps > 0 { if ps < obj_end {
                  local si = ps + ks.length()
                  local sj = StringOps.index_of_from(json, "\"", si)
                  if sj > 0 { if sj <= obj_end {
                    local sval = json.substring(si, sj)
                    if fname == "echo" { out.push(sval)  pos = p + k_print.length()  continue }
                  }}
                }}
                // int arg
                local ki = "\"type\":\"int\",\"value\":"
                local pi = StringOps.index_of_from(json, ki, ap)
                if pi > 0 { if pi < obj_end {
                  local ival = me.read_digits(json, pi + ki.length())
                  if ival != "" { if fname == "itoa" { out.push(ival)  pos = p + k_print.length()  continue } else { if fname == "echo" { out.push(ival)  pos = p + k_print.length()  continue } } }
                }}
              }}
            }}
          }}
        }}
      }

      // 4) Literal string
      {
        local ks = "\"type\":\"string\",\"value\":\""
        local ps = StringOps.index_of_from(json, ks, obj_start)
        if ps > 0 { if ps < obj_end {
          local si = ps + ks.length()
          local sj = StringOps.index_of_from(json, "\"", si)
          if sj > 0 { if sj <= obj_end { out.push(json.substring(si, sj))  pos = p + k_print.length()  continue }}
        }}
      }
      // 5) Literal int
      {
        local ki = "\"type\":\"int\",\"value\":"
        local pi = StringOps.index_of_from(json, ki, obj_start)
        if pi > 0 { if pi < obj_end {
          local digits = me.read_digits(json, pi + ki.length())
          if digits != "" { out.push(digits)  pos = p + k_print.length()  continue }
        }}
      }
      // Unknown: skip ahead
      pos = p + k_print.length()
      if pos <= p { pos = p + 1 }
    }
    return out
  }
  // int<->str delegation to StringHelpers
  _str_to_int(s) { return StringHelpers.to_i64(s) }
  _int_to_str(n) { return StringHelpers.int_to_str(n) }
  main(args) {
    local json = "{\"kind\":\"Program\",\"statements\":[{\"kind\":\"Print\",\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"string\",\"value\":\"A\"}}},{\"kind\":\"Print\",\"expression\":{\"kind\":\"FunctionCall\",\"name\":\"echo\",\"arguments\":[{\"kind\":\"Literal\",\"value\":{\"type\":\"string\",\"value\":\"B\"}}]}},{\"kind\":\"Print\",\"expression\":{\"kind\":\"FunctionCall\",\"name\":\"itoa\",\"arguments\":[{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":7}}]}},{\"kind\":\"Print\",\"expression\":{\"kind\":\"Compare\",\"operation\":\"<\",\"lhs\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":1}},\"rhs\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":2}}}},{\"kind\":\"Print\",\"expression\":{\"kind\":\"BinaryOp\",\"operator\":\"+\",\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":3}},\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":4}}}},{\"kind\":\"Print\",\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":5}}}]}"

    local arr = collect_prints(json)
    local i = 0
    loop (i < arr.length()) { print(arr.get(i))  i = i + 1 }
    return 0
  }
}
