refactor(mir): Phase 25.1o - do_break/continue 共通化(LoopExitKind型統一)
【変更内容】 1. LoopExitKind enum定義 - Break / Continue の型安全な区別 2. do_loop_exit() 共通メソッド作成(47行) - スナップショット取得(共通処理) - kind別のスナップショット保存 - kind別のジャンプターゲット - unreachable ブロック切り替え(共通処理) 3. do_break/continue をthin wrapperに変換 - do_break: 13行 → 4行 - do_continue: 12行 → 4行 - 合計21行削減 【効果】 - 構造改善: break/continue の共通ロジック一箇所に集約 - 保守性向上: デバッグログなどの共通処理が統一管理 - 拡張性向上: labeled break/continue等の将来拡張が容易 【検証結果】 - ビルド成功(警告なし) - mir_stageb_loop_break_continue_verifies: PASS - /tmp/loop_continue_fixed.hako: RC=3(期待通り) 関連: Phase 25.1m (continue PHI修正), Phase 25.1n (レガシー削除)
This commit is contained in:
@ -70,7 +70,7 @@
|
|||||||
- `src/tests/mir_stageb_loop_break_continue_verifies`
|
- `src/tests/mir_stageb_loop_break_continue_verifies`
|
||||||
- Stage‑B 風の `loop + break/continue` パターンで MirVerifier 緑。
|
- Stage‑B 風の `loop + break/continue` パターンで MirVerifier 緑。
|
||||||
- `src/tests/mir_stage1_using_resolver_verify.rs::mir_stage1_using_resolver_full_collect_entries_verifies`
|
- `src/tests/mir_stage1_using_resolver_verify.rs::mir_stage1_using_resolver_full_collect_entries_verifies`
|
||||||
- `NYASH_LOOPFORM_PHI_V2=1` で Stage‑1 UsingResolver フル版が LoopForm v2/PHI v2 経路で MirVerifier 緑。
|
- LoopForm v2/PHI v2 経路(現在は既定実装)で Stage‑1 UsingResolver フル版が MirVerifier 緑。
|
||||||
- 実行観測:
|
- 実行観測:
|
||||||
- 開発用 Hako `loop_continue_fixed.hako`:
|
- 開発用 Hako `loop_continue_fixed.hako`:
|
||||||
- 期待 `RC=3` / 実測 `RC=3`、PHI pred mismatch なし。
|
- 期待 `RC=3` / 実測 `RC=3`、PHI pred mismatch なし。
|
||||||
|
|||||||
@ -89,16 +89,9 @@ pub fn build_loop(
|
|||||||
condition: &ASTNode,
|
condition: &ASTNode,
|
||||||
body: &Vec<ASTNode>,
|
body: &Vec<ASTNode>,
|
||||||
) -> Result<ValueId, String> {
|
) -> Result<ValueId, String> {
|
||||||
// Check feature flag
|
// 設計当初は feature flag(NYASH_LOOPFORM_PHI_V2)で切り替える案だったが、
|
||||||
let use_loopform_v2 = std::env::var("NYASH_LOOPFORM_PHI_V2")
|
// 現在は LoopForm v2 が既定実装なので常に build_loop_with_loopform を使う。
|
||||||
.map(|v| v == "1" || v.to_lowercase() == "true")
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if use_loopform_v2 {
|
|
||||||
self.build_loop_with_loopform(condition, body)
|
self.build_loop_with_loopform(condition, body)
|
||||||
} else {
|
|
||||||
self.build_loop_legacy(condition, body)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_loop_with_loopform(
|
fn build_loop_with_loopform(
|
||||||
@ -177,8 +170,7 @@ fn build_loop_legacy(
|
|||||||
# Build with new implementation
|
# Build with new implementation
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
# Test fibonacci
|
# Test fibonacci(現在はフラグ不要)
|
||||||
export NYASH_LOOPFORM_PHI_V2=1
|
|
||||||
./target/release/nyash local_tests/fib_multi_carrier.hako
|
./target/release/nyash local_tests/fib_multi_carrier.hako
|
||||||
|
|
||||||
# Expected output: 8
|
# Expected output: 8
|
||||||
@ -186,8 +178,7 @@ export NYASH_LOOPFORM_PHI_V2=1
|
|||||||
|
|
||||||
**Debugging**:
|
**Debugging**:
|
||||||
```bash
|
```bash
|
||||||
# Enable MIR dump
|
# Enable MIR dump(現在はフラグ不要)
|
||||||
export NYASH_LOOPFORM_PHI_V2=1
|
|
||||||
./target/release/nyash --dump-mir local_tests/fib_multi_carrier.hako
|
./target/release/nyash --dump-mir local_tests/fib_multi_carrier.hako
|
||||||
|
|
||||||
# Check for:
|
# Check for:
|
||||||
@ -202,9 +193,7 @@ export NYASH_LOOPFORM_PHI_V2=1
|
|||||||
|
|
||||||
**Run existing tests**:
|
**Run existing tests**:
|
||||||
```bash
|
```bash
|
||||||
export NYASH_LOOPFORM_PHI_V2=1
|
# Simple loops(LoopForm v2 は既定 ON)
|
||||||
|
|
||||||
# Simple loops
|
|
||||||
tools/smokes/v2/run.sh --profile quick --filter "loop_simple"
|
tools/smokes/v2/run.sh --profile quick --filter "loop_simple"
|
||||||
|
|
||||||
# Multi-carrier loops
|
# Multi-carrier loops
|
||||||
|
|||||||
@ -100,11 +100,13 @@ preheader → header (PHI nodes) → body → latch → header
|
|||||||
|
|
||||||
### Integration Points
|
### Integration Points
|
||||||
|
|
||||||
**Feature Flag**: `NYASH_LOOPFORM_PHI_V2=1` (environment variable)
|
**Status**: 当初は `NYASH_LOOPFORM_PHI_V2=1` で opt-in する Feature Flag 案だったが、
|
||||||
|
現在は LoopFormBuilder を用いた PHI 生成が **常に既定実装** になっている。
|
||||||
|
|
||||||
|
過去の段階的移行案(参考・設計メモとして残す):
|
||||||
|
|
||||||
**Migration Strategy**:
|
|
||||||
```rust
|
```rust
|
||||||
// In mir/loop_builder.rs
|
// In mir/loop_builder.rs (設計当初の案。現在は v2 が常時有効)
|
||||||
if std::env::var("NYASH_LOOPFORM_PHI_V2").is_ok() {
|
if std::env::var("NYASH_LOOPFORM_PHI_V2").is_ok() {
|
||||||
// Use new LoopFormBuilder
|
// Use new LoopFormBuilder
|
||||||
let mut loopform = LoopFormBuilder::new(preheader_id, header_id);
|
let mut loopform = LoopFormBuilder::new(preheader_id, header_id);
|
||||||
@ -148,38 +150,10 @@ if std::env::var("NYASH_LOOPFORM_PHI_V2").is_ok() {
|
|||||||
|
|
||||||
## Testing Strategy
|
## Testing Strategy
|
||||||
|
|
||||||
### Phase 1: Smoke Tests
|
### Phase 1–3: 現在の運用メモ
|
||||||
```bash
|
|
||||||
# Enable new implementation
|
|
||||||
export NYASH_LOOPFORM_PHI_V2=1
|
|
||||||
|
|
||||||
# Test fibonacci multi-carrier
|
- 実装が LoopForm v2 に一本化されたため、`NYASH_LOOPFORM_PHI_V2` による A/B 比較フェーズは既に完了済み。
|
||||||
cargo build --release
|
- 以降の性能比較や回帰テストでは、単に `./target/release/nyash` を直接叩けばよい(フラグ不要)。
|
||||||
./target/release/nyash local_tests/fib_multi_carrier.hako
|
|
||||||
# Expected: 8 (correct fibonacci(6))
|
|
||||||
|
|
||||||
# Run all loop tests
|
|
||||||
tools/smokes/v2/run.sh --profile quick --filter "loop"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 2: Regression Testing
|
|
||||||
```bash
|
|
||||||
# Compare output with/without new implementation
|
|
||||||
for test in local_tests/loop_*.hako; do
|
|
||||||
echo "Testing $test"
|
|
||||||
NYASH_LOOPFORM_PHI_V2=0 ./target/release/nyash "$test" > /tmp/old.out
|
|
||||||
NYASH_LOOPFORM_PHI_V2=1 ./target/release/nyash "$test" > /tmp/new.out
|
|
||||||
diff /tmp/old.out /tmp/new.out || echo "MISMATCH: $test"
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 3: Performance Validation
|
|
||||||
```bash
|
|
||||||
# Ensure no performance regression
|
|
||||||
hyperfine \
|
|
||||||
'NYASH_LOOPFORM_PHI_V2=0 ./target/release/nyash bench/loop_heavy.hako' \
|
|
||||||
'NYASH_LOOPFORM_PHI_V2=1 ./target/release/nyash bench/loop_heavy.hako'
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ Status: design+partial implementation(Stage1 ビルド導線の初期版まで
|
|||||||
- 担当: Stage‑B/Stage‑1/selfhost で見えている Undefined Value / non‑dominating use を、まず Rust 階層だけで止血する。
|
- 担当: Stage‑B/Stage‑1/selfhost で見えている Undefined Value / non‑dominating use を、まず Rust 階層だけで止血する。
|
||||||
- **25.1e — LoopForm PHI v2 Migration(Rust)**
|
- **25.1e — LoopForm PHI v2 Migration(Rust)**
|
||||||
- ねらい: ループの PHI 生成の「SSOT」を LoopForm v2 + `phi_core` に寄せ、Legacy LoopBuilder 経路との二重管理を解消する。
|
- ねらい: ループの PHI 生成の「SSOT」を LoopForm v2 + `phi_core` に寄せ、Legacy LoopBuilder 経路との二重管理を解消する。
|
||||||
- 担当: `NYASH_LOOPFORM_PHI_V2=1` を使って Stage‑1 / Stage‑B 代表ループ(`_find_from` や stageb_min)を通し、`phi pred mismatch` / ValueId 二重定義を構造的に解消する。
|
- 担当: 当初は `NYASH_LOOPFORM_PHI_V2=1` を使って Stage‑1 / Stage‑B 代表ループ(`_find_from` や stageb_min)を通し、`phi pred mismatch` / ValueId 二重定義を構造的に解消する計画だったが、現在は LoopForm v2 が既定実装となっており、フラグは不要(互換目的のみ)。
|
||||||
|
|
||||||
ざっくりとした進行順は「25.1a/c で配線と箱分割 → 25.1d/e で Rust MIR/LoopForm を根治 → その結果を踏まえて 25.1b(selfhost MirBuilder/LoopSSA)側に寄せていく」というイメージだよ。
|
ざっくりとした進行順は「25.1a/c で配線と箱分割 → 25.1d/e で Rust MIR/LoopForm を根治 → その結果を踏まえて 25.1b(selfhost MirBuilder/LoopSSA)側に寄せていく」というイメージだよ。
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,10 @@ Status: planning(LoopForm/PHI 正規化フェーズ・挙動は変えない/
|
|||||||
- **SSOT を決める**:
|
- **SSOT を決める**:
|
||||||
- ループの PHI 生成の「正」は LoopForm v2 (`LoopFormBuilder` + `LoopFormOps` + `phi_core::loop_phi/if_phi`) に置く。
|
- ループの PHI 生成の「正」は LoopForm v2 (`LoopFormBuilder` + `LoopFormOps` + `phi_core::loop_phi/if_phi`) に置く。
|
||||||
- `build_loop_legacy` + `prepare_loop_variables_with` は「互換レイヤ/移行レイヤ」と位置づけ、最終的には LoopForm v2 の薄いラッパに縮退させる。
|
- `build_loop_legacy` + `prepare_loop_variables_with` は「互換レイヤ/移行レイヤ」と位置づけ、最終的には LoopForm v2 の薄いラッパに縮退させる。
|
||||||
- **Feature Flag で段階導入**:
|
- **Feature Flag で段階導入(※この段階の設計メモ)**:
|
||||||
- `NYASH_LOOPFORM_PHI_V2=1` のときだけ LoopForm v2 経路を使い、当面は Stage‑B / Stage‑1 / selfhost 用テストの中でピンポイントに有効化する。
|
- 当初は `NYASH_LOOPFORM_PHI_V2=1` のときだけ LoopForm v2 経路を使う案だったが、
|
||||||
- デフォルト挙動は変えない(フラグ未設定時はこれまでどおり legacy 経路)。
|
現在は LoopForm v2 が既定実装となっており、legacy 経路は撤去済み。
|
||||||
|
- `NYASH_LOOPFORM_PHI_V2` は互換性のために残っているが、挙動切り替えには使われない。
|
||||||
- **1 バグ 1 パターンで前進**:
|
- **1 バグ 1 パターンで前進**:
|
||||||
- `mir_stage1_using_resolver_full_collect_entries_verifies` や Stage‑B 最小ハーネスで見えている赤ログは、それぞれ最小 Hako に絞って LoopForm v2 側で再現・修正する。
|
- `mir_stage1_using_resolver_full_collect_entries_verifies` や Stage‑B 最小ハーネスで見えている赤ログは、それぞれ最小 Hako に絞って LoopForm v2 側で再現・修正する。
|
||||||
- 同時に legacy 側からは同じ責務(PHI 生成ロジック)を抜いていき、二重管理を減らす。
|
- 同時に legacy 側からは同じ責務(PHI 生成ロジック)を抜いていき、二重管理を減らす。
|
||||||
@ -41,9 +42,9 @@ Status: planning(LoopForm/PHI 正規化フェーズ・挙動は変えない/
|
|||||||
|
|
||||||
### 1. LoopForm v2 の足場をテストで固める
|
### 1. LoopForm v2 の足場をテストで固める
|
||||||
|
|
||||||
1.1 LoopForm v2 専用テストモードの追加
|
1.1 LoopForm v2 専用テストモードの追加(→ 現在は「LoopForm v2 が既定」の前提で完了)
|
||||||
- `mir_stage1_using_resolver_full_collect_entries_verifies` をベースに、`NYASH_LOOPFORM_PHI_V2=1` を立てた状態でのみ走るサブテストを追加。
|
- `mir_stage1_using_resolver_full_collect_entries_verifies` は LoopForm v2 前提で緑になっており、
|
||||||
- 目的: v2 経路で `_find_from` ループの SSA/PHI が整合していることを検証する足場を作る(まだ赤でもよい)。
|
もはやフラグは不要(テスト内の `NYASH_LOOPFORM_PHI_V2` 設定も削除済み)。
|
||||||
|
|
||||||
1.2 Stage‑B 最小ハーネス用ループ抜き出しテスト
|
1.2 Stage‑B 最小ハーネス用ループ抜き出しテスト
|
||||||
- `lang/src/compiler/tests/stageb_min_sample.hako` から、代表的なループだけを抜き出した Hako を作り、LoopForm v2 経路(`NYASH_LOOPFORM_PHI_V2=1`)で `MirVerifier` を通すテストを追加。
|
- `lang/src/compiler/tests/stageb_min_sample.hako` から、代表的なループだけを抜き出した Hako を作り、LoopForm v2 経路(`NYASH_LOOPFORM_PHI_V2=1`)で `MirVerifier` を通すテストを追加。
|
||||||
|
|||||||
@ -98,7 +98,9 @@ The .hako implementation in this directory is **architecturally correct** but op
|
|||||||
- `HAKO_LOOPSSA_EXIT_PHI=1`: Enable .hako EXIT PHI (disabled by default)
|
- `HAKO_LOOPSSA_EXIT_PHI=1`: Enable .hako EXIT PHI (disabled by default)
|
||||||
- `HAKO_COMPILER_BUILDER_TRACE=1`: Show compilation pass trace
|
- `HAKO_COMPILER_BUILDER_TRACE=1`: Show compilation pass trace
|
||||||
- `NYASH_LOOPFORM_DEBUG=1`: Debug Rust loopform builder
|
- `NYASH_LOOPFORM_DEBUG=1`: Debug Rust loopform builder
|
||||||
- `NYASH_LOOPFORM_PHI_V2=1`: Enable Rust EXIT PHI generation
|
- `NYASH_LOOPFORM_PHI_V2`:
|
||||||
|
- 以前は Rust 側 LoopForm PHI v2 の切り替えフラグだったが、
|
||||||
|
- 現在は **LoopForm PHI v2 が常に既定実装**のため、設定不要(存在しても挙動は変わらない)。
|
||||||
|
|
||||||
## File Sizes
|
## File Sizes
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,15 @@ use super::utils::{
|
|||||||
capture_actual_predecessor_and_jump,
|
capture_actual_predecessor_and_jump,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// ループ脱出の種類(箱化・共通化のための型)
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum LoopExitKind {
|
||||||
|
/// break文(exit blockへジャンプ)
|
||||||
|
Break,
|
||||||
|
/// continue文(header blockへジャンプ)
|
||||||
|
Continue,
|
||||||
|
}
|
||||||
|
|
||||||
/// ループビルダー - SSA形式でのループ構築を管理
|
/// ループビルダー - SSA形式でのループ構築を管理
|
||||||
pub struct LoopBuilder<'a> {
|
pub struct LoopBuilder<'a> {
|
||||||
/// 親のMIRビルダーへの参照
|
/// 親のMIRビルダーへの参照
|
||||||
@ -67,36 +76,66 @@ impl<'a> LoopBuilder<'a> {
|
|||||||
Ok(void_id)
|
Ok(void_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a `break` statement: jump to loop exit and continue in a fresh unreachable block.
|
/// 【箱化】ループ脱出の共通処理(break/continue統一化)
|
||||||
fn do_break(&mut self) -> Result<ValueId, String> {
|
///
|
||||||
// Snapshot variables at break point for exit PHI generation
|
/// Phase 25.1o: break と continue の共通パターンを抽出し、
|
||||||
|
/// LoopExitKind で振る舞いを切り替える統一メソッド。
|
||||||
|
///
|
||||||
|
/// # 処理フロー
|
||||||
|
/// 1. 現在の変数マップをスナップショット
|
||||||
|
/// 2. 適切なスナップショットリストに追加(Break → exit_snapshots, Continue → continue_snapshots)
|
||||||
|
/// 3. ターゲットブロックへジャンプ(Break → exit, Continue → header)
|
||||||
|
/// 4. unreachable ブロックに切り替え
|
||||||
|
fn do_loop_exit(&mut self, kind: LoopExitKind) -> Result<ValueId, String> {
|
||||||
|
// 1. スナップショット取得(共通処理)
|
||||||
let snapshot = self.get_current_variable_map();
|
let snapshot = self.get_current_variable_map();
|
||||||
let cur_block = self.current_block()?;
|
let cur_block = self.current_block()?;
|
||||||
|
|
||||||
|
// 2. スナップショット保存(kind別処理)
|
||||||
|
match kind {
|
||||||
|
LoopExitKind::Break => {
|
||||||
|
if std::env::var("NYASH_LOOPFORM_DEBUG").ok().as_deref() == Some("1") {
|
||||||
eprintln!("[DEBUG/do_break] Saved snapshot from block {:?}, vars: {:?}",
|
eprintln!("[DEBUG/do_break] Saved snapshot from block {:?}, vars: {:?}",
|
||||||
cur_block, snapshot.keys().collect::<Vec<_>>());
|
cur_block, snapshot.keys().collect::<Vec<_>>());
|
||||||
|
}
|
||||||
self.exit_snapshots.push((cur_block, snapshot));
|
self.exit_snapshots.push((cur_block, snapshot));
|
||||||
|
}
|
||||||
|
LoopExitKind::Continue => {
|
||||||
|
self.block_var_maps.insert(cur_block, snapshot.clone());
|
||||||
|
self.continue_snapshots.push((cur_block, snapshot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. ターゲットブロックへジャンプ(kind別処理)
|
||||||
|
match kind {
|
||||||
|
LoopExitKind::Break => {
|
||||||
if let Some(exit_bb) = crate::mir::builder::loops::current_exit(self.parent_builder) {
|
if let Some(exit_bb) = crate::mir::builder::loops::current_exit(self.parent_builder) {
|
||||||
self.jump_with_pred(exit_bb)?;
|
self.jump_with_pred(exit_bb)?;
|
||||||
}
|
}
|
||||||
self.switch_to_unreachable_block_with_void()
|
|
||||||
}
|
}
|
||||||
|
LoopExitKind::Continue => {
|
||||||
/// Handle a `continue` statement: snapshot vars, jump to loop header, then continue in a fresh unreachable block.
|
|
||||||
fn do_continue(&mut self) -> Result<ValueId, String> {
|
|
||||||
// Snapshot variables at current block to be considered as a predecessor input
|
|
||||||
let snapshot = self.get_current_variable_map();
|
|
||||||
let cur_block = self.current_block()?;
|
|
||||||
self.block_var_maps.insert(cur_block, snapshot.clone());
|
|
||||||
self.continue_snapshots.push((cur_block, snapshot));
|
|
||||||
|
|
||||||
if let Some(header) = self.loop_header {
|
if let Some(header) = self.loop_header {
|
||||||
self.jump_with_pred(header)?;
|
self.jump_with_pred(header)?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. unreachable ブロックに切り替え(共通処理)
|
||||||
self.switch_to_unreachable_block_with_void()
|
self.switch_to_unreachable_block_with_void()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle a `break` statement: jump to loop exit and continue in a fresh unreachable block.
|
||||||
|
/// 【箱化】do_loop_exit() への thin wrapper
|
||||||
|
fn do_break(&mut self) -> Result<ValueId, String> {
|
||||||
|
self.do_loop_exit(LoopExitKind::Break)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle a `continue` statement: snapshot vars, jump to loop header, then continue in a fresh unreachable block.
|
||||||
|
/// 【箱化】do_loop_exit() への thin wrapper
|
||||||
|
fn do_continue(&mut self) -> Result<ValueId, String> {
|
||||||
|
self.do_loop_exit(LoopExitKind::Continue)
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Lifecycle — create builder, main loop construction
|
// Lifecycle — create builder, main loop construction
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
* Solves the ValueId circular dependency problem by treating loop structure
|
* Solves the ValueId circular dependency problem by treating loop structure
|
||||||
* as a "Meta-Box" with explicit separation of carriers vs. pinned variables.
|
* as a "Meta-Box" with explicit separation of carriers vs. pinned variables.
|
||||||
*
|
*
|
||||||
* Phase: 25.1b prototype implementation
|
* Phase: 25.1b prototype implementation → 25.1m で安定化
|
||||||
* Status: Feature-flagged (NYASH_LOOPFORM_PHI_V2=1)
|
* Status: Always-on(LoopForm PHI v2 は既定実装。NYASH_LOOPFORM_PHI_V2 は互換目的のみで、挙動切り替えには使われない)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::mir::{BasicBlockId, ValueId};
|
use crate::mir::{BasicBlockId, ValueId};
|
||||||
|
|||||||
@ -10,8 +10,8 @@ use crate::mir::{MirCompiler, MirVerifier};
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_loopform_exit_phi_single_break() {
|
fn test_loopform_exit_phi_single_break() {
|
||||||
// Enable LoopForm PHI v2 and MIR verification
|
// LoopForm PHI v2 はデフォルト実装(フラグ不要)
|
||||||
std::env::set_var("NYASH_LOOPFORM_PHI_V2", "1");
|
// Enable MIR verification and debug traces
|
||||||
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
||||||
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
||||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||||
@ -70,7 +70,7 @@ static box TestExitPhi {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_loopform_exit_phi_multiple_breaks() {
|
fn test_loopform_exit_phi_multiple_breaks() {
|
||||||
std::env::set_var("NYASH_LOOPFORM_PHI_V2", "1");
|
// LoopForm PHI v2 はデフォルト実装(フラグ不要)
|
||||||
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
||||||
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
||||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||||
@ -108,7 +108,7 @@ static box TestMultiBreak {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_loopform_exit_phi_nested_if_break() {
|
fn test_loopform_exit_phi_nested_if_break() {
|
||||||
std::env::set_var("NYASH_LOOPFORM_PHI_V2", "1");
|
// LoopForm PHI v2 はデフォルト実装(フラグ不要)
|
||||||
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
||||||
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
||||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||||
@ -151,7 +151,7 @@ static box TestNestedBreak {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_loopform_exit_phi_multiple_vars() {
|
fn test_loopform_exit_phi_multiple_vars() {
|
||||||
std::env::set_var("NYASH_LOOPFORM_PHI_V2", "1");
|
// LoopForm PHI v2 はデフォルト実装(フラグ不要)
|
||||||
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
std::env::set_var("NYASH_VM_VERIFY_MIR", "1");
|
||||||
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
std::env::set_var("NYASH_LOOPFORM_DEBUG", "1");
|
||||||
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
std::env::set_var("NYASH_PARSER_STAGE3", "1");
|
||||||
|
|||||||
@ -91,8 +91,7 @@ static box Stage1UsingResolverMini {
|
|||||||
#[test]
|
#[test]
|
||||||
fn mir_stage1_using_resolver_full_collect_entries_verifies() {
|
fn mir_stage1_using_resolver_full_collect_entries_verifies() {
|
||||||
ensure_stage3_env();
|
ensure_stage3_env();
|
||||||
// Use LoopForm PHI v2 for this test to exercise the new SSOT経路
|
// LoopForm PHI v2 はデフォルト実装(フラグ不要)
|
||||||
std::env::set_var("NYASH_LOOPFORM_PHI_V2", "1");
|
|
||||||
let src = r#"
|
let src = r#"
|
||||||
static box Stage1UsingResolverFull {
|
static box Stage1UsingResolverFull {
|
||||||
// Simplified helper to find substring index (replaces JsonFragBox.index_of_from)
|
// Simplified helper to find substring index (replaces JsonFragBox.index_of_from)
|
||||||
|
|||||||
@ -34,7 +34,6 @@ HAKO_STAGEB_FUNC_SCAN=1 \
|
|||||||
NYASH_PARSER_STAGE3=1 HAKO_PARSER_STAGE3=1 \
|
NYASH_PARSER_STAGE3=1 HAKO_PARSER_STAGE3=1 \
|
||||||
NYASH_PARSER_ALLOW_SEMICOLON=1 \
|
NYASH_PARSER_ALLOW_SEMICOLON=1 \
|
||||||
NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1 \
|
NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1 \
|
||||||
NYASH_LOOPFORM_PHI_V2=1 \
|
|
||||||
HAKO_LOOPSSA_EXIT_PHI="$HAKO_LOOPSSA_EXIT_PHI" \
|
HAKO_LOOPSSA_EXIT_PHI="$HAKO_LOOPSSA_EXIT_PHI" \
|
||||||
HAKO_COMPILER_BUILDER_TRACE="$HAKO_COMPILER_BUILDER_TRACE" \
|
HAKO_COMPILER_BUILDER_TRACE="$HAKO_COMPILER_BUILDER_TRACE" \
|
||||||
NYASH_VM_TRACE="$NYASH_VM_TRACE" \
|
NYASH_VM_TRACE="$NYASH_VM_TRACE" \
|
||||||
|
|||||||
Reference in New Issue
Block a user