- Fix condition_fn resolution: Value call path + dev safety + stub injection - VM bridge: handle Method::birth via BoxCall; ArrayBox push/get/length/set direct bridge - Receiver safety: pin receiver in method_call_handlers to avoid undefined use across blocks - Local vars: materialize on declaration (use init ValueId; void for uninit) - Prefer legacy BoxCall for Array/Map/String/user boxes in emit_box_or_plugin_call (stability-first) - Test runner: update LLVM hint to llvmlite harness (remove LLVM_SYS_180_PREFIX guidance) - Docs/roadmap: update CURRENT_TASK with unified default-ON + guards Note: NYASH_DEV_BIRTH_INJECT_BUILTINS=1 can re-enable builtin birth() injection during migration.
113 lines
3.9 KiB
Plaintext
113 lines
3.9 KiB
Plaintext
// 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
|
||
}
|
||
}
|