// mir_vm_m2.nyash — Ny製の最小MIR(JSON v0)実行器(M2: const/binop/ret) static box MirVmM2 { _str_to_int(s) { local i = 0 local n = s.length() local acc = 0 loop (i < n) { local ch = s.substring(i, i+1) if ch == "0" { acc = acc * 10 + 0 i = i + 1 continue } if ch == "1" { acc = acc * 10 + 1 i = i + 1 continue } if ch == "2" { acc = acc * 10 + 2 i = i + 1 continue } if ch == "3" { acc = acc * 10 + 3 i = i + 1 continue } if ch == "4" { acc = acc * 10 + 4 i = i + 1 continue } if ch == "5" { acc = acc * 10 + 5 i = i + 1 continue } if ch == "6" { acc = acc * 10 + 6 i = i + 1 continue } if ch == "7" { acc = acc * 10 + 7 i = i + 1 continue } if ch == "8" { acc = acc * 10 + 8 i = i + 1 continue } if ch == "9" { acc = acc * 10 + 9 i = i + 1 continue } break } return acc } _int_to_str(n) { if n == 0 { return "0" } local v = n local out = "" loop (v > 0) { local d = v % 10 local ch = "0" if d == 1 { ch = "1" } else { if d == 2 { ch = "2" } else { if d == 3 { ch = "3" } else { if d == 4 { ch = "4" } else { if d == 5 { ch = "5" } else { if d == 6 { ch = "6" } else { if d == 7 { ch = "7" } else { if d == 8 { ch = "8" } else { if d == 9 { ch = "9" } } } } } } } } out = ch + out v = v / 10 } return out } _find_int_in(seg, keypat) { local p = seg.indexOf(keypat) if p < 0 { return null } p = p + keypat.length() local i = p local out = "" loop(true) { local ch = seg.substring(i, i+1) if ch == "" { break } if ch == "0" || ch == "1" || ch == "2" || ch == "3" || ch == "4" || ch == "5" || ch == "6" || ch == "7" || ch == "8" || ch == "9" { out = out + ch i = i + 1 } else { break } } if out == "" { return null } return me._str_to_int(out) } _find_str_in(seg, keypat) { local p = seg.indexOf(keypat) if p < 0 { return "" } p = p + keypat.length() local q = seg.indexOf(""", p) if q < 0 { return "" } return seg.substring(p, q) } _get(regs, id) { if regs.has(id) { return regs.get(id) } return 0 } _set(regs, id, v) { regs.set(id, v) } _bin(kind, a, b) { if kind == "Add" { return a + b } if kind == "Sub" { return a - b } if kind == "Mul" { return a * b } if kind == "Div" { if b == 0 { return 0 } else { return a / b } } return 0 } run(json) { local regs = new MapBox() local pos = json.indexOf(""instructions":[") if pos < 0 { print("0") return 0 } local cur = pos loop(true) { local op_pos = json.indexOf(""op":"", cur) if op_pos < 0 { break } local name_start = op_pos + 6 local name_end = json.indexOf(""", name_start) if name_end < 0 { break } local opname = json.substring(name_start, name_end) local next_pos = json.indexOf(""op":"", name_end) if next_pos < 0 { next_pos = json.length() } local seg = json.substring(op_pos, next_pos) if opname == "const" { local dst = me._find_int_in(seg, ""dst":") local val = me._find_int_in(seg, ""value":{"type":"i64","value":") if dst != null and val != null { me._set(regs, "" + dst, val) } } else { if opname == "binop" { local dst = me._find_int_in(seg, ""dst":") local kind = me._find_str_in(seg, ""op_kind":"") local lhs = me._find_int_in(seg, ""lhs":") local rhs = me._find_int_in(seg, ""rhs":") if dst != null and lhs != null and rhs != null { local a = me._get(regs, "" + lhs) local b = me._get(regs, "" + rhs) me._set(regs, "" + dst, me._bin(kind, a, b)) } } else { if opname == "ret" { local v = me._find_int_in(seg, ""value":") if v == null { v = 0 } local out = me._get(regs, "" + v) print(me._int_to_str(out)) return 0 } } } cur = next_pos } print("0") return 0 } }