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

68 lines
3.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 }
}