Files
hakorune/lang/src/compiler/entry/func_scanner.hako

540 lines
21 KiB
Plaintext
Raw Normal View History

// FuncScannerBox — Function definition scanner for Stage-B compiler
// Policy: Extract method definitions from Hako source (conservative, minimal)
// Toggle: HAKO_STAGEB_FUNC_SCAN=1
// Scope: method <name>(params) { ... } outside of main (same box Main)
// Output: [{"name":"<name>","params":[...],"body_json":"<Program JSON>","box":"Main"}]
2025-11-19 23:12:01 +09:00
using "lang.compiler.parser.box" as ParserBox
static box FuncScannerBox {
// Scan source for method definitions (excluding Main.main)
method scan_functions(source, box_name) {
return me.scan_methods(source, box_name, 1, 0)
}
// Scan all static box definitions and collect their methods.
method scan_all_boxes(source) {
// source が null の場合はスキャン対象がないので空配列を返すよ。
if source == null { return new ArrayBox() }
local defs = new ArrayBox()
local s = "" + source
local n = s.length()
local i = 0
// ────────────────────────────────────────────────────────────
// State flags: コメント/文字列スキップ状態管理4本
// ────────────────────────────────────────────────────────────
// in_str: 文字列リテラル内("..." の中)= 1, それ以外 = 0
// esc: 文字列内エスケープ直後(次の文字をスキップ)= 1, それ以外 = 0
// in_line: 行コメント内(// から改行まで)= 1, それ以外 = 0
// in_block: ブロックコメント内(/* から */ まで)= 1, それ以外 = 0
local in_str = 0
local esc = 0
local in_line = 0
local in_block = 0
// Region + next_i 形式に統一して、ループ本体での多重 continue による
// SSA/PHI の複雑さを下げる。
loop(i < n) {
local next_i = i + 1
local ch = s.substring(i, i + 1)
// ────────────────────────────────────────────────────────────
// State 1: 行コメントモード(// から改行まで)
// ────────────────────────────────────────────────────────────
if in_line == 1 {
if ch == "\n" { in_line = 0 } // 改行で行コメント終了
// ────────────────────────────────────────────────────────────
// State 2: ブロックコメントモード(/* から */ まで)
// ────────────────────────────────────────────────────────────
} else if in_block == 1 {
if ch == "*" && i + 1 < n && s.substring(i + 1, i + 2) == "/" {
in_block = 0 // */ でブロックコメント終了
next_i = i + 2
}
// ────────────────────────────────────────────────────────────
// State 3: 文字列リテラルモード("..." の中)
// ────────────────────────────────────────────────────────────
} else if in_str == 1 {
if esc == 1 {
esc = 0 // エスケープ直後文字処理完了
} else if ch == "\\" {
esc = 1 // バックスラッシュでエスケープ開始
} else if ch == "\"" {
in_str = 0 // 閉じクォートで文字列終了
}
// ────────────────────────────────────────────────────────────
// State 4: 通常モード(コメント/文字列の外)→ box キーワード検出
// ────────────────────────────────────────────────────────────
} else {
// 文字列リテラル開始(" 検出)
if ch == "\"" {
in_str = 1 // 文字列モードへ遷移
// コメント開始判定(/ の次の文字で行/ブロック判別)
} else if ch == "/" && i + 1 < n {
local ch2 = s.substring(i + 1, i + 2)
if ch2 == "/" {
in_line = 1 // 行コメントモードへ遷移(// 検出)
next_i = i + 2
} else if ch2 == "*" {
in_block = 1 // ブロックコメントモードへ遷移(/* 検出)
next_i = i + 2
}
// box キーワード検出(境界チェック付き)
} 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 {
local cursor = i + 3
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>
2025-11-20 08:03:05 +09:00
print("[DEBUG] box keyword found at i=" + ("" + i))
cursor = FuncScannerBox.skip_whitespace(s, cursor)
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>
2025-11-20 08:03:05 +09:00
print("[DEBUG] after skip_whitespace: cursor=" + ("" + cursor))
local name_start = cursor
loop(cursor < n) {
local ch_name = s.substring(cursor, cursor + 1)
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>
2025-11-20 08:03:05 +09:00
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 }
}
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>
2025-11-20 08:03:05 +09:00
print("[DEBUG] name_start=" + ("" + name_start) + " cursor=" + ("" + cursor) + " n=" + ("" + n))
local box_name = s.substring(name_start, cursor)
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>
2025-11-20 08:03:05 +09:00
print("[DEBUG] box_name='" + box_name + "' len=" + ("" + box_name.length()))
if box_name == "" {
next_i = cursor
} else {
cursor = FuncScannerBox.skip_whitespace(s, cursor)
if cursor >= n || s.substring(cursor, cursor + 1) != "{" {
next_i = cursor
} else {
local close_idx = FuncScannerBox.find_matching_brace(s, cursor)
if close_idx < 0 {
// マッチしない場合はこれ以上スキャンしても意味がないのでループ終了。
i = n
next_i = n
} else {
local body = s.substring(cursor + 1, close_idx)
local skip_main = 0
if box_name == "Main" { skip_main = 1 }
local include_me = 0
if box_name != "Main" { include_me = 1 }
local defs_box = me._scan_methods(body, box_name, skip_main, include_me)
me._append_defs(defs, defs_box)
next_i = close_idx + 1
}
}
}
}
}
}
i = next_i
}
return defs
}
method _scan_methods(source, box_name, skip_main, include_me) {
local methods = new ArrayBox()
local s = "" + source
local n = s.length()
local i = 0
loop(i < n) {
// Search for "method "
local k = -1
{
local pat = "method "
local m = pat.length()
local j = i
loop(j + m <= n) {
if s.substring(j, j + m) == pat { k = j break }
j = j + 1
}
}
if k < 0 { break }
i = k + 7
// Extract method name (alphanumeric until '(')
local name_start = i
local name_end = -1
{
local j = i
loop(j < n) {
local ch = s.substring(j, j + 1)
if ch == "(" { name_end = j break }
j = j + 1
}
}
if name_end < 0 { break }
local method_name = s.substring(name_start, name_end)
if skip_main == 1 && box_name == "Main" && method_name == "main" { i = name_end continue }
// Find '(' after name
local lparen = name_end
// Find matching ')' for params (skip strings)
local rparen = -1
{
local j = lparen + 1
local in_str = 0
local esc = 0
loop(j < n) {
local ch = s.substring(j, j + 1)
if in_str == 1 {
if esc == 1 { esc = 0 j = j + 1 continue }
if ch == "\\" { esc = 1 j = j + 1 continue }
if ch == "\"" { in_str = 0 j = j + 1 continue }
j = j + 1
continue
}
if ch == "\"" { in_str = 1 j = j + 1 continue }
if ch == ")" { rparen = j break }
j = j + 1
}
}
if rparen < 0 { break }
// Extract params (minimal: comma-separated names)
local params_str = s.substring(lparen + 1, rparen)
// static helper として扱うme ではなく FuncScannerBox に直接委譲)。
local params = FuncScannerBox._parse_params(params_str)
if include_me == 1 {
local first = ""
if params.length() > 0 { first = "" + params.get(0) }
if first != "me" {
local merged = new ArrayBox()
merged.push("me")
local pi2 = 0
local pn2 = params.length()
loop(pi2 < pn2) {
merged.push(params.get(pi2))
pi2 = pi2 + 1
}
params = merged
}
}
// Find opening '{' after ')'
local lbrace = -1
{
local j = rparen + 1
local in_str = 0
local esc = 0
loop(j < n) {
local ch = s.substring(j, j + 1)
if in_str == 1 {
if esc == 1 { esc = 0 j = j + 1 continue }
if ch == "\\" { esc = 1 j = j + 1 continue }
if ch == "\"" { in_str = 0 j = j + 1 continue }
j = j + 1
continue
}
if ch == "\"" { in_str = 1 j = j + 1 continue }
if ch == "{" { lbrace = j break }
j = j + 1
}
}
if lbrace < 0 { break }
// Find matching '}' (balanced)
local rbrace = -1
{
local depth = 0
local j = lbrace
local in_str = 0
local esc = 0
loop(j < n) {
local ch = s.substring(j, j + 1)
if in_str == 1 {
if esc == 1 { esc = 0 j = j + 1 continue }
if ch == "\\" { esc = 1 j = j + 1 continue }
if ch == "\"" { in_str = 0 j = j + 1 continue }
j = j + 1
continue
}
if ch == "\"" { in_str = 1 j = j + 1 continue }
if ch == "{" { depth = depth + 1 j = j + 1 continue }
if ch == "}" {
depth = depth - 1
j = j + 1
if depth == 0 { rbrace = j - 1 break }
continue
}
j = j + 1
}
}
if rbrace < 0 { break }
// Extract method body (inside braces)
local method_body = s.substring(lbrace + 1, rbrace)
// コメント除去と trim も static helper として扱う。
method_body = FuncScannerBox._strip_comments(method_body)
method_body = FuncScannerBox._trim(method_body)
// Parse method body to JSON (statement list)
local body_json = null
if method_body.length() > 0 {
local p = new ParserBox()
p.stage3_enable(1)
body_json = p.parse_program2(method_body)
}
if body_json != null && body_json != "" {
local def = new MapBox()
def.set("name", method_name)
def.set("params", params)
def.set("body_json", body_json)
def.set("box", box_name)
methods.push(def)
}
i = rbrace
}
return methods
}
method _append_defs(dst, defs_box) {
if defs_box == null { return }
local i = 0
loop(i < defs_box.length()) {
dst.push(defs_box.get(i))
i = i + 1
}
}
// ────────────────────────────────────────────────────────────
// Core Text Scanning Helpers (SSOT: single source of truth)
// Stage-B および他の箱からも参照される共通処理群
// ────────────────────────────────────────────────────────────
// Helper: 空白文字space/tab/newline/CRを idx 位置からスキップ
// 戻り値: スキップ後の位置(空白でない文字の位置、または文字列末尾)
method skip_whitespace(s, idx) {
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>
2025-11-20 08:03:05 +09:00
print("🔥🔥🔥 SENTINEL_SKIP_WS_CALLED!!! 🔥🔥🔥")
print("[skip_ws] START idx=" + ("" + idx) + " s.length()=" + ("" + s.length()))
local i = idx
local n = s.length()
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>
2025-11-20 08:03:05 +09:00
print("[skip_ws] i=" + ("" + i) + " n=" + ("" + n))
__mir__.log("skip_ws/head", i, n)
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>
2025-11-20 08:03:05 +09:00
// 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) {
__mir__.log("skip_ws/loop", i, n)
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>
2025-11-20 08:03:05 +09:00
print("[skip_ws] LOOP-TOP i=" + ("" + i))
if i >= n { break }
local ch = s.substring(i, i + 1)
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>
2025-11-20 08:03:05 +09:00
print("[skip_ws] LOOP i=" + ("" + i) + " ch='" + ch + "'")
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" { i = i + 1 } else { break }
}
__mir__.log("skip_ws/exit", i, n)
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>
2025-11-20 08:03:05 +09:00
print("[skip_ws] RETURN i=" + ("" + i))
return i
}
// Helper: キーワード前の境界チェック("box" などが識別子の一部でないことを確認)
// 戻り値: 1=境界OKキーワードとして有効, 0=境界NG識別子の一部
method kw_boundary_before(s, idx) {
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>
2025-11-20 08:03:05 +09:00
print("🎯 SENTINEL_KW_BOUNDARY_BEFORE_CALLED!!!")
if idx <= 0 { return 1 }
local ch = s.substring(idx - 1, idx)
if FuncScannerBox.is_ident_char(ch) == 1 { return 0 }
return 1
}
// Helper: キーワード後の境界チェック("box" などが識別子の一部でないことを確認)
// 戻り値: 1=境界OKキーワードとして有効, 0=境界NG識別子の一部
method kw_boundary_after(s, idx) {
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>
2025-11-20 08:03:05 +09:00
print("🎯 SENTINEL_KW_BOUNDARY_AFTER_CALLED!!!")
if idx >= s.length() { return 1 }
local ch = s.substring(idx, idx + 1)
if FuncScannerBox.is_ident_char(ch) == 1 { return 0 }
return 1
}
// Helper: 識別子として有効な文字かチェック0-9, A-Z, a-z, _
// 戻り値: 1=識別子文字, 0=非識別子文字
method is_ident_char(ch) {
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>
2025-11-20 08:03:05 +09:00
print("🔤 SENTINEL_IS_IDENT_CHAR_CALLED!!!")
if ch == null || ch == "" { return 0 }
if ch >= "0" && ch <= "9" { return 1 }
if ch >= "A" && ch <= "Z" { return 1 }
if ch >= "a" && ch <= "z" { return 1 }
if ch == "_" { return 1 }
return 0
}
method find_matching_brace(s, open_idx) {
local n = s.length()
if open_idx < 0 || open_idx >= n { return -1 }
// open_idx 以降だけを対象に走査することで、前方の構造に依存しないようにする。
local subs = s.substring(open_idx, n)
local m = subs.length()
local i = 0
local depth = 0
local in_str = 0
local esc = 0
local in_line = 0
local in_block = 0
loop(i < m) {
local ch = subs.substring(i, i + 1)
if in_line == 1 {
if ch == "\n" { in_line = 0 }
i = i + 1
continue
}
if in_block == 1 {
if ch == "*" && i + 1 < n && s.substring(i + 1, i + 2) == "/" {
in_block = 0
i = i + 2
continue
}
i = i + 1
continue
}
if in_str == 1 {
if esc == 1 { esc = 0 i = i + 1 continue }
if ch == "\\" { esc = 1 i = i + 1 continue }
if ch == "\"" { in_str = 0 i = i + 1 continue }
i = i + 1
continue
}
if ch == "\"" { in_str = 1 i = i + 1 continue }
if ch == "/" && i + 1 < m {
local ch2 = subs.substring(i + 1, i + 2)
if ch2 == "/" { in_line = 1 i = i + 2 continue }
if ch2 == "*" { in_block = 1 i = i + 2 continue }
}
if ch == "{" {
depth = depth + 1
i = i + 1
continue
}
if ch == "}" {
depth = depth - 1
i = i + 1
if depth == 0 { return open_idx + i - 1 }
continue
}
i = i + 1
}
return -1
}
// Helper: カンマ区切りパラメータリストをパース(例: "a, b, c" → ["a", "b", "c"]
// FuncScannerBox._trim を使用static helper パターン)
// 戻り値: ArrayBoxトリム済みパラメータ名のリスト
method parse_params(params_str) {
local params = new ArrayBox()
local pstr = "" + params_str
local pn = pstr.length()
local pstart = 0
loop(pstart < pn) {
// Skip whitespace
loop(pstart < pn) {
local ch = pstr.substring(pstart, pstart + 1)
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" { pstart = pstart + 1 } else { break }
}
if pstart >= pn { break }
// Find next comma or end
local pend = pstart
loop(pend < pn) {
local ch = pstr.substring(pend, pend + 1)
if ch == "," { break }
pend = pend + 1
}
// Extract param name (trim)
local pname = pstr.substring(pstart, pend)
pname = FuncScannerBox.trim(pname)
if pname.length() > 0 { params.push(pname) }
pstart = pend + 1
}
return params
}
// Helper: "//" と "/* */" コメントを削除(文字列リテラル内は保持、改行は保持)
// 戻り値: コメント削除後のソースコードnull の場合は空文字)
method strip_comments(source) {
// source が null の場合はそのまま空文字として扱う(コメント除去する対象がないだけ)
if source == null { return "" }
local s = "" + source
local out = ""
local i = 0
local n = s.length()
local in_str = 0
local esc = 0
local in_line = 0
local in_block = 0
loop(i < n) {
local ch = s.substring(i, i + 1)
if in_line == 1 {
if ch == "\n" { in_line = 0 out = out + ch }
i = i + 1
continue
}
if in_block == 1 {
if ch == "*" && i + 1 < n && s.substring(i + 1, i + 2) == "/" { in_block = 0 i = i + 2 continue }
i = i + 1
continue
}
if in_str == 1 {
if esc == 1 { out = out + ch esc = 0 i = i + 1 continue }
if ch == "\\" { out = out + ch esc = 1 i = i + 1 continue }
if ch == "\"" { out = out + ch in_str = 0 i = i + 1 continue }
out = out + ch
i = i + 1
continue
}
if ch == "\"" { out = out + ch in_str = 1 i = i + 1 continue }
if ch == "/" && i + 1 < n {
local ch2 = s.substring(i + 1, i + 2)
if ch2 == "/" { in_line = 1 i = i + 2 continue }
if ch2 == "*" { in_block = 1 i = i + 2 continue }
}
out = out + ch
i = i + 1
}
return out
}
// Helper: 前後の空白文字space/tab/newline/CRを削除
// 戻り値: トリム済み文字列null の場合は空文字)
method trim(s) {
if s == null { return "" }
local str = "" + s
local n = str.length()
local b = 0
loop(b < n) {
local ch = str.substring(b, b + 1)
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" { b = b + 1 } else { break }
}
local e = n
loop(e > b) {
local ch = str.substring(e - 1, e)
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" { e = e - 1 } else { break }
}
if e > b { return str.substring(b, e) }
return ""
}
// ────────────────────────────────────────────────────────────
// Static Helper Aliases (external API with underscore prefix)
// Stage-B および他の箱から static 呼び出しで使える薄いラッパー
// ────────────────────────────────────────────────────────────
// Static helper: パラメータリストパース(外部 API
method _parse_params(params_str) {
return FuncScannerBox.parse_params(params_str)
}
// Static helper: コメント削除(外部 API
method _strip_comments(source) {
return FuncScannerBox.strip_comments(source)
}
// Static helper: 前後空白削除(外部 API
method _trim(s) {
return FuncScannerBox.trim(s)
}
}