docs: Phase 123 plan (if-only normalized semantics)

This commit is contained in:
nyash-codex
2025-12-18 05:29:34 +09:00
parent bf7d3899b0
commit 51ed137339
3 changed files with 220 additions and 8 deletions

View File

@ -1,11 +1,12 @@
# Self Current Task — Now (main)
## Next: Phase 122(予定 / 実装中)
## Next: Phase 123(予定 / 実装中)
**Phase 122: StepTree→Normalizedif-only 実生成 / dev-only**
- Phase 121“contract-only shadow parity” まで完了。次は JoinModuleNormalized方言の実生成へ進め
- 既定挙動は不変(`joinir_dev_enabled()` のときだけ生成・検証、`joinir_strict_enabled()` で mismatch を Fail-Fast
- 入口(計画): `docs/development/current/main/phases/phase-122/README.md`
**Phase 123: if-only Normalized semanticsdev-only**
- Phase 122"JoinModule生成構造検証" まで完了。次は if-only を Normalized JoinModule として意味のある内容にす
- 対応ノード: Return(Integer literal), Return(Variable)禁止, If(cond_ast)最小Compare
- 既定挙動は不変(`joinir_dev_enabled()` のときだけ生成・検証、`joinir_strict_enabled()` で Fail-Fast
- 入口(計画): `docs/development/current/main/phases/phase-123/README.md`
## 2025-12-18Phase 121 完了 ✅

View File

@ -18,10 +18,10 @@ Related:
- 入口: `docs/development/current/main/phases/phase-94/README.md`
- **制御の再帰合成docs-only → dev-only段階投入**
- ねらい: `loop/if` ネストの 構造 を SSOTControlTree/StepTreeで表せるようにする
- ねらい: `loop/if` ネストの "構造" を SSOTControlTree/StepTreeで表せるようにする
- 注意: canonicalizer は観測/構造SSOTまでValueId/PHI配線は Normalized 側へ)
- 現状: Phase 119121StepTree cond SSOT / facts→contract / shadow parityまで完了
- 次候補Phase 122: if-only を StepTree→Normalized で実生成dev-onlyし、将来の dual-run の土台を作る
- 現状: Phase 119122StepTree cond SSOT / facts→contract / shadow parity / JoinModule生成)まで完了
- 次候補Phase 123: if-only を Normalized semantics で実装Return literal, If+Compare lowering
- 入口: `docs/development/current/main/design/control-tree.md`
## 中期(ループ在庫の残り)

View File

