fix(stageb): ParserStmtBox skip_ws静的呼び出し化 - Phase 25.1

**変更内容**:
- ctx.skip_ws(src, j) → ParserStringUtilsBox.skip_ws(src, j) (20箇所)
  - ParserStmtBox.parse: 13箇所
  - ParserStmtBox.parse_using: 7箇所

**理由**:
- MIRレベルでctx(ParserBox instance)がString化する問題を根本回避
- 箱理論的に正しい設計: scan utility = static box統一
- Region+next_iパターンと一貫性維持(LoopForm v2設計準拠)

**影響範囲**:
- lang/src/compiler/parser/stmt/parser_stmt_box.hako のみ
- using追加: ParserStringUtilsBox

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-21 12:27:24 +09:00
parent b00cc8d579
commit 227ce61de8

View File

@ -6,6 +6,7 @@
using sh_core as StringHelpers // Required: using chain resolution not implemented
using lang.compiler.parser.stmt.parser_control_box
using lang.compiler.parser.stmt.parser_exception_box
using lang.compiler.parser.scan.parser_string_utils_box as ParserStringUtilsBox
static box ParserStmtBox {
parse(src, i, ctx) {
@ -21,7 +22,7 @@ static box ParserStmtBox {
env.set("HAKO_STAGEB_STMT_DEPTH", "1")
}
}
local j = ctx.skip_ws(src, i)
local j = ParserStringUtilsBox.skip_ws(src, i)
// VM 差分で skip_ws が前進しないパスがあったため、手動で最小限の空白スキップをフォローする。
{
local n = src.length()
@ -50,19 +51,19 @@ static box ParserStmtBox {
print("[parser/stmt] kind=extern_c j=" + ("" + j))
}
}
j = j + 9 // len("@extern_c")
j = ctx.skip_ws(src, j)
j = j + 9 // len(\"@extern_c\")
j = ParserStringUtilsBox.skip_ws(src, j)
if j < src.length() && src.substring(j, j+1) == "(" { j = j + 1 }
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
// First string literal: symbol
local sym = ""
if j < src.length() && src.substring(j, j+1) == "\"" {
sym = ctx.read_string_lit(src, j)
j = ctx.gpos_get()
}
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
if j < src.length() && src.substring(j, j+1) == "," { j = j + 1 }
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
// Second string literal: func
local func_name = ""
if j < src.length() && src.substring(j, j+1) == "\"" {
@ -70,10 +71,10 @@ static box ParserStmtBox {
j = ctx.gpos_get()
}
// Skip to ')' if present
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
if j < src.length() && src.substring(j, j+1) == ")" { j = j + 1 }
// Optional semicolon is consumed by caller; still advance if present
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
if j < src.length() && src.substring(j, j+1) == ";" { j = j + 1 }
ctx.gpos_set(j)
// Record annotation in parser context and emit no statement
@ -106,7 +107,7 @@ static box ParserStmtBox {
}
}
j = j + 6
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
local default_ret = "{\"type\":\"Int\",\"value\":0}"
local expr_json_ret = default_ret
local end_pos_ret = j
@ -149,14 +150,14 @@ static box ParserStmtBox {
}
}
j = j + kw_len
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
local idp = ctx.read_ident2(src, j)
local at = idp.lastIndexOf("@")
local name = idp.substring(0, at)
j = ctx.to_int(idp.substring(at+1, idp.length()))
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
if j < src.length() && src.substring(j, j+1) == "=" { j = j + 1 }
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
local default_local = "{\"type\":\"Int\",\"value\":0}"
local expr_json_local = default_local
local end_pos_local = j
@ -269,13 +270,13 @@ static box ParserStmtBox {
if at0 > 0 {
local name0 = idp0.substring(0, at0)
local k0 = ctx.to_int(idp0.substring(at0+1, idp0.length()))
k0 = ctx.skip_ws(src, k0)
k0 = ParserStringUtilsBox.skip_ws(src, k0)
if k0 < src.length() && src.substring(k0, k0+1) == "=" {
local eq_two = "="
if k0 + 1 < src.length() { eq_two = src.substring(k0, k0+2) }
if eq_two != "==" {
k0 = k0 + 1
k0 = ctx.skip_ws(src, k0)
k0 = ParserStringUtilsBox.skip_ws(src, k0)
local default_local = "{\"type\":\"Int\",\"value\":0}"
local expr_json0 = default_local
local end_pos0 = k0
@ -321,16 +322,16 @@ static box ParserStmtBox {
// Parse using statement
parse_using(src, i, stmt_start, ctx) {
local j = i + 5 // skip "using"
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
if src.substring(j, j+1) == "\"" {
local p = ctx.read_string_lit(src, j)
j = ctx.gpos_get()
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
local alias = null
if ctx.starts_with_kw(src, j, "as") == 1 {
j = j + 2
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
local idp = ctx.read_ident2(src, j)
local at = idp.lastIndexOf("@")
alias = idp.substring(0, at)
@ -345,10 +346,10 @@ static box ParserStmtBox {
j = ctx.to_int(idp.substring(at+1, idp.length()))
local cont = 1
loop(cont == 1) {
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
if src.substring(j, j+1) == "." {
j = j + 1
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
idp = ctx.read_ident2(src, j)
at = idp.lastIndexOf("@")
name = name + "." + idp.substring(0, at)
@ -357,11 +358,11 @@ static box ParserStmtBox {
cont = 0
}
}
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
local alias2 = null
if ctx.starts_with_kw(src, j, "as") == 1 {
j = j + 2
j = ctx.skip_ws(src, j)
j = ParserStringUtilsBox.skip_ws(src, j)
idp = ctx.read_ident2(src, j)
at = idp.lastIndexOf("@")
alias2 = idp.substring(0, at)