132 lines
3.4 KiB
Plaintext
132 lines
3.4 KiB
Plaintext
|
|
// mini_collections.hako — Minimal collection boxes for selfhost VM tests
|
|||
|
|
|
|||
|
|
// Simple string-backed dynamic array of i64 (for smoke/testing)
|
|||
|
|
box MiniArray {
|
|||
|
|
field data: String
|
|||
|
|
birth() { me.data = "" return 0 }
|
|||
|
|
push(v) {
|
|||
|
|
v = "" + v
|
|||
|
|
if me.data == "" { me.data = v } else { me.data = me.data + "," + v }
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
length() {
|
|||
|
|
if me.data == "" { return 0 }
|
|||
|
|
// count commas + 1
|
|||
|
|
local s = me.data
|
|||
|
|
local i = 0
|
|||
|
|
local c = 1
|
|||
|
|
loop(true) {
|
|||
|
|
local j = s.indexOf(",", i)
|
|||
|
|
if j < 0 { break }
|
|||
|
|
c = c + 1
|
|||
|
|
i = j + 1
|
|||
|
|
}
|
|||
|
|
return c
|
|||
|
|
}
|
|||
|
|
// Fail‑Fast accessor: returns element string; prints error and returns 0 on OOB
|
|||
|
|
at(index) {
|
|||
|
|
// normalize and validate index
|
|||
|
|
local si = "" + index
|
|||
|
|
local idx = 0
|
|||
|
|
if si != "" {
|
|||
|
|
local i = 0
|
|||
|
|
loop(i < si.size()) { idx = idx * 10 + ("0123456789".indexOf(si.substring(i,i+1))) i = i + 1 }
|
|||
|
|
}
|
|||
|
|
local n = me.length()
|
|||
|
|
if idx < 0 || idx >= n { print("[ERROR] MiniArray.at: index out of range: " + (""+idx) + "/" + (""+n)) return 0 }
|
|||
|
|
// find start position of idx-th element
|
|||
|
|
local s = me.data
|
|||
|
|
local pos = 0
|
|||
|
|
local cur = 0
|
|||
|
|
loop(cur < idx) {
|
|||
|
|
local j = s.indexOf(",", pos)
|
|||
|
|
if j < 0 { print("[ERROR] MiniArray.at: broken storage") return 0 }
|
|||
|
|
pos = j + 1
|
|||
|
|
cur = cur + 1
|
|||
|
|
}
|
|||
|
|
local endp = s.indexOf(",", pos)
|
|||
|
|
if endp < 0 { endp = s.size() }
|
|||
|
|
return s.substring(pos, endp)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Simple string-backed map (key->value as 'k=v\n')
|
|||
|
|
box MiniMap2 {
|
|||
|
|
field store: String
|
|||
|
|
birth() { me.store = "" return 0 }
|
|||
|
|
set(key, value) {
|
|||
|
|
key = "" + key
|
|||
|
|
value = "" + value
|
|||
|
|
// Guard for unsupported characters in key that break line format
|
|||
|
|
if key.indexOf("\n") >= 0 || key.indexOf("=") >= 0 {
|
|||
|
|
print("[ERROR] MiniMap2.set: invalid key contains newline or '='")
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
// remove and append
|
|||
|
|
local out = ""
|
|||
|
|
local s = me.store
|
|||
|
|
local pos = 0
|
|||
|
|
loop(true) {
|
|||
|
|
local nl = s.indexOf("\n", pos)
|
|||
|
|
if nl < 0 { break }
|
|||
|
|
local line = s.substring(pos, nl)
|
|||
|
|
local eq = line.indexOf("=")
|
|||
|
|
if eq >= 0 {
|
|||
|
|
local k = line.substring(0, eq)
|
|||
|
|
if k != key { out = out + line + "\n" }
|
|||
|
|
}
|
|||
|
|
pos = nl + 1
|
|||
|
|
}
|
|||
|
|
me.store = out + key + "=" + value + "\n"
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
get(key) {
|
|||
|
|
key = "" + key
|
|||
|
|
local s = me.store
|
|||
|
|
local pos = 0
|
|||
|
|
loop(true) {
|
|||
|
|
local nl = s.indexOf("\n", pos)
|
|||
|
|
if nl < 0 { break }
|
|||
|
|
local line = s.substring(pos, nl)
|
|||
|
|
local eq = line.indexOf("=")
|
|||
|
|
if eq >= 0 {
|
|||
|
|
local k = line.substring(0, eq)
|
|||
|
|
if k == key { return line.substring(eq + 1, line.size()) }
|
|||
|
|
}
|
|||
|
|
pos = nl + 1
|
|||
|
|
}
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
// Strict getter: Fail‑Fast when key is missing; returns 0 on failure
|
|||
|
|
get_or_fail(key) {
|
|||
|
|
key = "" + key
|
|||
|
|
local v = me.get(key)
|
|||
|
|
if v == null { print("[ERROR] MiniMap2.get: key not found: " + key) return 0 }
|
|||
|
|
return v
|
|||
|
|
}
|
|||
|
|
has(key) {
|
|||
|
|
key = "" + key
|
|||
|
|
local s = me.store
|
|||
|
|
if s == "" { return 0 }
|
|||
|
|
// naive contains of 'key=' at line start or after \n
|
|||
|
|
local needle = key + "="
|
|||
|
|
if s.substring(0, needle.size()) == needle { return 1 }
|
|||
|
|
local p = s.indexOf("\n" + needle)
|
|||
|
|
if p >= 0 { return 1 }
|
|||
|
|
return 0
|
|||
|
|
}
|
|||
|
|
size() {
|
|||
|
|
if me.store == "" { return 0 }
|
|||
|
|
local s = me.store
|
|||
|
|
local i = 0
|
|||
|
|
local c = 0
|
|||
|
|
loop(true) {
|
|||
|
|
local nl = s.indexOf("\n", i)
|
|||
|
|
if nl < 0 { break }
|
|||
|
|
c = c + 1
|
|||
|
|
i = nl + 1
|
|||
|
|
}
|
|||
|
|
return c
|
|||
|
|
}
|
|||
|
|
}
|