debug(stageb): センチネル追加でVMバグ特定 - using経由static box内loop不実行
## 🔍 調査結果 ### ✅ 確認事項 - **本物の実装が呼ばれている**: SENTINEL出力で確認済み - 🔥 SENTINEL_SKIP_WS_CALLED!!! - 🎯 SENTINEL_KW_BOUNDARY_BEFORE_CALLED!!! - 🎯 SENTINEL_KW_BOUNDARY_AFTER_CALLED!!! - 🔤 SENTINEL_IS_IDENT_CHAR_CALLED!!! ### 🐛 重大バグ発見 **症状**: `FuncScannerBox.skip_whitespace` 内の `loop(1 == 1)` が実行されない **証拠**: ``` [skip_ws] START idx=10 s.length()=173 [skip_ws] i=10 n=173 [skip_ws] RETURN i=10 ← ループボディが実行されず即座にreturn ``` - `[skip_ws] LOOP-TOP i=10` が**一度も出力されない** - loop(1 == 1) の無限ループすら実行されない **影響範囲**: - box_name抽出失敗(空文字列) - defs生成失敗(defs_len=0) - canary テスト失敗 **問題の本質**: - using 経由で読み込まれたモジュールの static box 内 - 静的メソッド呼び出し (`FuncScannerBox.skip_whitespace(...)`) - loop 構文が VM/MIR レベルで実行されない ## 🔧 修正内容 1. **センチネル追加**: 4箇所に明確な出力追加 - skip_whitespace, kw_boundary_before, kw_boundary_after, is_ident_char 2. **呼び出し修正**: `me.scan_all_boxes` → `StageBFuncScannerBox.scan_all_boxes` ## 📊 次のステップ VM/MIR レイヤーでの loop 構文実装確認が必要 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -1214,7 +1214,7 @@ static box StageBDriverBox {
|
|||||||
tracer.log("StageBDriverBox.main:func_scan src_head=" + head)
|
tracer.log("StageBDriverBox.main:func_scan src_head=" + head)
|
||||||
}
|
}
|
||||||
|
|
||||||
local methods = me.scan_all_boxes(src)
|
local methods = StageBFuncScannerBox.scan_all_boxes(src)
|
||||||
|
|
||||||
{
|
{
|
||||||
local cnt = 0
|
local cnt = 0
|
||||||
|
|||||||
@ -83,13 +83,18 @@ static box FuncScannerBox {
|
|||||||
} else {
|
} else {
|
||||||
if i + 3 <= n && s.substring(i, i + 3) == "box" && FuncScannerBox.kw_boundary_before(s, i) == 1 && FuncScannerBox.kw_boundary_after(s, i + 3) == 1 {
|
if i + 3 <= n && s.substring(i, i + 3) == "box" && FuncScannerBox.kw_boundary_before(s, i) == 1 && FuncScannerBox.kw_boundary_after(s, i + 3) == 1 {
|
||||||
local cursor = i + 3
|
local cursor = i + 3
|
||||||
|
print("[DEBUG] box keyword found at i=" + ("" + i))
|
||||||
cursor = FuncScannerBox.skip_whitespace(s, cursor)
|
cursor = FuncScannerBox.skip_whitespace(s, cursor)
|
||||||
|
print("[DEBUG] after skip_whitespace: cursor=" + ("" + cursor))
|
||||||
local name_start = cursor
|
local name_start = cursor
|
||||||
loop(cursor < n) {
|
loop(cursor < n) {
|
||||||
local ch_name = s.substring(cursor, cursor + 1)
|
local ch_name = s.substring(cursor, cursor + 1)
|
||||||
|
print("[DEBUG] cursor=" + ("" + cursor) + " ch_name='" + ch_name + "' is_ident=" + ("" + FuncScannerBox.is_ident_char(ch_name)))
|
||||||
if FuncScannerBox.is_ident_char(ch_name) == 1 { cursor = cursor + 1 } else { break }
|
if FuncScannerBox.is_ident_char(ch_name) == 1 { cursor = cursor + 1 } else { break }
|
||||||
}
|
}
|
||||||
|
print("[DEBUG] name_start=" + ("" + name_start) + " cursor=" + ("" + cursor) + " n=" + ("" + n))
|
||||||
local box_name = s.substring(name_start, cursor)
|
local box_name = s.substring(name_start, cursor)
|
||||||
|
print("[DEBUG] box_name='" + box_name + "' len=" + ("" + box_name.length()))
|
||||||
if box_name == "" {
|
if box_name == "" {
|
||||||
next_i = cursor
|
next_i = cursor
|
||||||
} else {
|
} else {
|
||||||
@ -302,18 +307,28 @@ static box FuncScannerBox {
|
|||||||
// Helper: 空白文字(space/tab/newline/CR)を idx 位置からスキップ
|
// Helper: 空白文字(space/tab/newline/CR)を idx 位置からスキップ
|
||||||
// 戻り値: スキップ後の位置(空白でない文字の位置、または文字列末尾)
|
// 戻り値: スキップ後の位置(空白でない文字の位置、または文字列末尾)
|
||||||
method skip_whitespace(s, idx) {
|
method skip_whitespace(s, idx) {
|
||||||
|
print("🔥🔥🔥 SENTINEL_SKIP_WS_CALLED!!! 🔥🔥🔥")
|
||||||
|
print("[skip_ws] START idx=" + ("" + idx) + " s.length()=" + ("" + s.length()))
|
||||||
local i = idx
|
local i = idx
|
||||||
local n = s.length()
|
local n = s.length()
|
||||||
loop(i < n) {
|
print("[skip_ws] i=" + ("" + i) + " n=" + ("" + n))
|
||||||
|
// WORKAROUND: Changed from loop(i < n) to loop with internal if check
|
||||||
|
// Original: loop(i < n) { ... } was not executing body even when condition was true!
|
||||||
|
loop(1 == 1) {
|
||||||
|
print("[skip_ws] LOOP-TOP i=" + ("" + i))
|
||||||
|
if i >= n { break }
|
||||||
local ch = s.substring(i, i + 1)
|
local ch = s.substring(i, i + 1)
|
||||||
|
print("[skip_ws] LOOP i=" + ("" + i) + " ch='" + ch + "'")
|
||||||
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" { i = i + 1 } else { break }
|
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" { i = i + 1 } else { break }
|
||||||
}
|
}
|
||||||
|
print("[skip_ws] RETURN i=" + ("" + i))
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper: キーワード前の境界チェック("box" などが識別子の一部でないことを確認)
|
// Helper: キーワード前の境界チェック("box" などが識別子の一部でないことを確認)
|
||||||
// 戻り値: 1=境界OK(キーワードとして有効), 0=境界NG(識別子の一部)
|
// 戻り値: 1=境界OK(キーワードとして有効), 0=境界NG(識別子の一部)
|
||||||
method kw_boundary_before(s, idx) {
|
method kw_boundary_before(s, idx) {
|
||||||
|
print("🎯 SENTINEL_KW_BOUNDARY_BEFORE_CALLED!!!")
|
||||||
if idx <= 0 { return 1 }
|
if idx <= 0 { return 1 }
|
||||||
local ch = s.substring(idx - 1, idx)
|
local ch = s.substring(idx - 1, idx)
|
||||||
if FuncScannerBox.is_ident_char(ch) == 1 { return 0 }
|
if FuncScannerBox.is_ident_char(ch) == 1 { return 0 }
|
||||||
@ -323,6 +338,7 @@ static box FuncScannerBox {
|
|||||||
// Helper: キーワード後の境界チェック("box" などが識別子の一部でないことを確認)
|
// Helper: キーワード後の境界チェック("box" などが識別子の一部でないことを確認)
|
||||||
// 戻り値: 1=境界OK(キーワードとして有効), 0=境界NG(識別子の一部)
|
// 戻り値: 1=境界OK(キーワードとして有効), 0=境界NG(識別子の一部)
|
||||||
method kw_boundary_after(s, idx) {
|
method kw_boundary_after(s, idx) {
|
||||||
|
print("🎯 SENTINEL_KW_BOUNDARY_AFTER_CALLED!!!")
|
||||||
if idx >= s.length() { return 1 }
|
if idx >= s.length() { return 1 }
|
||||||
local ch = s.substring(idx, idx + 1)
|
local ch = s.substring(idx, idx + 1)
|
||||||
if FuncScannerBox.is_ident_char(ch) == 1 { return 0 }
|
if FuncScannerBox.is_ident_char(ch) == 1 { return 0 }
|
||||||
@ -332,6 +348,7 @@ static box FuncScannerBox {
|
|||||||
// Helper: 識別子として有効な文字かチェック(0-9, A-Z, a-z, _)
|
// Helper: 識別子として有効な文字かチェック(0-9, A-Z, a-z, _)
|
||||||
// 戻り値: 1=識別子文字, 0=非識別子文字
|
// 戻り値: 1=識別子文字, 0=非識別子文字
|
||||||
method is_ident_char(ch) {
|
method is_ident_char(ch) {
|
||||||
|
print("🔤 SENTINEL_IS_IDENT_CHAR_CALLED!!!")
|
||||||
if ch == null || ch == "" { return 0 }
|
if ch == null || ch == "" { return 0 }
|
||||||
if ch >= "0" && ch <= "9" { return 1 }
|
if ch >= "0" && ch <= "9" { return 1 }
|
||||||
if ch >= "A" && ch <= "Z" { return 1 }
|
if ch >= "A" && ch <= "Z" { return 1 }
|
||||||
|
|||||||
Reference in New Issue
Block a user