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