// Mini-VM: function-based entry using library // Minimal JSON cursor helpers (developer preview) // Note: naive and partial; sufficient for Mini-VM MVP patterns. static box MiniJsonCur { _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 } // Skip whitespace from pos; return first non-ws index or -1 next_non_ws(s, pos) { local i = pos local n = s.length() loop (i < n) { local ch = s.substring(i, i+1) if ch != " " && ch != "\n" && ch != "\r" && ch != "\t" { return i } i = i + 1 } return -1 } // Read a quoted string starting at pos '"'; returns decoded string (no state) read_quoted_from(s, pos) { local i = pos if s.substring(i, i+1) != "\"" { return "" } i = i + 1 local out = "" local n = s.length() loop (i < n) { local ch = s.substring(i, i+1) if ch == "\"" { break } if ch == "\\" { i = i + 1 ch = s.substring(i, i+1) } out = out + ch i = i + 1 } return out } // Read consecutive digits from pos read_digits_from(s, pos) { local out = "" local i = pos // guard against invalid position (null/negative) if i == null { return out } if i < 0 { return out } loop (true) { local ch = s.substring(i, i+1) if ch == "" { break } // inline digit check to avoid same-box method dispatch if ch == "0" { out = out + ch i = i + 1 continue } if ch == "1" { out = out + ch i = i + 1 continue } if ch == "2" { out = out + ch i = i + 1 continue } if ch == "3" { out = out + ch i = i + 1 continue } if ch == "4" { out = out + ch i = i + 1 continue } if ch == "5" { out = out + ch i = i + 1 continue } if ch == "6" { out = out + ch i = i + 1 continue } if ch == "7" { out = out + ch i = i + 1 continue } if ch == "8" { out = out + ch i = i + 1 continue } if ch == "9" { out = out + ch i = i + 1 continue } break } return out } } // Adapter for JSON cursor operations. In Stage‑B we centralize calls here // so we can later delegate to libs (`apps/libs/json_cur.nyash`) without // touching call sites. For now it wraps the local MiniJsonCur. static box MiniJson { read_quoted_from(s, pos) { local cur = new MiniJsonCur() return cur.read_quoted_from(s, pos) } read_digits_from(s, pos) { local cur = new MiniJsonCur() return cur.read_digits_from(s, pos) } next_non_ws(s, pos) { local cur = new MiniJsonCur() return cur.next_non_ws(s, pos) } } // Local static box (duplicated from mini_vm_lib for now to avoid include gate issues) static box MiniVm { _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 // use MiniJson adapter inline local n = s.length() local acc = 0 loop (i < n) { local ch = s.substring(i, i+1) // inline digit decode to avoid same-box method dispatch 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 } _digit_char(d) { if d == 0 { return "0" } if d == 1 { return "1" } if d == 2 { return "2" } if d == 3 { return "3" } if d == 4 { return "4" } if d == 5 { return "5" } if d == 6 { return "6" } if d == 7 { return "7" } if d == 8 { return "8" } if d == 9 { return "9" } return "0" } _int_to_str(n) { if n == 0 { return "0" } local v = n local out = "" loop (v > 0) { local d = v % 10 local ch = _digit_char(d) out = ch + out v = v / 10 } return out } read_digits(json, pos) { local out = "" loop (true) { local s = json.substring(pos, pos+1) if s == "" { break } // inline digit check to avoid same-box method dispatch if s == "0" { out = out + s pos = pos + 1 continue } if s == "1" { out = out + s pos = pos + 1 continue } if s == "2" { out = out + s pos = pos + 1 continue } if s == "3" { out = out + s pos = pos + 1 continue } if s == "4" { out = out + s pos = pos + 1 continue } if s == "5" { out = out + s pos = pos + 1 continue } if s == "6" { out = out + s pos = pos + 1 continue } if s == "7" { out = out + s pos = pos + 1 continue } if s == "8" { out = out + s pos = pos + 1 continue } if s == "9" { out = out + s pos = pos + 1 continue } break } return out } // Read a JSON string starting at position pos (at opening quote); returns the decoded string read_json_string(json, pos) { // Expect opening quote local i = pos local out = "" local n = json.length() if json.substring(i, i+1) == "\"" { i = i + 1 } else { return "" } loop (i < n) { local ch = json.substring(i, i+1) if ch == "\"" { i = i + 1 break } if ch == "\\" { // handle simple escapes for \ and " local nx = json.substring(i+1, i+2) if nx == "\"" { out = out + "\"" i = i + 2 continue } if nx == "\\" { out = out + "\\" i = i + 2 continue } // Unknown escape: skip backslash and take next as-is i = i + 1 continue } out = out + ch i = i + 1 } return out } // helper: find needle from position pos 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 } } // helper: next non-whitespace character index from pos next_non_ws(json, pos) { local i = pos local n = json.length() loop (i < n) { local ch = json.substring(i, i+1) if ch != " " && ch != "\n" && ch != "\r" && ch != "\t" { return i } i = i + 1 } return -1 } // ——— Helpers (as box methods) ——— try_print_string_value_at(json, end, print_pos) { local k_val = "\"value\":\"" local s = index_of_from(json, k_val, print_pos) if s < 0 || s >= end { return -1 } local i = s + k_val.length() local j = index_of_from(json, "\"", i) if j <= 0 || j > end { return -1 } print(json.substring(i, j)) return j + 1 } try_print_int_value_at(json, end, print_pos) { // Bind to this Print's expression object and require kind==Literal local k_expr = "\"expression\":{" local epos = index_of_from(json, k_expr, print_pos) if epos <= 0 || epos >= end { return -1 } local obj_start = index_of_from(json, "{", epos) if obj_start <= 0 || obj_start >= end { return -1 } local obj_end = find_balanced_object_end(json, obj_start) if obj_end <= 0 || obj_end > end { return -1 } local k_kind = "\"kind\":\"Literal\"" local kpos = index_of_from(json, k_kind, obj_start) if kpos <= 0 || kpos >= obj_end { return -1 } local k_type = "\"type\":\"" local tpos = index_of_from(json, k_type, kpos) if tpos <= 0 || tpos >= obj_end { return -1 } tpos = tpos + k_type.length() local t_end = index_of_from(json, "\"", tpos) if t_end <= 0 || t_end > obj_end { return -1 } local ty = json.substring(tpos, t_end) if (ty != "int" && ty != "i64" && ty != "integer") { return -1 } local k_val2 = "\"value\":" local v2 = index_of_from(json, k_val2, t_end) if v2 <= 0 || v2 >= obj_end { return -1 } local digits = read_digits(json, v2 + k_val2.length()) if digits == "" { return -1 } print(digits) return obj_end + 1 } try_print_functioncall_at(json, end, print_pos) { local k_fc = "\"kind\":\"FunctionCall\"" local fcp = index_of_from(json, k_fc, print_pos) if fcp <= 0 || fcp >= end { return -1 } // name local k_name = "\"name\":\"" local npos = index_of_from(json, k_name, fcp) if npos <= 0 || npos >= end { return -1 } local ni = npos + k_name.length() local nj = index_of_from(json, "\"", ni) if nj <= 0 || nj > end { return -1 } local fname = json.substring(ni, nj) // args local k_args = "\"arguments\":[" local apos = index_of_from(json, k_args, nj) if apos <= 0 || apos >= end { return -1 } local arr_start = index_of_from(json, "[", apos) local arr_end = find_balanced_array_end(json, arr_start) if arr_start <= 0 || arr_end <= 0 || arr_end > end { return -1 } // handle empty args [] local nn = next_non_ws(json, arr_start+1) if nn > 0 && nn <= arr_end { if json.substring(nn, nn+1) == "]" { if fname == "echo" { print("") return arr_end + 1 } if fname == "itoa" { print("0") return arr_end + 1 } return -1 } } // first arg type local k_t = "\"type\":\"" local atpos = index_of_from(json, k_t, arr_start) if atpos <= 0 || atpos >= arr_end { if fname == "echo" { print("") return arr_end + 1 } if fname == "itoa" { print("0") return arr_end + 1 } return -1 } atpos = atpos + k_t.length() local at_end = index_of_from(json, "\"", atpos) if at_end <= 0 || at_end > arr_end { return -1 } local aty = json.substring(atpos, at_end) if aty == "string" { local k_sval = "\"value\":\"" local svalp = index_of_from(json, k_sval, at_end) if svalp <= 0 || svalp >= arr_end { return -1 } local si = svalp + k_sval.length() local sj = index_of_from(json, "\"", si) if sj <= 0 || sj > arr_end { return -1 } local sval = json.substring(si, sj) if fname == "echo" { print(sval) return sj + 1 } return -1 } if aty == "int" || aty == "i64" || aty == "integer" { local k_ival = "\"value\":" local ivalp = index_of_from(json, k_ival, at_end) if ivalp <= 0 || ivalp >= arr_end { return -1 } local digits = read_digits(json, ivalp + k_ival.length()) if fname == "itoa" || fname == "echo" { print(digits) return ivalp + k_ival.length() } return -1 } return -1 } // Minimal: Print(BinaryOp) with operator "+"; supports string+string and int+int try_print_binop_at(json, end, print_pos) { local k_bo = "\"kind\":\"BinaryOp\"" local bpos = index_of_from(json, k_bo, print_pos) if bpos <= 0 || bpos >= end { return -1 } // bound this BinaryOp object by matching braces // Prefer the enclosing expression object: "expression":{ ... BinaryOp ... } local k_expr = "\"expression\":{" local expr_pos = index_of_from(json, k_expr, print_pos) local obj_start = -1 if expr_pos > 0 && expr_pos < end { obj_start = index_of_from(json, "{", expr_pos) } else { // fallback to the next '{' after kind, may be left-object; acceptable but less robust obj_start = index_of_from(json, "{", bpos) } local obj_end = find_balanced_object_end(json, obj_start) if obj_start <= 0 || obj_end <= 0 || obj_end > end { return -1 } // operator local k_op = "\"operator\":\"+\"" local opos = index_of_from(json, k_op, bpos) if opos <= 0 || opos >= obj_end { return -1 } // string + string パターン(カーソル+単純キー走査) local cur = new MiniJsonCur() local k_left_lit = "\"left\":{\"kind\":\"Literal\"" local lhdr = index_of_from(json, k_left_lit, opos) if lhdr > 0 && lhdr < obj_end { // find left value string local k_sval = "\"value\":\"" local lvp = index_of_from(json, k_sval, lhdr) if lvp > 0 && lvp < obj_end { local li = lvp + k_sval.length() local lval = cur.read_quoted_from(json, li) if lval { // find right literal header then value local k_right_lit = "\"right\":{\"kind\":\"Literal\"" local rhdr = index_of_from(json, k_right_lit, li + lval.length()) if rhdr > 0 && rhdr < obj_end { local rvp = index_of_from(json, k_sval, rhdr) if rvp > 0 && rvp < obj_end { local ri = rvp + k_sval.length() local rval = cur.read_quoted_from(json, ri) if rval { print(lval + rval) return ri + rval.length() + 1 } } } } } } // int + int パターン(MiniJson を用いて value 数字を抽出) // left literal value local k_l = "\"left\":{\"kind\":\"Literal\"" local lpos = index_of_from(json, k_l, opos) if lpos <= 0 || lpos >= obj_end { return -1 } // typed fast-path within object bounds local k_lint = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local li2 = index_of_from(json, k_lint, opos) if li2 <= 0 || li2 >= obj_end { return -1 } local ldigits = read_digits(json, li2 + k_lint.length()) if ldigits == "" { return -1 } // right literal value local k_r = "\"right\":{\"kind\":\"Literal\"" local rpos = index_of_from(json, k_r, lpos) if rpos <= 0 || rpos >= obj_end { return -1 } local k_rint = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local ri2 = index_of_from(json, k_rint, lpos) if ri2 <= 0 || ri2 >= obj_end { return -1 } local rdigits = read_digits(json, ri2 + k_rint.length()) if rdigits == "" { return -1 } // sum local ai = _str_to_int(ldigits) local bi = _str_to_int(rdigits) print(_int_to_str(ai + bi)) return obj_end + 1 // fallback: scan two numeric values inside BinaryOp object local k_v2 = "\"value\":" local p1 = index_of_from(json, k_v2, obj_start) if p1 > 0 && p1 < obj_end { local cur2 = new MiniJsonCur() local d1 = cur2.read_digits_from(json, p1 + k_v2.length()) if d1 { local p2 = index_of_from(json, k_v2, p1 + k_v2.length()) if p2 > 0 && p2 < obj_end { local d2 = cur2.read_digits_from(json, p2 + k_v2.length()) if d2 { print(_int_to_str(_str_to_int(d1) + _str_to_int(d2))) return obj_end + 1 } } } } } // Greedy fallback: detect BinaryOp int+int by pattern regardless of field order nuances try_print_binop_int_greedy(json, end, print_pos) { // disabled for now (was causing false positives) return -1 } // Fallback: within the current Print's expression BinaryOp object, scan for two numeric values and sum try_print_binop_sum_any(json, end, print_pos) { // Bind expression object { ... } local k_expr = "\"expression\":{" local expr_pos = index_of_from(json, k_expr, print_pos) if expr_pos <= 0 || expr_pos >= end { return -1 } local obj_start = index_of_from(json, "{", expr_pos) if obj_start <= 0 || obj_start >= end { return -1 } local obj_end = find_balanced_object_end(json, obj_start) if obj_end <= 0 || obj_end > end { return -1 } // Must be BinaryOp '+' inside this expression local k_bo = "\"kind\":\"BinaryOp\"" local bpos = index_of_from(json, k_bo, obj_start) if bpos <= 0 || bpos >= obj_end { return -1 } local k_plus = "\"operator\":\"+\"" local opos = index_of_from(json, k_plus, bpos) if opos <= 0 || opos >= obj_end { return -1 } // Within [obj_start, obj_end], collect all integer literals and sum the last two local nums = [] local i = obj_start loop (i < obj_end) { // skip strings if json.substring(i, i+1) == "\"" { local j = index_of_from(json, "\"", i+1) if j < 0 || j >= obj_end { break } i = j + 1 continue } // digits local d = read_digits(json, i) if d { nums.push(d) i = i + d.length() continue } i = i + 1 } local nsz = nums.size() if nsz < 2 { return -1 } local a = _str_to_int(nums.get(nsz-2)) local b = _str_to_int(nums.get(nsz-1)) print(_int_to_str(a + b)) return obj_end + 1 } // Deterministic: within the first Print.expression BinaryOp('+'), // find exactly two numeric values from successive '"value":' fields and sum. // Stops after collecting two ints; bounded strictly by the expression object. try_print_binop_sum_expr_values(json, end, print_pos) { // Bind expression object { ... } local k_expr = "\"expression\":{" local expr_pos = index_of_from(json, k_expr, print_pos) if expr_pos <= 0 || expr_pos >= end { return -1 } local obj_start = index_of_from(json, "{", expr_pos) if obj_start <= 0 || obj_start >= end { return -1 } local obj_end = find_balanced_object_end(json, obj_start) if obj_end <= 0 || obj_end > end { return -1 } // Ensure BinaryOp '+' local k_bo = "\"kind\":\"BinaryOp\"" local bpos = index_of_from(json, k_bo, obj_start) if bpos <= 0 || bpos >= obj_end { return -1 } local k_plus = "\"operator\":\"+\"" local opos = index_of_from(json, k_plus, bpos) if opos <= 0 || opos >= obj_end { return -1 } // Collect two integer values exactly from successive 'value' fields within bounds local cur = new MiniJsonCur() local k_v = "\"value\":" local found = 0 local a = 0 local pos = index_of_from(json, k_v, obj_start) loop (pos > 0 && pos < obj_end) { // attempt to read digits right after '"value":' local di = cur.read_digits_from(json, pos + k_v.length()) if di != "" { if found == 0 { a = _str_to_int(di) found = 1 } else { local b = _str_to_int(di) print(_int_to_str(a + b)) return obj_end + 1 } } // advance to next 'value' key within object bounds pos = index_of_from(json, k_v, pos + k_v.length()) if pos <= 0 || pos >= obj_end { break } } return -1 } // Simpler deterministic fallback: after the first BinaryOp '+', // scan forward for two successive 'value' fields and sum their integer digits. // This avoids brace matching and remains bounded by two finds. try_print_binop_sum_after_bop(json) { local k_bo = "\"kind\":\"BinaryOp\"" local bpos = json.indexOf(k_bo) if bpos < 0 { return -1 } local k_plus = "\"operator\":\"+\"" local opos = index_of_from(json, k_plus, bpos) if opos < 0 { return -1 } local k_v = "\"value\":" // We know the structure around operator '+': // left: { ... value: { type:int, value: } }, right: { ... value: { type:int, value: } } // So the 2nd 'value' after operator is , and the 4th is . local p = opos local i = 0 // 1st value key (object) p = index_of_from(json, k_v, p) if p < 0 { return -1 } i = i + 1 // 2nd value key (digits for left) p = index_of_from(json, k_v, p + k_v.length()) if p < 0 { return -1 } i = i + 1 local end1 = index_of_from(json, "}", p) if end1 < 0 { return -1 } local d1 = json.substring(p + k_v.length(), end1) // 3rd value key (object in right) p = index_of_from(json, k_v, p + k_v.length()) if p < 0 { return -1 } i = i + 1 // 4th value key (digits for right) p = index_of_from(json, k_v, p + k_v.length()) if p < 0 { return -1 } i = i + 1 local end2 = index_of_from(json, "}", p) if end2 < 0 { return -1 } local d2 = json.substring(p + k_v.length(), end2) // Print as integer to avoid relying on string concatenation print(_str_to_int(d1) + _str_to_int(d2)) return end2 + 1 } // Direct typed BinaryOp(int+int) matcher using explicit left/right literal paths try_print_binop_typed_direct(json) { local k_left = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local k_right = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local lp = json.indexOf(k_left) if lp < 0 { return -1 } local ld = read_digits(json, lp + k_left.length()) if ld == "" { return -1 } local rp = index_of_from(json, k_right, lp + k_left.length()) if rp < 0 { return -1 } local rd = read_digits(json, rp + k_right.length()) if rd == "" { return -1 } print(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) return rp + k_right.length() } // Tokenized typed extractor: search left/right blocks then type/value pairs try_print_binop_typed_tokens(json) { local k_bo = "\"kind\":\"BinaryOp\"" local bpos = json.indexOf(k_bo) if bpos < 0 { return -1 } local lp = index_of_from(json, "\"left\":", bpos) if lp < 0 { return -1 } local kt = "\"type\":\"int\"" local kv = "\"value\":" local tp1 = index_of_from(json, kt, lp) if tp1 < 0 { return -1 } local vp1 = index_of_from(json, kv, tp1) if vp1 < 0 { return -1 } local ld = read_digits(json, vp1 + kv.length()) if ld == "" { return -1 } local rp = index_of_from(json, "\"right\":", lp) if rp < 0 { return -1 } local tp2 = index_of_from(json, kt, rp) if tp2 < 0 { return -1 } local vp2 = index_of_from(json, kv, tp2) if vp2 < 0 { return -1 } local rd = read_digits(json, vp2 + kv.length()) if rd == "" { return -1 } print(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) return rp } // Fast value-pair extractor: find left/right then first value digits after each try_print_binop_value_pairs(json) { local k_bo = "\"kind\":\"BinaryOp\"" local bpos = json.indexOf(k_bo) if bpos < 0 { return -1 } local kl = "\"left\":" local kv = "\"value\":" local lp = index_of_from(json, kl, bpos) if lp < 0 { return -1 } local v1 = index_of_from(json, kv, lp) if v1 < 0 { return -1 } local ld = read_digits(json, v1 + kv.length()) if ld == "" { return -1 } local rp = index_of_from(json, "\"right\":", lp) if rp < 0 { return -1 } local v2 = index_of_from(json, kv, rp) if v2 < 0 { return -1 } local rd = read_digits(json, v2 + kv.length()) if rd == "" { return -1 } print(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) return v2 + kv.length() } // Minimal: Print(Compare) for integers. Prints 1/0 for true/false. try_print_compare_at(json, end, print_pos) { local k_cp = "\"kind\":\"Compare\"" local cpos = index_of_from(json, k_cp, print_pos) if cpos <= 0 || cpos >= end { return -1 } local k_op = "\"operation\":\"" local opos = index_of_from(json, k_op, cpos) if opos <= 0 || opos >= end { // fallback key name k_op = "\"operator\":\"" opos = index_of_from(json, k_op, cpos) if opos <= 0 || opos >= end { return -1 } } local oi = opos + k_op.length() local oj = index_of_from(json, "\"", oi) if oj <= 0 || oj > end { return -1 } local op = json.substring(oi, oj) // Robust numeric lhs/rhs using cursor digits after value key local cur = new MiniJsonCur() // lhs local k_lhs = "\"lhs\":{\"kind\":\"Literal\"" local hl = index_of_from(json, k_lhs, oj) if hl <= 0 || hl >= end { return -1 } local k_v = "\"value\":" local hv = index_of_from(json, k_v, hl) if hv <= 0 || hv >= end { return -1 } local a = cur.read_digits_from(json, hv + k_v.length()) if a == "" { return -1 } // rhs local k_rhs = "\"rhs\":{\"kind\":\"Literal\"" local hr = index_of_from(json, k_rhs, hl) if hr <= 0 || hr >= end { return -1 } local rv = index_of_from(json, k_v, hr) if rv <= 0 || rv >= end { return -1 } local b = cur.read_digits_from(json, rv + k_v.length()) if b == "" { return -1 } // Strict compare for <, ==, <=, >, >=, != local ai = _str_to_int(a) local bi = _str_to_int(b) local res = 0 if op == "<" { if ai < bi { res = 1 } } if op == "==" { if ai == bi { res = 1 } } if op == "<=" { if ai <= bi { res = 1 } } if op == ">" { if ai > bi { res = 1 } } if op == ">=" { if ai >= bi { res = 1 } } if op == "!=" { if ai != bi { res = 1 } } print(res) return rv + k_v.length() } // Extract first Print literal from JSON v0 Program and return its string representation parse_first_print_literal(json) { // Find a Print statement local k_print = "\"kind\":\"Print\"" local p = json.indexOf(k_print) if p < 0 { return null } // Find value type in the expression following Print local k_type = "\"type\":\"" local tpos = json.indexOf(k_type) if tpos < 0 { return null } tpos = tpos + k_type.length() // Read type name until next quote local t_end = index_of_from(json, "\"", tpos) if t_end < 0 { return null } local ty = json.substring(tpos, t_end) // Find value field local k_val = "\"value\":" local vpos = index_of_from(json, k_val, t_end) if vpos < 0 { return null } vpos = vpos + k_val.length() if ty == "int" || ty == "i64" || ty == "integer" { // read digits directly local digits = read_digits(json, vpos) return digits } if ty == "string" { // Find opening and closing quotes (no escape handling in MVP) local i = index_of_from(json, "\"", vpos) if i < 0 { return null } local j = index_of_from(json, "\"", i+1) if j < 0 { return null } return json.substring(i+1, j) } // Other types not supported yet return null } // helper: find balanced bracket range [ ... ] starting at idx (points to '[') find_balanced_array_end(json, idx) { local n = json.length() if json.substring(idx, idx+1) != "[" { return -1 } local depth = 0 local i = idx loop (i < n) { local ch = json.substring(i, i+1) if ch == "[" { depth = depth + 1 } if ch == "]" { depth = depth - 1 if depth == 0 { return i } } i = i + 1 } return -1 } // helper: find balanced object range { ... } starting at idx (points to '{') find_balanced_object_end(json, idx) { local n = json.length() if json.substring(idx, idx+1) != "{" { return -1 } local depth = 0 local i = idx loop (i < n) { local ch = json.substring(i, i+1) if ch == "{" { depth = depth + 1 } if ch == "}" { depth = depth - 1 if depth == 0 { return i } } i = i + 1 } return -1 } // Print all Print-Literal values within [start,end] (inclusive slice indices) print_prints_in_slice(json, start, end) { // Main loop with simple guard to avoid pathological hangs local pos = start local printed = 0 local guard = 0 loop (true) { guard = guard + 1 if guard > 200 { break } local k_print = "\"kind\":\"Print\"" local p = index_of_from(json, k_print, pos) if p < 0 || p > end { break } // avoid global digit-sum shortcuts to keep scans bounded and robust // bound the current Print object to advance correctly local p_obj_start = index_of_from(json, "{", p) local p_obj_end = find_balanced_object_end(json, p_obj_start) if p_obj_start <= 0 || p_obj_end <= 0 { p_obj_end = p + k_print.length() } // Prefer structured expressions first (avoid matching inner literal fields) // 1) BinaryOp(sum_any → 厳密 → 貪欲intフォールバック) local nextp = try_print_binop_sum_any(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } nextp = try_print_binop_at(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } nextp = try_print_binop_int_greedy(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } nextp = try_print_binop_sum_any(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } // 2) Compare nextp = try_print_compare_at(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } // 3) FunctionCall minimal nextp = try_print_functioncall_at(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } // 4) literal string nextp = try_print_string_value_at(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } // 5) literal int via type nextp = try_print_int_value_at(json, end, p) if nextp > 0 { printed = printed + 1 pos = p_obj_end + 1 continue } // Skip if unknown shape pos = p + k_print.length() if pos <= p { pos = p + 1 } } return printed } // Process top-level If with literal condition; print branch prints. Returns printed count. process_if_once(json) { local k_if = "\"kind\":\"If\"" local p = index_of_from(json, k_if, 0) if p < 0 { return 0 } // condition value (assume int literal truthy) local k_cond = "\"condition\"" local cpos = index_of_from(json, k_cond, p) if cpos < 0 { return 0 } local k_val = "\"value\":" local vpos = index_of_from(json, k_val, cpos) if vpos < 0 { return 0 } local val_digits = read_digits(json, vpos + k_val.length()) local truthy = 0 if val_digits { if val_digits != "0" { truthy = 1 } } // choose branch key local k_then = "\"then_body\"" local k_else = "\"else_body\"" local bkey = k_then if truthy == 0 { bkey = k_else } local bpos = index_of_from(json, bkey, cpos) if bpos < 0 { return 0 } // find array start '[' then end local arr_start = index_of_from(json, "[", bpos) if arr_start < 0 { return 0 } local arr_end = find_balanced_array_end(json, arr_start) if arr_end < 0 { return 0 } return print_prints_in_slice(json, arr_start, arr_end) } // Print all Print-Literal values in Program.statements (string/int only; MVP) print_all_print_literals(json) { return print_prints_in_slice(json, 0, json.length()) } parse_first_int(json) { local key = "\"value\":{\"type\":\"int\",\"value\":" local idx = json.lastIndexOf(key) if idx < 0 { return "0" } local start = idx + key.length() return read_digits(json, start) } // Fallback: find first BinaryOp and return sum of two numeric values as string; empty if not found parse_first_binop_sum(json) { local k_bo = "\"kind\":\"BinaryOp\"" local bpos = json.indexOf(k_bo) if bpos < 0 { return "" } // typed pattern inside left/right.literal.value: {"type":"int","value":} local k_typed = "\"type\":\"int\",\"value\":" // first number local p1 = index_of_from(json, k_typed, bpos) if p1 < 0 { return "" } local d1 = read_digits(json, p1 + k_typed.length()) if d1 == "" { return "" } // second number local p2 = index_of_from(json, k_typed, p1 + k_typed.length()) if p2 < 0 { return "" } local d2 = read_digits(json, p2 + k_typed.length()) if d2 == "" { return "" } return _int_to_str(_str_to_int(d1) + _str_to_int(d2)) } // Linear pass: sum all numbers outside of quotes (fast, finite) sum_numbers_no_quotes(json) { local i = 0 local n = json.length() local total = 0 loop (i < n) { local ch = json.substring(i, i+1) if ch == "\"" { // skip to next quote local j = index_of_from(json, "\"", i+1) if j < 0 { break } i = j + 1 continue } // digits local d = read_digits(json, i) if d { total = total + _str_to_int(d) i = i + d.length() continue } i = i + 1 } return _int_to_str(total) } // Naive: sum all digit runs anywhere (for simple BinaryOp JSON) sum_all_digits_naive(json) { local i = 0 local n = json.length() local total = 0 loop (i < n) { local d = read_digits(json, i) if d { total = total + _str_to_int(d) i = i + d.length() continue } i = i + 1 } return _int_to_str(total) } // Sum first two integers outside quotes; returns string or empty if not found sum_first_two_numbers(json) { local i = 0 local n = json.length() local total = 0 local found = 0 loop (i < n) { local ch = json.substring(i, i+1) if ch == "\"" { // skip to next quote local j = index_of_from(json, "\"", i+1) if j < 0 { break } i = j + 1 continue } local d = read_digits(json, i) if d { total = total + _str_to_int(d) found = found + 1 i = i + d.length() if found >= 2 { return _int_to_str(total) } continue } i = i + 1 } return "" } // Sum two integers near a BinaryOp '+' token; bounded window to keep steps low sum_two_numbers_near_plus(json) { local k_plus = "\"operator\":\"+\"" local op = json.indexOf(k_plus) if op < 0 { return "" } local n = json.length() local start = op - 120 if start < 0 { start = 0 } local limit = op + 240 if limit > n { limit = n } local i = start local found = 0 local a = 0 loop (i < limit) { local ch = json.substring(i, i+1) if ch == "\"" { // skip to next quote within window local j = index_of_from(json, "\"", i+1) if j < 0 || j > limit { break } i = j + 1 continue } local d = read_digits(json, i) if d { if found == 0 { a = _str_to_int(d) found = 1 } else { local b = _str_to_int(d) return _int_to_str(a + b) } i = i + d.length() continue } i = i + 1 } return "" } // Fallback: sum all bare numbers (not inside quotes) in the JSON; return string or empty if none sum_all_numbers(json) { local cur = new MiniJsonCur() local i = 0 local n = json.length() local sum = 0 loop (i < n) { local ch = json.substring(i, i+1) if ch == "\"" { // skip quoted string local s = cur.read_quoted_from(json, i) i = i + s.length() + 2 continue } // try digits local d = cur.read_digits_from(json, i) if d != "" { sum = sum + _str_to_int(d) i = i + d.length() continue } i = i + 1 } if sum == 0 { return "" } return _int_to_str(sum) } // (reserved) helper for future robust binop scan run(json) { // Single-purpose fast path for smoke: if BinaryOp '+' exists, try expression-bounded extractor first. if json.indexOf("\"BinaryOp\"") >= 0 && json.indexOf("\"operator\":\"+\"") >= 0 { // Bind to first Print and extract value×2 within expression bounds local k_print = "\"kind\":\"Print\"" local p = index_of_from(json, k_print, 0) if p >= 0 { local np0 = try_print_binop_sum_expr_values(json, json.length(), p) if np0 > 0 { return 0 } } // Typed direct inside BinaryOp object (fast and finite) local k_bo = "\"kind\":\"BinaryOp\"" local bpos = json.indexOf(k_bo) if bpos >= 0 { local k_lint = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local li = index_of_from(json, k_lint, bpos) if li >= 0 { local ld = read_digits(json, li + k_lint.length()) if ld != "" { local k_rint = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local ri = index_of_from(json, k_rint, li + k_lint.length()) if ri >= 0 { local rd = read_digits(json, ri + k_rint.length()) if rd != "" { print(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) return 0 } } } } } // As a final bounded fallback under BinaryOp '+', sum first two numbers outside quotes { local s2 = sum_first_two_numbers(json) if s2 { print(s2) return 0 } } // (skip near-operator windowed scan to avoid high step counts under PyVM) } // Prefer If(literal) branch handling first local ifc = process_if_once(json) if ifc > 0 { return 0 } // Quick conservative path: if BinaryOp exists, sum bare numbers outside quotes // (limited to simple BinaryOp(int,int) JSON) if json.indexOf("\"BinaryOp\"") >= 0 { // Prefer expression-bounded scan first local k_print = "\"kind\":\"Print\"" local p = index_of_from(json, k_print, 0) if p >= 0 { // Deterministic: sum the first two numbers from successive 'value' fields local np0 = try_print_binop_sum_expr_values(json, json.length(), p) if np0 > 0 { return 0 } } // Brace-free deterministic fallback tied to the first BinaryOp { local np1 = try_print_binop_sum_after_bop(json) if np1 > 0 { return 0 } } // avoid global number-sum fallback to keep steps bounded } // 0) direct typed BinaryOp '+' fast-path (explicit left/right literal ints) local k_bo = "\"kind\":\"BinaryOp\"" local k_plus = "\"operator\":\"+\"" if json.indexOf(k_bo) >= 0 && json.indexOf(k_plus) >= 0 { local np = try_print_binop_typed_direct(json) if np > 0 { return 0 } np = try_print_binop_typed_tokens(json) if np > 0 { return 0 } np = try_print_binop_value_pairs(json) if np > 0 { return 0 } // (skip bounded-window fallback around '+') } // 0) quick path: BinaryOp(int+int) typed fast-path local k_bo = "\"kind\":\"BinaryOp\"" local bpos = json.indexOf(k_bo) if bpos >= 0 { // typed left/right ints inside BinaryOp local k_lint = "\"left\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local li = index_of_from(json, k_lint, bpos) if li >= 0 { local ld = read_digits(json, li + k_lint.length()) if ld != "" { local k_rint = "\"right\":{\"kind\":\"Literal\",\"value\":{\"type\":\"int\",\"value\":" local ri = index_of_from(json, k_rint, li + k_lint.length()) if ri >= 0 { local rd = read_digits(json, ri + k_rint.length()) if rd != "" { print(_int_to_str(_str_to_int(ld) + _str_to_int(rd))) return 0 } } } } // fallback: sum two numeric values within the first Print.expression BinaryOp object local k_print = "\"kind\":\"Print\"" local p = index_of_from(json, k_print, 0) if p >= 0 { local k_expr = "\"expression\":{" local epos = index_of_from(json, k_expr, p) if epos > 0 { local obj_start = index_of_from(json, "{", epos) local obj_end = find_balanced_object_end(json, obj_start) if obj_start > 0 && obj_end > 0 { local k_bo2 = "\"kind\":\"BinaryOp\"" local b2 = index_of_from(json, k_bo2, obj_start) if b2 > 0 && b2 < obj_end { local k_v = "\"value\":" local p1 = index_of_from(json, k_v, obj_start) local d1 = "" loop (p1 > 0 && p1 < obj_end) { d1 = new MiniJsonCur().read_digits_from(json, p1 + k_v.length()) if d1 != "" { break } p1 = index_of_from(json, k_v, p1 + k_v.length()) } if d1 != "" { local p2 = index_of_from(json, k_v, p1 + k_v.length()) local d2 = "" loop (p2 > 0 && p2 < obj_end) { d2 = new MiniJsonCur().read_digits_from(json, p2 + k_v.length()) if d2 != "" { break } p2 = index_of_from(json, k_v, p2 + k_v.length()) } if d2 != "" { local ai = _str_to_int(d1) local bi = _str_to_int(d2) print(_int_to_str(ai + bi)) return 0 } } } } } } // fallback: parse-first within BinaryOp scope by scanning two numeric values local ssum = parse_first_binop_sum(json) if ssum { print(ssum) return 0 } } // Attempt expression-local BinaryOp sum via existing helper on first Print { local k_print = "\"kind\":\"Print\"" local p = index_of_from(json, k_print, 0) if p >= 0 { local np = try_print_binop_sum_any(json, json.length(), p) if np > 0 { return 0 } } } // 0-c) quick path: Compare(lhs int, rhs int) local k_cp = "\"kind\":\"Compare\"" local cpos = json.indexOf(k_cp) if cpos >= 0 { // operation local k_op = "\"operation\":\"" local opos = index_of_from(json, k_op, cpos) if opos > 0 { local oi = opos + k_op.length() local oj = index_of_from(json, "\"", oi) if oj > 0 { local op = json.substring(oi, oj) // lhs value local k_lhs = "\"lhs\":{\"kind\":\"Literal\"" local hl = index_of_from(json, k_lhs, oj) if hl > 0 { local k_v = "\"value\":" local hv = index_of_from(json, k_v, hl) if hv > 0 { local a = read_digits(json, hv + k_v.length()) // rhs value local k_rhs = "\"rhs\":{\"kind\":\"Literal\"" local hr = index_of_from(json, k_rhs, hl) if hr > 0 { local rv = index_of_from(json, k_v, hr) if rv > 0 { local b = read_digits(json, rv + k_v.length()) if a && b { local ai = _str_to_int(a) local bi = _str_to_int(b) local res = 0 if op == "<" { if ai < bi { res = 1 } } if op == "==" { if ai == bi { res = 1 } } if op == "<=" { if ai <= bi { res = 1 } } if op == ">" { if ai > bi { res = 1 } } if op == ">=" { if ai >= bi { res = 1 } } if op == "!=" { if ai != bi { res = 1 } } print(res) return 0 } } } } } } } } // Scan global prints (flat programs) local pc = print_all_print_literals(json) // 2) as a robustness fallback, handle first BinaryOp sum within first Print.expression if pc == 0 { local k_print = "\"kind\":\"Print\"" local p = index_of_from(json, k_print, 0) if p >= 0 { local k_expr = "\"expression\":{" local epos = index_of_from(json, k_expr, p) if epos > 0 { local obj_start = index_of_from(json, "{", epos) local obj_end = find_balanced_object_end(json, obj_start) if obj_start > 0 && obj_end > 0 { local k_bo = "\"kind\":\"BinaryOp\"" local bpos = index_of_from(json, k_bo, obj_start) if bpos > 0 && bpos < obj_end { // sum two numeric values inside this expression object local cur = new MiniJsonCur() local k_v = "\"value\":" local p1 = index_of_from(json, k_v, obj_start) local d1 = "" loop (p1 > 0 && p1 < obj_end) { d1 = cur.read_digits_from(json, p1 + k_v.length()) if d1 != "" { break } p1 = index_of_from(json, k_v, p1 + k_v.length()) } if d1 != "" { local p2 = index_of_from(json, k_v, p1 + k_v.length()) local d2 = "" loop (p2 > 0 && p2 < obj_end) { d2 = cur.read_digits_from(json, p2 + k_v.length()) if d2 != "" { break } p2 = index_of_from(json, k_v, p2 + k_v.length()) } if d2 != "" { local ai = _str_to_int(d1) local bi = _str_to_int(d2) print(_int_to_str(ai + bi)) pc = 1 } } } } } } } if pc == 0 { // last resort: typed pattern-wide sum, then safe number sum outside quotes, else single int literal local s = parse_first_binop_sum(json) if s { print(s) } else { local ts = sum_numbers_no_quotes(json) if ts { print(ts) } else { local n = parse_first_int(json) print(n) } } } return 0 } } // 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) }