net-plugin: modularize constants (consts.rs) and sockets (sockets.rs); remove legacy commented socket code; fix unused imports mir: move instruction unit tests to tests/mir_instruction_unit.rs (file lean-up); no semantic changes runner/pyvm: ensure using pre-strip; misc docs updates Build: cargo build ok; legacy cfg warnings remain as before
310 lines
12 KiB
Plaintext
310 lines
12 KiB
Plaintext
// Mini-VM: function-based entry using library
|
||
|
||
using selfhost.vm.json_cur as MiniJsonCur
|
||
using selfhost.vm.json as MiniJson
|
||
using selfhost.vm.core as MiniVm
|
||
// Local static box (duplicated from mini_vm_lib for now to avoid include gate issues)
|
||
// Program entry: prefer argv[0] JSON, fallback to embedded sample
|
||
static box Main {
|
||
// Small helpers for quick JSON scans (avoid cross-box deps)
|
||
index_of_from(hay, needle, pos) {
|
||
local tail = hay.substring(pos, hay.length())
|
||
local rel = tail.indexOf(needle)
|
||
if rel < 0 { return -1 } else { return pos + rel }
|
||
}
|
||
_is_digit(ch) {
|
||
if ch == "0" { return 1 }
|
||
if ch == "1" { return 1 }
|
||
if ch == "2" { return 1 }
|
||
if ch == "3" { return 1 }
|
||
if ch == "4" { return 1 }
|
||
if ch == "5" { return 1 }
|
||
if ch == "6" { return 1 }
|
||
if ch == "7" { return 1 }
|
||
if ch == "8" { return 1 }
|
||
if ch == "9" { return 1 }
|
||
return 0
|
||
}
|
||
_digit_value(ch) {
|
||
if ch == "0" { return 0 }
|
||
if ch == "1" { return 1 }
|
||
if ch == "2" { return 2 }
|
||
if ch == "3" { return 3 }
|
||
if ch == "4" { return 4 }
|
||
if ch == "5" { return 5 }
|
||
if ch == "6" { return 6 }
|
||
if ch == "7" { return 7 }
|
||
if ch == "8" { return 8 }
|
||
if ch == "9" { return 9 }
|
||
return 0
|
||
}
|
||
_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
|
||
}
|
||
main(args) {
|
||
local json = "{\"kind\":\"Program\",\"statements\":[{\"kind\":\"Print\",\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":42}}}]}"
|
||
// If args provided, use the first as JSON source (guard None)
|
||
if args {
|
||
if args.size() > 0 {
|
||
local s = args.get(0)
|
||
if s { json = s }
|
||
}
|
||
}
|
||
// Top-level fast paths for simple Print cases (Literal/FunctionCall/Compare/BinaryOp)
|
||
// 0) If(literal int) then/else branch (string prints)
|
||
if json.indexOf("\"If\"") >= 0 {
|
||
local kc = "\"condition\""
|
||
local pc = json.indexOf(kc)
|
||
if pc >= 0 {
|
||
local kv = "\"type\":\"int\",\"value\":"
|
||
local pv = json.indexOf(kv, pc)
|
||
if pv >= 0 {
|
||
local vi = pv + kv.length()
|
||
local ve = json.indexOf("}", vi)
|
||
if ve >= 0 {
|
||
local cond_str = json.substring(vi, ve)
|
||
// parse int
|
||
local a = 0
|
||
local i = 0
|
||
loop (i < cond_str.length()) {
|
||
local ch = cond_str.substring(i, i+1)
|
||
if ch == "0" { a = a*10 i = i + 1 continue }
|
||
if ch == "1" { a = a*10+1 i = i + 1 continue }
|
||
if ch == "2" { a = a*10+2 i = i + 1 continue }
|
||
if ch == "3" { a = a*10+3 i = i + 1 continue }
|
||
if ch == "4" { a = a*10+4 i = i + 1 continue }
|
||
if ch == "5" { a = a*10+5 i = i + 1 continue }
|
||
if ch == "6" { a = a*10+6 i = i + 1 continue }
|
||
if ch == "7" { a = a*10+7 i = i + 1 continue }
|
||
if ch == "8" { a = a*10+8 i = i + 1 continue }
|
||
if ch == "9" { a = a*10+9 i = i + 1 continue }
|
||
break
|
||
}
|
||
local truthy = 0
|
||
if a != 0 { truthy = 1 }
|
||
local bkey = "\"then_body\""
|
||
if truthy == 0 { bkey = "\"else_body\"" }
|
||
local pb = json.indexOf(bkey, ve)
|
||
if pb >= 0 {
|
||
// search first string literal value inside the chosen body
|
||
local ts = "\"type\":\"string\",\"value\":\""
|
||
local ps = json.indexOf(ts, pb)
|
||
if ps >= 0 {
|
||
local si = ps + ts.length()
|
||
local sj = json.indexOf("\"", si)
|
||
if sj >= 0 { print(json.substring(si, sj)) return 0 }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 1) Print(Literal string)
|
||
if json.indexOf("\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"string\"") >= 0 {
|
||
local ks = "\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"string\",\"value\":\""
|
||
local ps = json.indexOf(ks)
|
||
if ps >= 0 {
|
||
local si = ps + ks.length()
|
||
local sj = json.indexOf("\"", si)
|
||
if sj >= 0 { print(json.substring(si, sj)) return 0 }
|
||
}
|
||
}
|
||
// 2) Print(Literal int)
|
||
if json.indexOf("\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\"") >= 0 {
|
||
local ki = "\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
|
||
local pi = json.indexOf(ki)
|
||
if pi >= 0 {
|
||
local ii = pi + ki.length()
|
||
// take until next non-digit or closing brace
|
||
local ie = json.indexOf("}", ii)
|
||
if ie < 0 { ie = ii }
|
||
local d = json.substring(ii, ie)
|
||
print(d)
|
||
return 0
|
||
}
|
||
}
|
||
// 3) Print(FunctionCall) minimal (echo/itoa)
|
||
if json.indexOf("\"FunctionCall\"") >= 0 {
|
||
local pos = 0
|
||
loop (true) {
|
||
local kfc = "\"kind\":\"FunctionCall\""
|
||
local fcp = json.indexOf(kfc, pos)
|
||
if fcp < 0 { break }
|
||
local kn = "\"name\":\""
|
||
local pn = json.indexOf(kn, fcp)
|
||
if pn < 0 { break }
|
||
local ni = pn + kn.length()
|
||
local nj = json.indexOf("\"", ni)
|
||
if nj < 0 { break }
|
||
local fname = json.substring(ni, nj)
|
||
local ka = "\"arguments\":["
|
||
local pa = json.indexOf(ka, nj)
|
||
if pa < 0 { pos = nj + 1 continue }
|
||
// string arg
|
||
local ts = "\"type\":\"string\",\"value\":\""
|
||
local ti = json.indexOf(ts, pa)
|
||
if ti >= 0 {
|
||
local si = ti + ts.length()
|
||
local sj = json.indexOf("\"", si)
|
||
if sj >= 0 {
|
||
local sval = json.substring(si, sj)
|
||
if fname == "echo" { print(sval) }
|
||
pos = sj + 1
|
||
continue
|
||
}
|
||
}
|
||
// int arg
|
||
local ti2 = json.indexOf("\"type\":\"int\",\"value\":", pa)
|
||
if ti2 >= 0 {
|
||
local vi = ti2 + "\"type\":\"int\",\"value\":".length()
|
||
local ve = json.indexOf("}", vi)
|
||
if ve < 0 { ve = vi }
|
||
local ival = json.substring(vi, ve)
|
||
if fname == "itoa" || fname == "echo" { print(ival) }
|
||
pos = ve + 1
|
||
continue
|
||
}
|
||
pos = pn + 1
|
||
}
|
||
return 0
|
||
}
|
||
// 4) Print(Compare) minimal
|
||
if json.indexOf("\"Compare\"") >= 0 {
|
||
local ko = "\"operation\":\""
|
||
local po = json.indexOf(ko)
|
||
if po >= 0 {
|
||
local oi = po + ko.length()
|
||
local oj = json.indexOf("\"", oi)
|
||
if oj >= 0 {
|
||
local op = json.substring(oi, oj)
|
||
local kv = "\"value\":\""
|
||
// lhs int
|
||
local kl = "\"lhs\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
|
||
local pl = json.indexOf(kl, oj)
|
||
if pl >= 0 {
|
||
local li = pl + kl.length()
|
||
local le = json.indexOf("}", li)
|
||
if le >= 0 {
|
||
local la = json.substring(li, le)
|
||
// rhs int
|
||
local kr = "\"rhs\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":"
|
||
local pr = json.indexOf(kr, le)
|
||
if pr >= 0 {
|
||
local ri = pr + kr.length()
|
||
local re = json.indexOf("}", ri)
|
||
if re >= 0 {
|
||
local rb = json.substring(ri, re)
|
||
// compute
|
||
local a = 0
|
||
local i = 0
|
||
loop (i < la.length()) { local ch = la.substring(i, i+1) if ch == "0" { a = a*10+0 i=i+1 continue } if ch == "1" { a=a*10+1 i=i+1 continue } if ch == "2" { a=a*10+2 i=i+1 continue } if ch == "3" { a=a*10+3 i=i+1 continue } if ch == "4" { a=a*10+4 i=i+1 continue } if ch == "5" { a=a*10+5 i=i+1 continue } if ch == "6" { a=a*10+6 i=i+1 continue } if ch == "7" { a=a*10+7 i=i+1 continue } if ch == "8" { a=a*10+8 i=i+1 continue } if ch == "9" { a=a*10+9 i=i+1 continue } break }
|
||
local b = 0
|
||
local j = 0
|
||
loop (j < rb.length()) { local ch2 = rb.substring(j, j+1) if ch2 == "0" { b = b*10+0 j=j+1 continue } if ch2 == "1" { b=b*10+1 j=j+1 continue } if ch2 == "2" { b=b*10+2 j=j+1 continue } if ch2 == "3" { b=b*10+3 j=j+1 continue } if ch2 == "4" { b=b*10+4 j=j+1 continue } if ch2 == "5" { b=b*10+5 j=j+1 continue } if ch2 == "6" { b=b*10+6 j=j+1 continue } if ch2 == "7" { b=b*10+7 j=j+1 continue } if ch2 == "8" { b=b*10+8 j=j+1 continue } if ch2 == "9" { b=b*10+9 j=j+1 continue } break }
|
||
local res = 0
|
||
if op == "<" { if a < b { res = 1 } }
|
||
if op == "==" { if a == b { res = 1 } }
|
||
if op == "<=" { if a <= b { res = 1 } }
|
||
if op == ">" { if a > b { res = 1 } }
|
||
if op == ">=" { if a >= b { res = 1 } }
|
||
if op == "!=" { if a != b { res = 1 } }
|
||
print(res)
|
||
return 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 5) BinaryOp(int+int) typed pattern twice and add(保険)
|
||
if json.indexOf("\"BinaryOp\"") >= 0 && json.indexOf("\"operator\":\"+\"") >= 0 {
|
||
local pat = "\"type\":\"int\",\"value\":"
|
||
local p1 = json.indexOf(pat)
|
||
if p1 >= 0 {
|
||
// parse first integer by taking until next closing brace
|
||
local i = p1 + pat.length()
|
||
local end1 = json.indexOf("}", i)
|
||
if end1 < 0 { end1 = i }
|
||
local a_str = json.substring(i, end1)
|
||
// convert a_str to int
|
||
local a = 0
|
||
local k = 0
|
||
loop (k < a_str.length()) {
|
||
local ch = a_str.substring(k, k+1)
|
||
if ch == "0" { a = a * 10 + 0 k = k + 1 continue }
|
||
if ch == "1" { a = a * 10 + 1 k = k + 1 continue }
|
||
if ch == "2" { a = a * 10 + 2 k = k + 1 continue }
|
||
if ch == "3" { a = a * 10 + 3 k = k + 1 continue }
|
||
if ch == "4" { a = a * 10 + 4 k = k + 1 continue }
|
||
if ch == "5" { a = a * 10 + 5 k = k + 1 continue }
|
||
if ch == "6" { a = a * 10 + 6 k = k + 1 continue }
|
||
if ch == "7" { a = a * 10 + 7 k = k + 1 continue }
|
||
if ch == "8" { a = a * 10 + 8 k = k + 1 continue }
|
||
if ch == "9" { a = a * 10 + 9 k = k + 1 continue }
|
||
break
|
||
}
|
||
// parse second integer
|
||
local p2 = json.lastIndexOf(pat)
|
||
if p2 >= 0 && p2 != p1 {
|
||
local j = p2 + pat.length()
|
||
local end2 = json.indexOf("}", j)
|
||
if end2 < 0 { end2 = j }
|
||
local b_str = json.substring(j, end2)
|
||
local b = 0
|
||
local m = 0
|
||
loop (m < b_str.length()) {
|
||
local ch2 = b_str.substring(m, m+1)
|
||
if ch2 == "0" { b = b * 10 + 0 m = m + 1 continue }
|
||
if ch2 == "1" { b = b * 10 + 1 m = m + 1 continue }
|
||
if ch2 == "2" { b = b * 10 + 2 m = m + 1 continue }
|
||
if ch2 == "3" { b = b * 10 + 3 m = m + 1 continue }
|
||
if ch2 == "4" { b = b * 10 + 4 m = m + 1 continue }
|
||
if ch2 == "5" { b = b * 10 + 5 m = m + 1 continue }
|
||
if ch2 == "6" { b = b * 10 + 6 m = m + 1 continue }
|
||
if ch2 == "7" { b = b * 10 + 7 m = m + 1 continue }
|
||
if ch2 == "8" { b = b * 10 + 8 m = m + 1 continue }
|
||
if ch2 == "9" { b = b * 10 + 9 m = m + 1 continue }
|
||
break
|
||
}
|
||
print(a + b)
|
||
return 0
|
||
}
|
||
}
|
||
}
|
||
// Fallback to full MiniVm runner
|
||
local vm = new MiniVm()
|
||
return vm.run(json)
|
||
}
|
||
}
|
||
|
||
// Top-level fallback entry for current runner
|
||
function main(args) {
|
||
local json = "{\"kind\":\"Program\",\"statements\":[{\"kind\":\"Print\",\"expression\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":42}}}]}"
|
||
if args {
|
||
if args.size() > 0 {
|
||
local s = args.get(0)
|
||
if s { json = s }
|
||
}
|
||
}
|
||
local vm = new MiniVm()
|
||
return vm.run(json)
|
||
}
|