From 227ce61de82be067eeecd309948329a600bc2c71 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Fri, 21 Nov 2025 12:27:24 +0900 Subject: [PATCH] =?UTF-8?q?fix(stageb):=20ParserStmtBox=20skip=5Fws?= =?UTF-8?q?=E9=9D=99=E7=9A=84=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=97=E5=8C=96?= =?UTF-8?q?=20-=20Phase=2025.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **変更内容**: - 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 --- .../compiler/parser/stmt/parser_stmt_box.hako | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/lang/src/compiler/parser/stmt/parser_stmt_box.hako b/lang/src/compiler/parser/stmt/parser_stmt_box.hako index b4de6bf7..182304f7 100644 --- a/lang/src/compiler/parser/stmt/parser_stmt_box.hako +++ b/lang/src/compiler/parser/stmt/parser_stmt_box.hako @@ -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)