refactor(builder): 箱理論リファクタリング Phase 1完了
🎯 builder_calls.rs (982行) を箱理論で責務別にモジュール分割 ## 成果 ✅ builder_calls.rs: 982行 → 766行(-216行、22%削減) ✅ calls/lowering.rs: 354行(新規、箱理論6段階パターン) ✅ calls/utils.rs: 45行(新規、ユーティリティ統一) ✅ ビルド・テスト完全成功(0エラー) ## 箱理論の実装 1. 責務ごとに箱に分離: - lowering: 関数lowering専用 - utils: ユーティリティ統一 - emit/build: Phase 2で実装予定 2. 境界を明確に: - mod.rs で公開インターフェース定義 - pub(in crate::mir::builder) で適切な可視性制御 3. いつでも戻せる: - 段階的移行、各ステップでビルド確認 - 既存API完全保持(互換性100%) 4. 巨大関数は分割: - lower_static_method_as_function: 125行 → 6段階に分解 - lower_method_as_function: 80行 → 6段階に分解 ## 箱理論6段階パターン 1. prepare_lowering_context - Context準備 2. create_function_skeleton - 関数スケルトン作成 3. setup_function_params - パラメータ設定 4. lower_function_body - 本体lowering 5. finalize_function - 関数finalize 6. restore_lowering_context - Context復元 ## ファイル構成 src/mir/builder/ ├── calls/ │ ├── mod.rs # 公開インターフェース │ ├── lowering.rs # 関数lowering(354行) │ └── utils.rs # ユーティリティ(45行) └── builder_calls.rs # 削減版(766行) ## 次のステップ Phase 2: emit.rs 作成(~500行移行) Phase 3: build.rs 作成(~350行移行) 最終目標: builder_calls.rs を200行以内に 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Task先生 <task@anthropic.com>
This commit is contained in:
@ -2,10 +2,16 @@ use crate::ast::ASTNode;
|
||||
use crate::mir::{MirCompiler, MirVerifier};
|
||||
use crate::parser::NyashParser;
|
||||
|
||||
fn ensure_stage3_env() {
|
||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||
std::env::set_var("NYASH_PARSER_ALLOW_SEMICOLON", "1");
|
||||
}
|
||||
|
||||
/// Minimal Stage‑1 using resolver harness resembling Stage1UsingResolverBox.resolve_for_source.
|
||||
/// Focuses on loops over ArrayBox/MapBox and JSON scanning, without FileBox/@ sugar.
|
||||
#[test]
|
||||
fn mir_stage1_using_resolver_min_fragment_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
using lang.compiler.parser.scan.parser_common_utils_box as ParserCommonUtilsBox
|
||||
using selfhost.shared.json.utils.json_frag as JsonFragBox
|
||||
@ -71,6 +77,7 @@ static box Stage1UsingResolverMini {
|
||||
/// Verify MIR/SSA for ParserBox.parse_program2 in isolation by compiling a small wrapper.
|
||||
#[test]
|
||||
fn mir_parserbox_parse_program2_harness_parses_minimal_source() {
|
||||
ensure_stage3_env();
|
||||
// Minimal wrapper that brings ParserBox into scope and calls parse_program2.
|
||||
let src = r#"
|
||||
using lang.compiler.parser.parser_box as ParserBox
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
use crate::parser::NyashParser;
|
||||
use crate::mir::MirPrinter;
|
||||
|
||||
fn ensure_stage3_env() {
|
||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||
std::env::set_var("NYASH_PARSER_ALLOW_SEMICOLON", "1");
|
||||
}
|
||||
use crate::ast::ASTNode;
|
||||
use crate::mir::{MirCompiler, MirVerifier};
|
||||
|
||||
@ -15,6 +21,7 @@ use crate::mir::{MirCompiler, MirVerifier};
|
||||
/// を Rust MirBuilder で MIR 化し、SSA/PHI が破綻していないことを検証する。
|
||||
#[test]
|
||||
fn mir_stageb_like_args_length_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box StageBArgsBox {
|
||||
method resolve_src(args) {
|
||||
@ -36,6 +43,10 @@ static box StageBArgsBox {
|
||||
// Verify MIR SSA/PHI invariants
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (StageBArgsBox.resolve_src) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
@ -61,6 +72,7 @@ static box StageBArgsBox {
|
||||
/// を Rust MirBuilder で MIR 化し、SSA/PHI が破綻していないことを検証する。
|
||||
#[test]
|
||||
fn mir_stageb_like_if_args_length_loop_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box StageBArgsBox {
|
||||
method process(args) {
|
||||
@ -84,6 +96,10 @@ static box StageBArgsBox {
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (StageBArgsBox.process if+loop) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
@ -107,6 +123,7 @@ static box StageBArgsBox {
|
||||
/// }
|
||||
#[test]
|
||||
fn mir_stageb_like_nested_if_loop_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box TestNested {
|
||||
method complex(data) {
|
||||
@ -135,6 +152,10 @@ static box TestNested {
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (TestNested.complex nested if+loop) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
@ -151,6 +172,7 @@ static box TestNested {
|
||||
/// }
|
||||
#[test]
|
||||
fn mir_stageb_like_loop_cond_uses_length_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box StageBArgsBox {
|
||||
method process(args) {
|
||||
@ -172,6 +194,10 @@ static box StageBArgsBox {
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (StageBArgsBox.process loop cond uses length) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
@ -188,6 +214,7 @@ static box StageBArgsBox {
|
||||
/// }
|
||||
#[test]
|
||||
fn mir_stageb_like_conditional_and_loop_length_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box TestNested2 {
|
||||
method walk(data) {
|
||||
@ -209,6 +236,10 @@ static box TestNested2 {
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (TestNested2.walk conditional+loop length) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
@ -221,6 +252,7 @@ static box TestNested2 {
|
||||
/// - 文字列内/エスケープなどの分岐を含むが、ここでは最小限の骨格のみを再現。
|
||||
#[test]
|
||||
fn mir_jsonscanbox_like_seek_array_end_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
using selfhost.shared.json.core.string_scan as StringScanBox
|
||||
|
||||
@ -252,6 +284,10 @@ static box JsonScanBoxMini {
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (JsonScanBoxMini.seek_array_end) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
|
||||
141
src/tests/mir_stageb_loop_break_continue.rs
Normal file
141
src/tests/mir_stageb_loop_break_continue.rs
Normal file
@ -0,0 +1,141 @@
|
||||
use crate::ast::ASTNode;
|
||||
use crate::mir::{MirCompiler, MirPrinter, MirVerifier};
|
||||
use crate::parser::NyashParser;
|
||||
|
||||
fn ensure_stage3_env() {
|
||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||
std::env::set_var("NYASH_PARSER_ALLOW_SEMICOLON", "1");
|
||||
}
|
||||
|
||||
/// Stage‑B 風: loop + break/continue + ArrayBox.length/get
|
||||
///
|
||||
/// static box LoopBreakContinueBox {
|
||||
/// method sum_positive_until_null(arr) {
|
||||
/// if arr == null { return 0 }
|
||||
/// local i = 0
|
||||
/// local acc = 0
|
||||
/// loop (i < arr.length()) {
|
||||
/// local v = arr.get(i)
|
||||
/// if v == null { break }
|
||||
/// if v < 0 {
|
||||
/// i = i + 1
|
||||
/// continue
|
||||
/// }
|
||||
/// acc = acc + v
|
||||
/// i = i + 1
|
||||
/// }
|
||||
/// return acc
|
||||
/// }
|
||||
/// }
|
||||
#[test]
|
||||
fn mir_stageb_loop_break_continue_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box LoopBreakContinueBox {
|
||||
method sum_positive_until_null(arr) {
|
||||
if arr == null { return 0 }
|
||||
local i = 0
|
||||
local acc = 0
|
||||
loop (i < arr.length()) {
|
||||
local v = arr.get(i)
|
||||
if v == null { break }
|
||||
if v < 0 {
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
acc = acc + v
|
||||
i = i + 1
|
||||
}
|
||||
return acc
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let ast: ASTNode = NyashParser::parse_from_string(src).expect("parse ok");
|
||||
let mut mc = MirCompiler::with_options(false);
|
||||
let cr = mc.compile(ast).expect("compile");
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (LoopBreakContinueBox.sum_positive_until_null) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
panic!("MIR verification failed for StageB-like loop+break/continue pattern");
|
||||
}
|
||||
}
|
||||
|
||||
/// Stage‑B 風: 入れ子ループ + break/continue + length/get
|
||||
///
|
||||
/// static box LoopNestedBreakBox {
|
||||
/// method nested_walk(arr) {
|
||||
/// if arr == null { return 0 }
|
||||
/// local i = 0
|
||||
/// local total = 0
|
||||
/// loop (i < arr.length()) {
|
||||
/// local inner = arr.get(i)
|
||||
/// if inner == null {
|
||||
/// i = i + 1
|
||||
/// continue
|
||||
/// }
|
||||
/// local j = 0
|
||||
/// loop (j < inner.length()) {
|
||||
/// local v = inner.get(j)
|
||||
/// if v == null { break }
|
||||
/// total = total + v
|
||||
/// j = j + 1
|
||||
/// }
|
||||
/// i = i + 1
|
||||
/// }
|
||||
/// return total
|
||||
/// }
|
||||
/// }
|
||||
#[test]
|
||||
fn mir_stageb_nested_loop_break_continue_verifies() {
|
||||
ensure_stage3_env();
|
||||
let src = r#"
|
||||
static box LoopNestedBreakBox {
|
||||
method nested_walk(arr) {
|
||||
if arr == null { return 0 }
|
||||
local i = 0
|
||||
local total = 0
|
||||
loop (i < arr.length()) {
|
||||
local inner = arr.get(i)
|
||||
if inner == null {
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
local j = 0
|
||||
loop (j < inner.length()) {
|
||||
local v = inner.get(j)
|
||||
if v == null { break }
|
||||
total = total + v
|
||||
j = j + 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return total
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let ast: ASTNode = NyashParser::parse_from_string(src).expect("parse ok");
|
||||
let mut mc = MirCompiler::with_options(false);
|
||||
let cr = mc.compile(ast).expect("compile");
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
if std::env::var("NYASH_MIR_TEST_DUMP").ok().as_deref() == Some("1") {
|
||||
let dump = MirPrinter::new().print_module(&cr.module);
|
||||
eprintln!("----- MIR DUMP (LoopNestedBreakBox.nested_walk) -----\n{}", dump);
|
||||
}
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
panic!("MIR verification failed for StageB-like nested loop+break/continue pattern");
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ pub mod identical_exec_collections;
|
||||
pub mod identical_exec_instance;
|
||||
pub mod identical_exec_string;
|
||||
pub mod mir_stageb_like_args_length;
|
||||
pub mod mir_stageb_loop_break_continue;
|
||||
pub mod mir_stage1_using_resolver_verify;
|
||||
pub mod mir_vm_poc;
|
||||
pub mod nyash_abi_basic;
|
||||
|
||||
Reference in New Issue
Block a user