Files
hakorune/apps/examples/json_query_min/main.nyash
nyash-codex 3aa0c3c875 fix(stage-b): Add sh_core using + Stage-1 JSON support
## Fixed Issues

1. compiler_stageb.hako: Added 'using sh_core as StringHelpers'
   - Resolved: call unresolved ParserStringUtilsBox.skip_ws/2
   - Root cause: using chain resolution not implemented
   - Workaround: explicit using in parent file

2. stageb_helpers.sh: Accept Stage-1 JSON format
   - Modified awk pattern to accept both formats:
     - MIR JSON v0: "version":0, "kind":"Program"
     - Stage-1 JSON: "type":"Program"

## Remaining Issues

ParserBox VM crash: Invalid value: use of undefined value ValueId(5839)
- Cause: Complex nested loops in parse_program2()
- Workaround: Minimal Stage-B (without ParserBox) works
- Fallback: Rust compiler path available

## Verification

 Minimal Stage-B outputs JSON correctly
 ParserBox execution crashes VM (SSA bug)

Co-Authored-By: Task先生 (AI Agent)
2025-11-02 08:23:43 +09:00

93 lines
3.5 KiB
Plaintext

// Minimal, single-method evaluator to avoid parser seam issues.
static box Main {
main() {
local j = "{\"a\":{\"b\":[1,2,3]}}"
local path = ".a.b[1]"
local out = this.eval_path_text(j, path)
if out == null { print("null") } else { print(out) }
return 0
}
// Minimal evaluator for the demo path shape: .a.b[<int>]
eval_path_text(json_text, path) {
// Find key "a"
local k1 = json_text.indexOf("\"a\"")
if k1 < 0 { return null }
// find ':' after k1
local c1 = k1
loop(c1 < json_text.length() and json_text.substring(c1, c1+1) != ":") { c1 = c1 + 1 }
if c1 >= json_text.length() { return null }
if c1 < 0 { return null }
// Find key "b" after a's value colon
// find '"b"' after c1
local k2 = c1
loop(k2 + 2 < json_text.length()) {
if json_text.substring(k2, k2+1) == "\"" and json_text.substring(k2+1, k2+2) == "b" and json_text.substring(k2+2, k2+3) == "\"" { break }
k2 = k2 + 1
}
if k2 >= json_text.length() { return null }
if k2 < 0 { return null }
// find ':' after k2
local c2 = k2
loop(c2 < json_text.length() and json_text.substring(c2, c2+1) != ":") { c2 = c2 + 1 }
if c2 >= json_text.length() { return null }
if c2 < 0 { return null }
// Find '[' starting the array
// find '[' after c2
local arr = c2
loop(arr < json_text.length() and json_text.substring(arr, arr+1) != "[") { arr = arr + 1 }
if arr >= json_text.length() { return null }
if arr < 0 { return null }
// Parse index from path
local p_lb = path.indexOf("[")
if p_lb < 0 { return null }
// find ']' after p_lb
local p_rb = p_lb
loop(p_rb < path.length() and path.substring(p_rb, p_rb+1) != "]") { p_rb = p_rb + 1 }
if p_rb < 0 { return null }
local idx_text = path.substring(p_lb + 1, p_rb)
// parse integer
local k = 0
local idx = 0
loop(k < idx_text.length()) {
local ch = idx_text.substring(k, k + 1)
if ch == "0" { idx = idx * 10 + 0 }
else { if ch == "1" { idx = idx * 10 + 1 }
else { if ch == "2" { idx = idx * 10 + 2 }
else { if ch == "3" { idx = idx * 10 + 3 }
else { if ch == "4" { idx = idx * 10 + 4 }
else { if ch == "5" { idx = idx * 10 + 5 }
else { if ch == "6" { idx = idx * 10 + 6 }
else { if ch == "7" { idx = idx * 10 + 7 }
else { if ch == "8" { idx = idx * 10 + 8 }
else { if ch == "9" { idx = idx * 10 + 9 } }}}}}}}}
k = k + 1
}
// Iterate array to the idx-th element (numbers only in this demo)
local pos = arr + 1
local cur = 0
loop(pos < json_text.length()) {
// skip whitespace
loop(pos < json_text.length() and (json_text.substring(pos, pos+1) == " " or json_text.substring(pos, pos+1) == "\n" or json_text.substring(pos, pos+1) == "\t" or json_text.substring(pos, pos+1) == "\r")) { pos = pos + 1 }
if json_text.substring(pos, pos+1) == "]" { return null }
// read token
local start = pos
loop(pos < json_text.length()) {
local c = json_text.substring(pos, pos+1)
if c == "," or c == "]" or c == " " or c == "\n" or c == "\t" or c == "\r" { break }
pos = pos + 1
}
if cur == idx { return json_text.substring(start, pos) }
// advance to next
loop(pos < json_text.length() and json_text.substring(pos, pos+1) != "," and json_text.substring(pos, pos+1) != "]") { pos = pos + 1 }
if pos < json_text.length() and json_text.substring(pos, pos+1) == "," { pos = pos + 1 cur = cur + 1 continue }
return null
}
return null
}
}
}