docs: Phase 118 DONE (loop+if merge parity)
This commit is contained in:
@ -72,17 +72,19 @@ JoinIR の箱構造と責務、ループ/if の lowering パターンを把握
|
|||||||
- `docs/development/current/main/phases/phase-116/README.md`
|
- `docs/development/current/main/phases/phase-116/README.md`
|
||||||
19. Phase 117: if-only nested-if + call merge parity(ネストif + call merge)
|
19. Phase 117: if-only nested-if + call merge parity(ネストif + call merge)
|
||||||
- `docs/development/current/main/phases/phase-117/README.md`
|
- `docs/development/current/main/phases/phase-117/README.md`
|
||||||
20. Phase 104: loop(true) break-only digits(VM + LLVM EXE)
|
20. Phase 118: loop + if-else merge parity(loop + if-else 変数更新 merge / carrier PHI contract)
|
||||||
|
- `docs/development/current/main/phases/phase-118/README.md`
|
||||||
|
21. Phase 104: loop(true) break-only digits(VM + LLVM EXE)
|
||||||
- `docs/development/current/main/phases/phase-104/README.md`
|
- `docs/development/current/main/phases/phase-104/README.md`
|
||||||
21. Phase 107: json_cur find_balanced_* depth scan(VM + LLVM EXE)
|
22. Phase 107: json_cur find_balanced_* depth scan(VM + LLVM EXE)
|
||||||
- `docs/development/current/main/phases/phase-107/README.md`
|
- `docs/development/current/main/phases/phase-107/README.md`
|
||||||
22. Phase 108: Pattern2 policy router SSOT(入口の薄さを固定)
|
23. Phase 108: Pattern2 policy router SSOT(入口の薄さを固定)
|
||||||
- `docs/development/current/main/phases/phase-108/README.md`
|
- `docs/development/current/main/phases/phase-108/README.md`
|
||||||
23. Phase 109: error_tags hints SSOT(Fail-Fast + hint の語彙固定)
|
24. Phase 109: error_tags hints SSOT(Fail-Fast + hint の語彙固定)
|
||||||
- `docs/development/current/main/phases/phase-109/README.md`
|
- `docs/development/current/main/phases/phase-109/README.md`
|
||||||
24. MIR Builder(Context 分割の入口)
|
25. MIR Builder(Context 分割の入口)
|
||||||
- `src/mir/builder/README.md`
|
- `src/mir/builder/README.md`
|
||||||
25. Scope/BindingId(shadowing・束縛同一性の段階移行)
|
26. Scope/BindingId(shadowing・束縛同一性の段階移行)
|
||||||
- `docs/development/current/main/phase73-scope-manager-design.md`
|
- `docs/development/current/main/phase73-scope-manager-design.md`
|
||||||
- `docs/development/current/main/PHASE_74_SUMMARY.md`
|
- `docs/development/current/main/PHASE_74_SUMMARY.md`
|
||||||
- `docs/development/current/main/PHASE_75_SUMMARY.md`
|
- `docs/development/current/main/PHASE_75_SUMMARY.md`
|
||||||
|
|||||||
@ -1,5 +1,18 @@
|
|||||||
# Self Current Task — Now (main)
|
# Self Current Task — Now (main)
|
||||||
|
|
||||||
|
## 2025-12-18:Phase 118 完了 ✅
|
||||||
|
|
||||||
|
**Phase 118: loop + if-only merge parity**
|
||||||
|
- loop + if-only で条件付き変数更新 merge を VM/LLVM で固定
|
||||||
|
- Fixture: phase118_loop_nested_if_merge_min.hako (expected: 2)
|
||||||
|
- Pattern3 (if-sum) 活用
|
||||||
|
- Smoke: VM + LLVM EXE parity 検証済み
|
||||||
|
- Follow-up: Pattern3 carrier PHI contract(expected: 12)
|
||||||
|
- Fixture: phase118_pattern3_if_sum_min.hako
|
||||||
|
- Smoke: phase118_pattern3_if_sum_{vm,llvm_exe}.sh
|
||||||
|
- 回帰: Phase 117 維持確認
|
||||||
|
- 入口: `docs/development/current/main/phases/phase-118/README.md`
|
||||||
|
|
||||||
## 2025-12-18:Phase 117 完了 ✅
|
## 2025-12-18:Phase 117 完了 ✅
|
||||||
|
|
||||||
**Phase 117: if-only nested-if + call merge parity**
|
**Phase 117: if-only nested-if + call merge parity**
|
||||||
|
|||||||
@ -20,8 +20,8 @@ Related:
|
|||||||
- **制御の再帰合成(docs-only → dev-only段階投入)**
|
- **制御の再帰合成(docs-only → dev-only段階投入)**
|
||||||
- ねらい: `loop/if` ネストの “構造” を SSOT(ControlTree/StepTree)で表せるようにする
|
- ねらい: `loop/if` ネストの “構造” を SSOT(ControlTree/StepTree)で表せるようにする
|
||||||
- 注意: canonicalizer は観測/構造SSOTまで(ValueId/PHI配線は Normalized 側へ)
|
- 注意: canonicalizer は観測/構造SSOTまで(ValueId/PHI配線は Normalized 側へ)
|
||||||
- 現状: Phase 110–112 で StepTree(dev-only + strict guard)まで完了
|
- 現状: Phase 110–112(StepTree dev-only + strict guard)、Phase 117(if-only nested-if parity)、Phase 118(loop + if merge parity)まで完了
|
||||||
- 次候補(Phase 117): if-only の回帰をもう1本追加(nested if + call merge)→ VM/LLVM EXE parity で固定
|
- 次候補: StepTreeContract を “変換可能” な SSOT に寄せる(cond は AST 参照を保持、sig は派生にする)→ docs-only → dev-only で段階投入
|
||||||
- 入口: `docs/development/current/main/design/control-tree.md`
|
- 入口: `docs/development/current/main/design/control-tree.md`
|
||||||
|
|
||||||
## 中期(ループ在庫の残り)
|
## 中期(ループ在庫の残り)
|
||||||
|
|||||||
180
docs/development/current/main/phases/phase-118/README.md
Normal file
180
docs/development/current/main/phases/phase-118/README.md
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
# Phase 118: Loop + If-Only Merge Parity (VM + LLVM EXE)
|
||||||
|
|
||||||
|
## 目的
|
||||||
|
Phase 117で if-only nested-if + call merge が固まったので、Phase 118では "loop + if-only + merge" を固定する。loop側のPHI生成と if-only条件付き更新を組み合わせたパターンを確立し、VM + LLVM EXE の両方で動作保証する。
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
- **Phase 117**: if-only nested-if + call merge parity 確立(`phase117_if_only_nested_if_call_merge_min.hako`)
|
||||||
|
- **Phase 118**: loop + if-only merge の組み合わせテスト
|
||||||
|
- ループ内で if-only により条件付き変数更新
|
||||||
|
- Pattern3 (if-sum) の活用(既存実装を利用)
|
||||||
|
- ループ継続条件での PHI 生成
|
||||||
|
- Exit での merge 処理
|
||||||
|
|
||||||
|
## テストケース
|
||||||
|
|
||||||
|
### Fixture
|
||||||
|
**ファイル**: `apps/tests/phase118_loop_nested_if_merge_min.hako`
|
||||||
|
|
||||||
|
```hako
|
||||||
|
// Phase 118: loop + if-only merge parity test
|
||||||
|
// Expected output: 2 (numeric line)
|
||||||
|
// Calculation: i=0: x=0 (skip), i=1: x=0+1→1, i=2: x=1+1→2
|
||||||
|
|
||||||
|
static box Main {
|
||||||
|
main() {
|
||||||
|
local i = 0
|
||||||
|
local x = 0
|
||||||
|
loop(i < 3) {
|
||||||
|
if i > 0 {
|
||||||
|
x = x + 1
|
||||||
|
}
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
|
print(x)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**期待出力**: `2`(数値1行)
|
||||||
|
|
||||||
|
**計算ロジック**:
|
||||||
|
- `i=0`: `i > 0` は false、x は 0 のまま(skip)
|
||||||
|
- `i=1`: `i > 0` は true、`x = 0 + 1 → 1`(if ブランチ)
|
||||||
|
- `i=2`: `i > 0` は true、`x = 1 + 1 → 2`(if ブランチ)
|
||||||
|
- ループ終了後に `x` の値 `2` を出力
|
||||||
|
|
||||||
|
**Pattern3 活用**: このパターンは Pattern3 (if-sum) で既に対応済み。if-only で条件付き加算を行うパターンとして、既存実装を活用。
|
||||||
|
|
||||||
|
### スモークテスト
|
||||||
|
|
||||||
|
#### VM Smoke Test
|
||||||
|
**ファイル**: `tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_vm.sh`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
source "$SCRIPT_DIR/../../../lib/output_validator.sh"
|
||||||
|
|
||||||
|
FIXTURE="apps/tests/phase118_loop_nested_if_merge_min.hako"
|
||||||
|
|
||||||
|
echo "[phase118_loop_nested_if_merge_vm] Testing loop + if-else merge parity (VM)..."
|
||||||
|
|
||||||
|
# VM execution with STRICT mode
|
||||||
|
OUTPUT=$(NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1 ./target/release/hakorune --backend vm "$FIXTURE" 2>&1) || {
|
||||||
|
echo "❌ VM execution failed"
|
||||||
|
echo "$OUTPUT"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate: expect 1 line with value 2
|
||||||
|
validate_numeric_output 1 "2" "$OUTPUT"
|
||||||
|
|
||||||
|
echo "✅ [phase118_loop_nested_if_merge_vm] PASS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**実行条件**:
|
||||||
|
- `NYASH_DISABLE_PLUGINS=1`: プラグイン無効(core経路のみ)
|
||||||
|
- `HAKO_JOINIR_STRICT=1`: JoinIR STRICT モード有効
|
||||||
|
- `--backend vm`: Rust VM バックエンド
|
||||||
|
|
||||||
|
**検証**: `validate_numeric_output 1 "2" "$OUTPUT"`(1行、値2)
|
||||||
|
|
||||||
|
#### LLVM EXE Smoke Test
|
||||||
|
**ファイル**: `tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_llvm_exe.sh`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# Phase 118: loop + if-else merge parity (LLVM EXE)
|
||||||
|
|
||||||
|
source "$(dirname "$0")/../../../lib/test_runner.sh"
|
||||||
|
source "$(dirname "$0")/../../../lib/llvm_exe_runner.sh"
|
||||||
|
export SMOKES_USE_PYVM=0
|
||||||
|
require_env || exit 2
|
||||||
|
|
||||||
|
llvm_exe_preflight_or_skip || exit 0
|
||||||
|
|
||||||
|
# Phase 97/98/100 SSOT: plugin dlopen check → build only if needed → dlopen recheck.
|
||||||
|
FILEBOX_SO="$NYASH_ROOT/plugins/nyash-filebox-plugin/libnyash_filebox_plugin.so"
|
||||||
|
MAPBOX_SO="$NYASH_ROOT/plugins/nyash-map-plugin/libnyash_map_plugin.so"
|
||||||
|
STRINGBOX_SO="$NYASH_ROOT/plugins/nyash-string-plugin/libnyash_string_plugin.so"
|
||||||
|
CONSOLEBOX_SO="$NYASH_ROOT/plugins/nyash-console-plugin/libnyash_console_plugin.so"
|
||||||
|
INTEGERBOX_SO="$NYASH_ROOT/plugins/nyash-integer-plugin/libnyash_integer_plugin.so"
|
||||||
|
|
||||||
|
LLVM_REQUIRED_PLUGINS=(
|
||||||
|
"FileBox|$FILEBOX_SO|nyash-filebox-plugin"
|
||||||
|
"MapBox|$MAPBOX_SO|nyash-map-plugin"
|
||||||
|
"StringBox|$STRINGBOX_SO|nyash-string-plugin"
|
||||||
|
"ConsoleBox|$CONSOLEBOX_SO|nyash-console-plugin"
|
||||||
|
"IntegerBox|$INTEGERBOX_SO|nyash-integer-plugin"
|
||||||
|
)
|
||||||
|
LLVM_PLUGIN_BUILD_LOG="/tmp/phase118_loop_nested_if_merge_plugin_build.log"
|
||||||
|
llvm_exe_ensure_plugins_or_fail || exit 1
|
||||||
|
|
||||||
|
INPUT_HAKO="$NYASH_ROOT/apps/tests/phase118_loop_nested_if_merge_min.hako"
|
||||||
|
OUTPUT_EXE="$NYASH_ROOT/tmp/phase118_loop_nested_if_merge_llvm_exe"
|
||||||
|
|
||||||
|
EXPECTED='2'
|
||||||
|
EXPECTED_LINES=1
|
||||||
|
LLVM_BUILD_LOG="/tmp/phase118_loop_nested_if_merge_build.log"
|
||||||
|
if llvm_exe_build_and_run_numeric_smoke; then
|
||||||
|
test_pass "phase118_loop_nested_if_merge_llvm_exe: output matches expected (2)"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
**必要プラグイン**: FileBox, MapBox, StringBox, ConsoleBox, IntegerBox(Phase 117と同じセット)
|
||||||
|
|
||||||
|
**検証**: `llvm_exe_build_and_run_numeric_smoke`(EXPECTED='2', EXPECTED_LINES=1)
|
||||||
|
|
||||||
|
## 検証コマンド
|
||||||
|
|
||||||
|
### VM Smoke Test
|
||||||
|
```bash
|
||||||
|
bash tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_vm.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### LLVM EXE Smoke Test
|
||||||
|
```bash
|
||||||
|
bash tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_llvm_exe.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 回帰テスト(Phase 117)
|
||||||
|
```bash
|
||||||
|
bash tools/smokes/v2/profiles/integration/apps/phase117_if_only_nested_if_call_merge_llvm_exe.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 成果物
|
||||||
|
1. **Fixture**: `apps/tests/phase118_loop_nested_if_merge_min.hako`
|
||||||
|
2. **VM Smoke**: `tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_vm.sh`
|
||||||
|
3. **LLVM EXE Smoke**: `tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_llvm_exe.sh`
|
||||||
|
4. **ドキュメント**: `docs/development/current/main/phases/phase-118/README.md`(本ファイル)
|
||||||
|
|
||||||
|
## 追加(Phase 118 follow-up):Pattern3 carrier PHI contract 固定
|
||||||
|
|
||||||
|
Pattern3(if-sum)の exit carrier PHI が欠けると、後段で `Carrier '<name>' not found in carrier_phis` が発生する。
|
||||||
|
このフェーズでは fixture + VM/LLVM EXE smoke で再現と回帰固定を行い、さらに Fail-Fast の契約チェックを追加した。
|
||||||
|
|
||||||
|
### Fixture
|
||||||
|
- `apps/tests/phase118_pattern3_if_sum_min.hako`(期待: `12`)
|
||||||
|
|
||||||
|
### Smoke
|
||||||
|
- VM: `tools/smokes/v2/profiles/integration/apps/phase118_pattern3_if_sum_vm.sh`
|
||||||
|
- LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase118_pattern3_if_sum_llvm_exe.sh`
|
||||||
|
|
||||||
|
### 契約(SSOT)
|
||||||
|
- `exit_bindings` に含まれる `LoopState` carrier は、必ず exit PHI(`exit_carrier_phis`)を持つこと。
|
||||||
|
- 違反時は `[joinir/phase118/exit_phi/missing_carrier_phi] ... Hint: ...` で Fail-Fast。
|
||||||
|
|
||||||
|
## Phase 118 完了条件
|
||||||
|
- ✅ VM Smoke Test PASS
|
||||||
|
- ✅ LLVM EXE Smoke Test PASS
|
||||||
|
- ✅ Phase 117 回帰テスト PASS
|
||||||
|
- ✅ ドキュメント更新(10-Now.md, 01-JoinIR-Selfhost-INDEX.md)
|
||||||
|
|
||||||
|
## 次のステップ
|
||||||
|
Phase 119以降で更に複雑なループ + 制御フロー構造のテストケースを追加予定。
|
||||||
Reference in New Issue
Block a user