diff --git a/lang/src/compiler/parser/parser_box.hako b/lang/src/compiler/parser/parser_box.hako index 3637869b..d27cb3e0 100644 --- a/lang/src/compiler/parser/parser_box.hako +++ b/lang/src/compiler/parser/parser_box.hako @@ -351,17 +351,20 @@ box ParserBox { } loop(cont_prog == 1) { - // ✅ TRACE: main_prog loop progress (Task先生推奨トレースポイント) - local _loop_info = "" - if trace == 1 && (guard_prog < 5 || (guard_prog % 10) == 0) { - _loop_info = "[parse_program2:main] count=" + ("" + guard_prog) + - " i=" + ("" + i) + " n=" + ("" + n) - if i < n { - local _end = i + 40 - if _end > n { _end = n } - _loop_info = _loop_info + " ctx=\"" + src.substring(i, _end) + "\"" + // ===== 1) WS SKIP (inline, simple structure) ===== + loop(i < n) { + local ch_ws = src.substring(i, i + 1) + if ch_ws == " " || ch_ws == "\n" || ch_ws == "\r" || ch_ws == "\t" { + i = i + 1 + continue } - print(_loop_info) + break + } + + // ===== 2) EOF/GUARD CHECK (early exit) ===== + if i >= n { + cont_prog = 0 + break } if max_prog > 0 { @@ -371,117 +374,78 @@ box ParserBox { print("[parser/program2:guard] max iteration reached at pos=" + ("" + i)) } cont_prog = 0 + break } } - // Fail-fast: EOF まで進んでいれば即座にループを抜ける(無限走行防止)。 - if i >= n { - cont_prog = 0 - break + + // ===== 3) PARSE_STMT2 + GPOS_GET (unconditional execution) ===== + local start_i = i + local s = me.parse_stmt2(src, i) + i = me.gpos_get() + + // ===== 4) PROGRESS GUARD (ensure i always advances) ===== + if i <= start_i { + if trace == 1 { + print("[parser/trace:program2] progress-guard bump i from " + ("" + start_i) + " to " + ("" + (start_i + 1))) + } + i = start_i + 1 + if i > n { i = n } + me.gpos_set(i) } + + // ===== 5) TRACE (simplified, at end) ===== if trace == 1 { - local kind = "Stmt" - if i >= n { - kind = "EOF" + print("[parser/trace:program2] i=" + ("" + i) + " stmt_len=" + ("" + s.length()) + " guard=" + ("" + guard_prog)) + } + + // ===== 6) CONSUME OPTIONAL SEMICOLONS ===== + local done_semi = 0 + local guard_semi = 0 + local max_semi = 100000 + + loop(done_semi == 0) { + if guard_semi > max_semi { + done_semi = 1 } else { - if me.starts_with(src, i, "static box") == 1 { kind = "StaticBox" } - else { - if me.starts_with(src, i, "box ") == 1 { kind = "BoxDecl" } - else { - if me.starts_with(src, i, "method ") == 1 { kind = "Method" } - } - } - } - print("[parser/trace:program2] pos=" + ("" + i) + " kind=" + kind + " stage3=" + ("" + me.stage3)) - // Dev-only: small preview of remaining source to debug top-level progress - { - local head = "" - if i < n { - local end = i + 40 - if end > n { end = n } - head = src.substring(i, end) - } - print("[parser/trace:program2] head=\"" + head + "\"") - } - } - // Inline skip_ws instead of calling me.skip_ws(src, i) - if i < n { - local ws_cont_1 = 1 - loop(ws_cont_1 == 1) { - if i < n { - local ch1 = src.substring(i, i + 1) - if ch1 == " " || ch1 == "\n" || ch1 == "\r" || ch1 == "\t" { i = i + 1 } - else { ws_cont_1 = 0 } - } else { ws_cont_1 = 0 } - } - } - - if i >= src.length() { - cont_prog = 0 - } else { - local start_i = i - if trace == 1 { - print("[parser/trace:program2] before_stmt i=" + ("" + i)) - } - local s = me.parse_stmt2(src, i) - i = me.gpos_get() - if trace == 1 { - print("[parser/trace:program2] after_stmt i=" + ("" + i) + " stmt_len=" + ("" + s.length())) + guard_semi = guard_semi + 1 } - // Progress guard - if i <= start_i { - if trace == 1 { - print("[parser/trace:program2] progress-guard bump i from " + ("" + start_i) + " to " + ("" + (start_i + 1))) - } - if i < src.length() { i = i + 1 } - else { i = src.length() } - me.gpos_set(i) - } + local before_semi = i - // consume optional semicolons - local done2 = 0 - local guard2 = 0 - local max2 = 100000 - - loop(done2 == 0) { - if guard2 > max2 { done2 = 1 } - else { guard2 = guard2 + 1 } - - local before2 = i - // Inline skip_ws instead of calling me.skip_ws(src, i) - if i < n { - local ws_cont_2 = 1 - loop(ws_cont_2 == 1) { - if i < n { - local ch2 = src.substring(i, i + 1) - if ch2 == " " || ch2 == "\n" || ch2 == "\r" || ch2 == "\t" { i = i + 1 } - else { ws_cont_2 = 0 } - } else { ws_cont_2 = 0 } - } - } - - if i < src.length() && src.substring(i, i+1) == ";" { + // Inline ws skip + loop(i < n) { + local ch_semi = src.substring(i, i + 1) + if ch_semi == " " || ch_semi == "\n" || ch_semi == "\r" || ch_semi == "\t" { i = i + 1 - } else { - done2 = 1 + continue } - - if i == before2 { done2 = 1 } + break } - if s.length() > 0 { - if first == 1 { - if trace == 1 { - print("[parser/trace:program2] emit-first stmt_len=" + ("" + s.length())) - } - body = body + s - first = 0 - } else { - if trace == 1 { - print("[parser/trace:program2] emit stmt_len=" + ("" + s.length())) - } - body = body + "," + s + if i < n && src.substring(i, i+1) == ";" { + i = i + 1 + } else { + done_semi = 1 + } + + if i == before_semi { + done_semi = 1 + } + } + + // ===== 7) EMIT STATEMENT ===== + if s.length() > 0 { + if first == 1 { + if trace == 1 { + print("[parser/trace:program2] emit-first stmt_len=" + ("" + s.length())) } + body = body + s + first = 0 + } else { + if trace == 1 { + print("[parser/trace:program2] emit stmt_len=" + ("" + s.length())) + } + body = body + "," + s } } } diff --git a/lang/src/shared/common/string_helpers.hako b/lang/src/shared/common/string_helpers.hako index 29b3ce9a..7137618a 100644 --- a/lang/src/shared/common/string_helpers.hako +++ b/lang/src/shared/common/string_helpers.hako @@ -172,14 +172,13 @@ static box StringHelpers { local s = "" + src local n = s.length() local j = i - local cont = 1 - local guard = 0 - local max = 100000 - loop(cont == 1) { - if guard > max { return j } else { guard = guard + 1 } - if j < n { - if me.is_space(s.substring(j, j+1)) { j = j + 1 } else { cont = 0 } - } else { cont = 0 } + // Simplified loop structure for MirBuilder compatibility + loop(j < n) { + if me.is_space(s.substring(j, j+1)) { + j = j + 1 + continue + } + break } return j } diff --git a/src/runner/modes/vm.rs b/src/runner/modes/vm.rs index 203d0a58..25229839 100644 --- a/src/runner/modes/vm.rs +++ b/src/runner/modes/vm.rs @@ -431,6 +431,15 @@ impl NyashRunner { } // Optional: dump MIR for diagnostics + // Phase 25.1: File dump for offline analysis (ParserBox等) + if let Ok(path) = std::env::var("RUST_MIR_DUMP_PATH") { + if let Ok(mut f) = std::fs::File::create(&path) { + let p = crate::mir::MirPrinter::new(); + let _ = std::io::Write::write_all(&mut f, p.print_module(&module_vm).as_bytes()); + eprintln!("[vm] MIR dumped to: {}", path); + } + } + // Existing: NYASH_VM_DUMP_MIR dumps to stderr if crate::config::env::env_bool("NYASH_VM_DUMP_MIR") { let p = crate::mir::MirPrinter::new(); eprintln!("{}", p.print_module(&module_vm)); diff --git a/src/runner/modes/vm_fallback.rs b/src/runner/modes/vm_fallback.rs index 527be1dd..c933c82c 100644 --- a/src/runner/modes/vm_fallback.rs +++ b/src/runner/modes/vm_fallback.rs @@ -294,6 +294,15 @@ impl NyashRunner { } // Optional: dump MIR for diagnostics (parity with vm path) + // Phase 25.1: File dump for offline analysis (ParserBox等) + if let Ok(path) = std::env::var("RUST_MIR_DUMP_PATH") { + if let Ok(mut f) = std::fs::File::create(&path) { + let p = crate::mir::MirPrinter::new(); + let _ = std::io::Write::write_all(&mut f, p.print_module(&module_vm).as_bytes()); + eprintln!("[vm-fallback] MIR dumped to: {}", path); + } + } + // Existing: NYASH_VM_DUMP_MIR dumps to stderr if crate::config::env::env_bool("NYASH_VM_DUMP_MIR") { let p = crate::mir::MirPrinter::new(); eprintln!("{}", p.print_module(&module_vm));