**Stage-B Parser Improvements:**
- Add NEWLINE skipping before/after LOCAL keyword (variables.rs)
- Add NEWLINE skipping after '{' in block statements (mod.rs)
- Add safety valve for statement keywords in static_box.rs
**Test File Fixes:**
- Fix collect_empty_args_smoke.hako: static box → box (allow instantiation)
- Fix method calls: index_of_from() → me.index_of_from() (explicit receiver)
**Context:**
These changes support the PHI UseBeforeDef bug investigation and improve
Stage-B parser robustness for NEWLINE handling in method bodies.
**Test Results:**
✅ collect_prints() loop break handling verified
✅ ArrayBox.length() working correctly (after user fix)
✅ All existing loop smoke tests passing (loop_min_while, nested_loop_inner_break, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
2.1 KiB
Plaintext
66 lines
2.1 KiB
Plaintext
// Self-contained dev smoke for FunctionCall empty-args
|
|
// Goal: echo() -> empty line, itoa() -> 0
|
|
|
|
box MiniVm {
|
|
// simple substring find from position
|
|
index_of_from(hay, needle, pos) {
|
|
if pos < 0 { pos = 0 }
|
|
if pos >= hay.length() { return -1 }
|
|
local tail = hay.substring(pos, hay.length())
|
|
local rel = tail.indexOf(needle)
|
|
if rel < 0 { return -1 } else { return pos + rel }
|
|
}
|
|
|
|
// collect only FunctionCall with empty arguments [] for echo/itoa
|
|
collect_prints(json) {
|
|
local out = new ArrayBox()
|
|
local pos = 0
|
|
local guard = 0
|
|
loop (true) {
|
|
guard = guard + 1
|
|
if guard > 16 { break }
|
|
local k_fc = "\"kind\":\"FunctionCall\""
|
|
local p = me.index_of_from(json, k_fc, pos)
|
|
if p < 0 { break }
|
|
// name
|
|
local k_n = "\"name\":\""
|
|
local np = me.index_of_from(json, k_n, p)
|
|
if np < 0 { break }
|
|
local ni = np + k_n.length()
|
|
local nj = me.index_of_from(json, "\"", ni)
|
|
if nj < 0 { break }
|
|
local fname = json.substring(ni, nj)
|
|
// args [] detection
|
|
local k_a = "\"arguments\":["
|
|
local ap = me.index_of_from(json, k_a, nj)
|
|
if ap < 0 { break }
|
|
local rb = me.index_of_from(json, "]", ap)
|
|
if rb < 0 { break }
|
|
// no content between '[' and ']'
|
|
if rb == ap + k_a.length() {
|
|
if fname == "echo" { out.push("") }
|
|
if fname == "itoa" { out.push("0") }
|
|
}
|
|
pos = rb + 1
|
|
}
|
|
return out
|
|
}
|
|
}
|
|
|
|
static box Main {
|
|
main(args) {
|
|
local json = "{\"kind\":\"Program\",\"statements\":[{\"kind\":\"Print\",\"expression\":{\"kind\":\"FunctionCall\",\"name\":\"echo\",\"arguments\":[]}},{\"kind\":\"Print\",\"expression\":{\"kind\":\"FunctionCall\",\"name\":\"itoa\",\"arguments\":[]}}]}"
|
|
|
|
local arr = new MiniVm().collect_prints(json)
|
|
print("✅ collect_prints() test PASSED:")
|
|
print(" Array length: " + arr.length())
|
|
print(" Element[0]: '" + arr.get(0) + "'")
|
|
print(" Element[1]: '" + arr.get(1) + "'")
|
|
print("Expected: echo() -> empty, itoa() -> 0")
|
|
local i = 0
|
|
loop (i < arr.length()) { print(arr.get(i)) i = i + 1 }
|
|
return 0
|
|
}
|
|
}
|
|
// migrated from .nyash to .hako (branding)
|