diff --git a/docs/development/current/main/phases/phase-100/README.md b/docs/development/current/main/phases/phase-100/README.md index 30806ac0..d5af2f90 100644 --- a/docs/development/current/main/phases/phase-100/README.md +++ b/docs/development/current/main/phases/phase-100/README.md @@ -111,3 +111,34 @@ print(out.length()) # Output: 2 - **P2-4**: Integration test (fixture + smoke, length-based validation) **LLVM EXE parity**: P2 accumulator を LLVM EXE smoke でも固定(phase100_mutable_accumulator_llvm_exe.sh) + +## P3: String Accumulator (out = out + ch, Variable RHS only) + +**Constraint**: String accumulator は最小形のみサポート。 + +**Allowed form**: +- `out = out + ch` where ch ∈ {Variable (string-ish)} +- RHS must be Variable (not Literal, not MethodCall) + +**Fail-Fast (未対応)**: +- Literal RHS: `out = out + "x"` (P3.1 で解禁予定) +- MethodCall RHS: `out = out + substring(...)` (P3.2 で解禁予定) +- Non-string-ish RHS: 型判定は既存の box facts に委譲 + +**Example** (now works): +```hako +local out = "" +local s = "abc" +loop(i < 3) { + local ch = s.substring(i, i+1) # body-local string 1文字 + out = out + ch # String accumulator + print(out.length()) # Output: 1, 2, 3 + i = i + 1 +} +``` + +**Implementation**: +- **P3-1**: AccumulatorKind::{Int, String} 追加(型判定は委譲) +- **P3-2**: StringAccumulatorEmitter 専用箱(JoinIR lowering) +- **P3-3**: Pattern2 wiring(string carrier 昇格、emitter 分岐) +- **P3-4**: Fixture + smokes(VM + LLVM EXE)