From af2a5e27d625b8d3e961cd5aa5139525a47839b3 Mon Sep 17 00:00:00 2001 From: tomoaki Date: Fri, 19 Dec 2025 05:42:11 +0900 Subject: [PATCH] feat(normalization): Phase 142 P1 - LLVM EXE parity for loop normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 142-loopstmt P1: LLVM EXE smoke test for statement-level loop normalization - Added: tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh - Verification: Exit code 3 parity with VM test - Status: ✅ PASS (exit code 3, string length computed correctly) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 --- docs/development/current/main/10-Now.md | 1 - docs/development/current/main/30-Backlog.md | 8 ---- .../development/current/main/phases/README.md | 2 +- .../main/phases/phase-142-loopstmt/README.md | 19 +++++---- .../control_tree/normalized_shadow/builder.rs | 2 +- ...mt_only_then_return_length_min_llvm_exe.sh | 42 +++++++++++++++++++ 6 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 769897c6..f503618b 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -2,7 +2,6 @@ ## Next (planned) -- Phase 142-loopstmt P1: LLVM EXE smoke test 追加(Phase 130 完了後) - Phase 141 P2+: Call/MethodCall 対応(effects + typing を分離して段階投入) - Phase 143-loopvocab: StepTree の語彙拡張(loop 内 if/break/continue を「新パターン追加」ではなく「語彙追加」で吸収) - 詳細: `docs/development/current/main/30-Backlog.md` diff --git a/docs/development/current/main/30-Backlog.md b/docs/development/current/main/30-Backlog.md index db9a0ab1..71c5d3b1 100644 --- a/docs/development/current/main/30-Backlog.md +++ b/docs/development/current/main/30-Backlog.md @@ -8,14 +8,6 @@ Related: ## 直近(JoinIR/selfhost) -- **Phase 142-loopstmt P1(planned): LLVM EXE smoke を追加** - - 前提(DONE): Phase 142-loopstmt P0(正規化単位を statement(loop 1個)へ寄せる) - - ねらい: VM で固定済みの fixture を LLVM EXE でも parity 固定する。 - - 受け入れ条件: - - 既存 fixture をそのまま使う(新パターン追加をしない) - - out-of-scope は `Ok(None)` でフォールバック(既定挙動不変) - - Phase 130 の LLVM EXE gate が前提(未完なら SKIP を維持) - - **Phase 141 P2+(planned): Call/MethodCall(effects + typing を分離して段階投入)** - ねらい: pure/impure 境界を壊さずに、impure lowering を段階投入する。 - 前提(DONE): diff --git a/docs/development/current/main/phases/README.md b/docs/development/current/main/phases/README.md index 17b8c9d5..9ed2eb1d 100644 --- a/docs/development/current/main/phases/README.md +++ b/docs/development/current/main/phases/README.md @@ -11,7 +11,7 @@ - **Phase 141 P1.5(DONE)**: known intrinsic registry + available_inputs 3-source merge + diagnostics - **Phase 141 P2+(planned)**: Call/MethodCall 対応(effects + typing の段階投入) - **Phase 142-loopstmt P0(DONE)**: 正規化単位を statement(loop 1個)へ寄せる(パターン爆発を止める) -- **Phase 142-loopstmt P1(planned)**: LLVM EXE smoke(同 fixture)を追加 +- **Phase 142-loopstmt P1(DONE)**: LLVM EXE smoke(同 fixture)を追加 - **Phase 143-loopvocab(planned)**: StepTree の語彙拡張(loop 内 if/break/continue を「語彙追加」で吸収) - **Phase 91–92**: Selfhost depth‑2 coverage(P5b escape recognition → lowering) - **Phase 94–100**: P5b escape E2E / Trim policy / pinned + accumulator(VM/LLVM EXE parity) diff --git a/docs/development/current/main/phases/phase-142-loopstmt/README.md b/docs/development/current/main/phases/phase-142-loopstmt/README.md index 5fa6fb3b..5d6ab7f2 100644 --- a/docs/development/current/main/phases/phase-142-loopstmt/README.md +++ b/docs/development/current/main/phases/phase-142-loopstmt/README.md @@ -163,7 +163,14 @@ bash tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_retu **File**: `tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh` -**Status**: ⚠️ TODO in P1 (requires Phase 130 LLVM EXE gate complete) +**Status**: ✅ P1 COMPLETE (LLVM EXE parity achieved) + +**Command**: +```bash +bash tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh +``` + +**Result**: ✅ PASS (exit code 3, parity with VM) --- @@ -305,13 +312,11 @@ bash tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_retu ## Next Steps -### P1: LLVM EXE Smoke Test (TODO) +### P1: LLVM EXE Smoke Test (DONE ✅) -**File**: `tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh` - -**Prerequisites**: Phase 130 LLVM EXE gate complete - -**Expected**: exit code 3 parity with VM +- File: `tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh` +- Gate: `llvm_exe_preflight_or_skip` により、Phase 130 の LLVM EXE 前提が満たされない環境では SKIP を維持 +- Contract: exit code 3 parity with VM ### P2: Code Contract Enforcement (Planned) diff --git a/src/mir/control_tree/normalized_shadow/builder.rs b/src/mir/control_tree/normalized_shadow/builder.rs index aacef7f6..3a136f76 100644 --- a/src/mir/control_tree/normalized_shadow/builder.rs +++ b/src/mir/control_tree/normalized_shadow/builder.rs @@ -93,7 +93,7 @@ impl StepTreeNormalizedShadowLowererBox { // Phase 126: EnvLayout 生成(available_inputs を使用) let env_layout = EnvLayout::from_contract(&step_tree.contract, available_inputs); - // Phase 131: loop(true) break-once pattern + // Phase 131: loop(true) break-once pattern (simpler, higher priority) if let Some((module, meta)) = LoopTrueBreakOnceBuilderBox::lower(step_tree, &env_layout)? { return Ok(Some((module, meta))); } diff --git a/tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh b/tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh new file mode 100644 index 00000000..1ad8e57f --- /dev/null +++ b/tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Phase 142 P0: Loop normalization as single statement (LLVM EXE parity) +# +# Verifies that loop(true) normalization returns consumed=1, allowing +# subsequent statements (return s.length()) to be processed normally. +# Expected: exit code 3 (s="abc" → s.length() → 3) +# +# Dev-only: NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1 + +source "$(dirname "$0")/../../../lib/test_runner.sh" +source "$(dirname "$0")/../../../lib/llvm_exe_runner.sh" +export SMOKES_USE_PYVM=0 +require_env || exit 2 + +# Preflight check (SKIP gate) +llvm_exe_preflight_or_skip || exit 0 + +# JoinIR dev mode (Phase 130+ gate) +require_joinir_dev + +# Minimal plugins (String + Integer for s.length()) +STRINGBOX_SO="$NYASH_ROOT/plugins/nyash-string-plugin/libnyash_string_plugin.so" +INTEGERBOX_SO="$NYASH_ROOT/plugins/nyash-integer-plugin/libnyash_integer_plugin.so" +LLVM_REQUIRED_PLUGINS=( + "StringBox|$STRINGBOX_SO|nyash-string-plugin" + "IntegerBox|$INTEGERBOX_SO|nyash-integer-plugin" +) +LLVM_PLUGIN_BUILD_LOG="/tmp/phase142_loop_stmt_llvm_plugin_build.log" +llvm_exe_ensure_plugins_or_fail || exit 1 + +# Test configuration +INPUT_HAKO="$NYASH_ROOT/apps/tests/phase142_loop_stmt_only_then_return_length_min.hako" +OUTPUT_EXE="$NYASH_ROOT/tmp/phase142_loop_stmt_only_then_return_length_min_llvm_exe" + +# Execute (exit code contract) +EXPECTED_EXIT_CODE=3 +LLVM_BUILD_LOG="/tmp/phase142_loop_stmt_llvm_build.log" +if llvm_exe_build_and_run_expect_exit_code; then + test_pass "phase142_loop_stmt_llvm_exe: exit code matches (3)" +else + exit 1 +fi