// ops/typeop.hako — NyVmOpTypeOp
// v1 shape: {"op":"typeop","operation":"check|cast","src":VID,"dst":VID,"target_type":STRING}
using selfhost.shared.json.core.json_cursor as JsonCursorBox
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.vm.core.state as NyVmState

static box NyVmOpTypeOp {
  _read_int(inst_json, key) {
    local pat = "\"" + key + "\":"
    local p = JsonCursorBox.find_key_dual(inst_json, pat, pat, 0)
    if p < 0 { return null }
    p = inst_json.indexOf(":", p)
    if p < 0 { return null }
    p = p + 1
    loop(true) { local ch = inst_json.substring(p,p+1) if ch == " " || ch == "\n" || ch == "\r" || ch == "\t" { p = p + 1 continue } break }
    local digits = JsonCursorBox.digits_from(inst_json, p)
    if digits == "" { return null }
    return StringHelpers.to_i64(digits)
  }
  _read_str(inst_json, key) {
    local pat = "\"" + key + "\":"
    local p = JsonCursorBox.find_key_dual(inst_json, pat, pat, 0)
    if p < 0 { return "" }
    p = inst_json.indexOf(":", p)
    if p < 0 { return "" }
    p = p + 1
    loop(true) { local ch = inst_json.substring(p,p+1) if ch == " " || ch == "\n" || ch == "\r" || ch == "\t" { p = p + 1 continue } break }
    if inst_json.substring(p,p+1) != "\"" { return "" }
    local end = JsonCursorBox.scan_string_end(inst_json, p)
    if end < 0 { return "" }
    return inst_json.substring(p+1, end)
  }
  handle(inst_json, state) {
    local dst = me._read_int(inst_json, "dst")
    local src = me._read_int(inst_json, "src")
    local op = me._read_str(inst_json, "operation")
    if dst == null || src == null || op == "" { print("[core/typeop] malformed") return -1 }
    if op == "check" {
      NyVmState.set_reg(state, dst, 1)
      return 0
    }
    if op == "cast" {
      local v = NyVmState.get_reg(state, src)
      NyVmState.set_reg(state, dst, v)
      return 0
    }
    print("[core/typeop] unsupported operation: " + op)
    return -1
  }
}

static box NyVmOpTypeOpMain { main(args){ return 0 } }
