Files
hakorune/lang/src/vm/boxes/step_runner.hako

68 lines
3.2 KiB
Plaintext
Raw Normal View History

// step_runner.hako — MiniVM 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 }
}