@ -0,0 +1,211 @@
# Phase 123: if-only Normalized Semantics (dev-only)
**Status**: In Progress
**Started**: 2025-12-18
**Scope**: if-only patterns with normalized semantics
## Goals
Phase 122 completed "JoinModule generation + structure validation". Phase 123 adds meaningful normalized semantics to if-only patterns.
## Scope
### In-Scope (Phase 123)
- **Return(Integer literal)**: `return 7``Const + Ret(Some(vid))`
- **Return(Variable)**: Fail-Fast with strict mode (needs reads facts - Phase 124)
- **If(cond_ast)**: Minimal Compare lowering (`flag == 1`, `i < 3`)
- Variable vs Integer literal comparisons only
- then/else: Return(Integer literal) only
- Merge: `join_k(env)` tail-call (no PHI)
### Out-of-Scope (Future Phases)
- **Return(Variable)**: Requires reads facts (Phase 124)
- **Complex conditions**: Compound expressions, &&/||, method calls
- **Loop/Break/Continue**: Capability insufficient (future)
## Design Principles
- **Box-First**: Modular separation of concerns
- **Fail-Fast**: No fallbacks, explicit errors with hints
- **SSOT**: No re-analysis of facts/contracts (use computed values only)
- **Dev-only**: Default behavior unchanged
- **Contract-based**: Use contract information, not AST inference
## Node Support (Phase 123)
### Return Nodes
#### Return(Integer literal) - P1
```
return 7
→ Const { dst: v1, value: Integer(7) }
→ Ret { value: Some(v1) }
```
#### Return(Variable) - P2 (Fail-Fast)
```
return x
→ freeze_with_hint(
"phase123/return/var_unsupported",
"Phase 123 only supports return with integer literals",
"Add reads fact (Phase 124) or return literal only"
)
```
### If Nodes - P3
#### Minimal Compare Support
```
if (flag == 1) {
return 2
} else {
return 3
}
→ Compare { ... }
→ Branch { ... }
→ Ret { ... } (in then block)
→ Ret { ... } (in else block)
→ join_k(env) (merge continuation)
```
**Supported comparisons**:
- `Variable == Integer`
- `Variable < Integer`
- `Variable > Integer`
- `Variable <= Integer`
- `Variable >= Integer`
- `Variable != Integer`
**Not supported** (cap_missing):
- Compound expressions: `a == 1 && b == 2`
- Method calls: `s.length() == 0`
- Complex expressions: `a + b == 5`
## Implementation Plan
### P0: docs-only (Plan & Scope)
**Docs**:
- `docs/development/current/main/phases/phase-123/README.md` (this file)
- Update `docs/development/current/main/10-Now.md`: Next: Phase 123
- Update `docs/development/current/main/30-Backlog.md`: Next candidate → Phase 123
**Commit**: `docs: Phase 123 plan (if-only normalized semantics)`
### P1: Return payload (Integer literal)
**Implementation**:
- `src/mir/control_tree/normalized_shadow/builder.rs`
- Return node → `JoinInst::Ret { value: Some(v) }`
- Literal(Integer) → `Const` + `Ret(Some(const_vid))`
- Other literals → strict `freeze_with_hint` ("Phase 123 integer only")
**Unit tests**:
- "return 7" generates `Const(Integer 7)` + `Ret(Some(...))`
**Commit**: `feat(control_tree): Phase 123 return integer literal in Normalized if-only`
### P2: Return payload (Variable) - Fail-Fast (A plan)
**Design Decision**:
- **A plan (recommended)**: Adopted
- Do not add "reads" to StepTreeFacts
- Phase 123 does not allow Return(Variable)
- To support Return(Variable), add reads facts in Phase 124
**Implementation**:
- `src/mir/control_tree/normalized_shadow/builder.rs`
- Return(Variable) → strict `freeze_with_hint(
"phase123/return/var_unsupported",
"Phase 123 only supports return with integer literals",
"Add reads fact (Phase 124) or return literal only"
)`
**Unit tests**:
- Verify strict mode fails with appropriate hint
**Commit**: `feat(control_tree): Phase 123 fail-fast on return variable (needs reads fact)`
### P3: If(cond_ast) minimal lowering
**Implementation**:
- `src/mir/control_tree/normalized_shadow/builder.rs`
- If node:
- Parse `cond_ast` as "minimal Compare"
- Generate JoinIR Compare instruction
- then/else: Return(Integer literal) only (other → strict freeze)
- Merge: `join_k(env)` tail-call (no PHI)
- Minimal parsing:
- `flag == 1` / `i < 3` (Variable vs Integer literal)
- Other (compound, &&/||, method call) → cap_missing strict freeze
**Unit tests**:
- If(true/false equivalent comparison) generates correct then/else structure
**Commit**: `feat(control_tree): Phase 123 if-only compare+return lowering (Normalized, dev-only)`
### P4: integration smoke (dev-only strict)
**Fixture**:
- `apps/tests/phase123_if_only_return_literal_min.hako` (output: 7)
**Smoke**:
- `tools/smokes/v2/profiles/integration/apps/phase123_if_only_normalized_semantics_vm.sh`
- Target: New fixture
- Dev+strict: `NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1`
- Output validation: `output_validator.sh`
**Commit**: `test(joinir): Phase 123 normalized semantics smoke (VM)`
### P5: docs completion
**Docs**:
- `docs/development/current/main/phases/phase-123/README.md`: Add DONE section
- `docs/development/current/main/10-Now.md`: Update to Phase 123 complete
- `docs/development/current/main/01-JoinIR-Selfhost-INDEX.md`: Add Phase 123
**Commit**: `docs: Phase 123 DONE`
## Verification Commands
```bash
# Unit tests
cargo test --lib
# Smoke tests
bash tools/smokes/v2/profiles/integration/apps/phase121_shadow_if_only_vm.sh
bash tools/smokes/v2/profiles/integration/apps/phase122_if_only_normalized_emit_vm.sh
bash tools/smokes/v2/profiles/integration/apps/phase118_loop_nested_if_merge_vm.sh
bash tools/smokes/v2/profiles/integration/apps/phase123_if_only_normalized_semantics_vm.sh
```
## Node Support Design
### Return(Integer literal)
- Direct lowering to Const + Ret
- Single responsibility: literal → instruction generation
### Return(Variable)
- Fail-Fast with structured error
- Clear migration path: Phase 124 reads facts
- No workarounds or fallbacks
### If(cond_ast) - Minimal Compare
- Parse only simple binary comparisons
- Variable on left, Integer literal on right
- Explicit scope: no compound/complex expressions
- Merge via continuation: `join_k(env)` tail-call
## Success Criteria
- [ ] P0: Docs complete, scope frozen
- [ ] P1: Return(Integer literal) working with unit tests
- [ ] P2: Return(Variable) fails fast with hint
- [ ] P3: If(minimal compare) generates correct JoinIR
- [ ] P4: Integration smoke passing
- [ ] P5: Docs updated, Phase 123 recorded as complete
## Progress
- **2025-12-18**: P0 started (docs-only planning)