docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)

This commit is contained in:
nyash-codex
2025-10-31 18:00:10 +09:00
parent 1d49e24bf0
commit 8fd3a2b509
433 changed files with 108935 additions and 0 deletions

View File

@ -0,0 +1,353 @@
# @enum Architecture Summary (Quick Reference)
**For**: Developers who want the TL;DR version
**See Also**: [enum-module-architecture.md](enum-module-architecture.md) (complete design)
---
## File Map (What Goes Where)
```
┌─────────────────────────────────────────────────────────────────┐
│ @enum Implementation │
│ File Organization │
└─────────────────────────────────────────────────────────────────┘
📁 src/
├── 📄 ast.rs [MODIFY +80 lines]
│ └── Add: EnumDeclaration, EnumVariant, EnumField structs
├── 📁 parser/
│ ├── 📄 mod.rs [MODIFY +10 lines]
│ │ └── Integrate enum parsing in parse_statement()
│ └── 📁 declarations/
│ ├── 📄 mod.rs [MODIFY +1 line]
│ │ └── Export enum_parser module
│ └── 📄 enum_parser.rs [NEW ~200 lines] ⭐
│ └── parse_enum_declaration()
└── 📁 macro/
├── 📄 mod.rs [MODIFY +1 line]
│ └── Export enum_expander module
├── 📄 engine.rs [MODIFY +15 lines]
│ └── Call enum_expander::expand_enum()
└── 📄 enum_expander.rs [NEW ~300 lines] ⭐
├── expand_enum()
├── generate_box_declaration()
└── generate_static_box()
📁 apps/
└── 📁 tests/
└── 📁 enum/ [NEW directory] ⭐
├── 📄 test_enum_basic.hako [NEW ~40 lines]
├── 📄 test_enum_option.hako [NEW ~30 lines]
└── 📄 test_enum_multi.hako [NEW ~50 lines]
📁 docs/
├── 📁 reference/language/
│ └── 📄 enum-syntax.md [NEW ~300 lines] ⭐
│ └── User guide for @enum
└── 📁 development/roadmap/phases/phase-19-enum-match/
├── 📄 enum-module-architecture.md [THIS DOC] ⭐
├── 📄 IMPLEMENTATION_CHECKLIST.md [CHECKLIST] ⭐
└── 📄 enum-implementation-notes.md [NEW ~200 lines] ⭐
└── Developer implementation notes
```
---
## Data Flow (Pipeline)
```
┌──────────────────────────────────────────────────────────────────────┐
│ @enum Processing Pipeline │
└──────────────────────────────────────────────────────────────────────┘
Source Code:
@enum Result { Ok(value: T), Err(error: E) }
┌─────────────────┐
│ Tokenizer │ (existing)
└─────────────────┘
│ Token Stream: [@, enum, Result, {, Ok, (, value, :, T, ), ...]
┌─────────────────┐
│ Parser │ src/parser/declarations/enum_parser.rs (NEW)
│ enum_parser.rs │ ← parse_enum_declaration()
└─────────────────┘
│ EnumDeclaration AST
┌─────────────────┐
│ AST Structs │ src/ast.rs (MODIFY)
│ ast.rs │ ← EnumDeclaration, EnumVariant, EnumField
└─────────────────┘
│ EnumDeclaration AST
┌─────────────────┐
│ Macro Engine │ src/macro/engine.rs (MODIFY)
│ engine.rs │ ← Call enum_expander::expand_enum()
└─────────────────┘
┌─────────────────┐
│ Enum Expander │ src/macro/enum_expander.rs (NEW)
│ enum_expander.rs│ ← expand_enum()
└─────────────────┘
│ Vec<ASTNode> [BoxDeclaration, StaticBoxDeclaration]
┌─────────────────────────────────────────────────────────────────┐
│ Generated AST: │
│ │
│ box ResultBox<T, E> { │
│ variant: StringBox │
│ ok_value: T │
│ err_error: E │
│ birth(variant, ok_value, err_error) { ... } │
│ is_ok() { return me.variant == "Ok" } │
│ is_err() { return me.variant == "Err" } │
│ } │
│ │
│ static box Result { │
│ Ok(value) { return new ResultBox("Ok", value, null) } │
│ Err(error) { return new ResultBox("Err", null, error) } │
│ } │
└─────────────────────────────────────────────────────────────────┘
│ BoxDeclaration + StaticBoxDeclaration AST
┌─────────────────┐
│ MIR Builder │ (existing)
└─────────────────┘
│ MIR
┌─────────────────┐
│ Backend │ (existing)
│ VM/LLVM/WASM │
└─────────────────┘
Executable
```
---
## Module Dependencies (No Cycles)
```
┌─────────────────────────────────────────────────────────────┐
│ Dependency Graph │
│ (Linear Flow) │
└─────────────────────────────────────────────────────────────┘
tokenizer.rs
enum_parser.rs ──depends on──> ast.rs (EnumDeclaration structs)
ast.rs
enum_expander.rs ──depends on──> ast.rs (BoxDeclaration structs)
engine.rs ──depends on──> enum_expander.rs
parser/mod.rs (integration)
MIR builder (existing)
✅ No circular dependencies
✅ Clear data flow
✅ Easy to test each layer independently
```
---
## Naming Conventions (Quick Reference)
| Item | Pattern | Example |
|------|---------|---------|
| **Files** | `snake_case.rs` | `enum_parser.rs`, `enum_expander.rs` |
| **AST structs** | `CamelCase` | `EnumDeclaration`, `EnumVariant`, `EnumField` |
| **Functions** | `verb_noun()` | `parse_enum_declaration()`, `expand_enum()` |
| **Tests** | `test_*.hako` | `test_enum_basic.hako` |
| **Input syntax** | `@enum Name` | `@enum Result`, `@enum Option` |
| **Generated box** | `{Name}Box<T>` | `ResultBox<T, E>`, `OptionBox<T>` |
| **Generated static** | `{Name}` | `Result`, `Option` |
| **Variant fields** | `{variant}_{field}` | `ok_value`, `err_error` |
| **Query methods** | `is_{variant}()` | `is_ok()`, `is_err()` |
---
## Test Organization (3 Layers)
```
┌─────────────────────────────────────────────────────────────────┐
│ Test Strategy │
└─────────────────────────────────────────────────────────────────┘
Layer 1: Parser Unit Tests (Rust)
📁 src/parser/declarations/enum_parser.rs
└── #[cfg(test)] mod tests {
✓ test_parse_two_variant_enum()
✓ test_parse_zero_field_variant()
✓ test_duplicate_variant_error()
}
Run: cargo test --lib enum_parser::tests
Layer 2: Expander Unit Tests (Rust)
📁 src/macro/enum_expander.rs
└── #[cfg(test)] mod tests {
✓ test_expand_result_enum()
✓ test_generated_box_fields()
✓ test_generated_is_methods()
}
Run: cargo test --lib enum_expander::tests
Layer 3: Integration Tests (Hakorune)
📁 apps/tests/enum/
├── test_enum_basic.hako ← Result-like (Ok/Err)
├── test_enum_option.hako ← Option-like (Some/None)
└── test_enum_multi.hako ← 3+ variants
Run: ./target/release/hako apps/tests/enum/*.hako
```
---
## Timeline (3 Days + 1 Buffer)
```
┌─────────────────────────────────────────────────────────────────┐
│ Implementation Timeline │
└─────────────────────────────────────────────────────────────────┘
Day 1: Parser + AST (Foundation) ⏰ 8 hours
✓ Add AST structs (EnumDeclaration, EnumVariant, EnumField)
✓ Create enum_parser.rs
✓ Implement parse_enum_declaration()
✓ Add tokenizer support for @enum
✓ Write parser unit tests
✓ Integration: Export from mod.rs
Output: Can parse @enum syntax into AST ✅
Day 2: Macro Expander (Code Generation) ⏰ 8 hours
✓ Create enum_expander.rs
✓ Implement expand_enum()
✓ Implement generate_box_declaration()
✓ Implement generate_static_box()
✓ Write expander unit tests
✓ Integration: Call from engine.rs
Output: Can transform enum AST → box AST ✅
Day 3: Integration Tests + Documentation ⏰ 8 hours
✓ Create apps/tests/enum/ directory
✓ Write test_enum_basic.hako (Result-like)
✓ Write test_enum_option.hako (Option-like)
✓ Write test_enum_multi.hako (3+ variants)
✓ Write enum-syntax.md (user guide)
✓ Write enum-implementation-notes.md (dev notes)
Output: Full pipeline working + documented ✅
Day 4: Polish + Edge Cases (Buffer) ⏰ 4-8 hours
✓ Error handling (duplicate variants, invalid names)
✓ Edge cases (zero-field variants, single variant)
✓ Code review and refactoring
✓ Clippy and fmt fixes
Output: Production-ready code ✅
```
---
## Success Criteria (Checklist)
- [ ]**Parser**: Can parse `@enum Result { Ok(value: T), Err(error: E) }`
- [ ]**AST**: EnumDeclaration nodes correctly constructed
- [ ]**Expander**: Generates BoxDeclaration + StaticBoxDeclaration
- [ ]**Generated Code**: Valid Hakorune syntax
- [ ]**Tests**: All integration tests pass
- [ ]**Docs**: User guide and developer notes complete
- [ ]**Errors**: Helpful error messages for common mistakes
- [ ]**Edge Cases**: Zero-field variants, single variant, many variants
- [ ]**No Regressions**: Existing tests still pass
---
## Quick Commands (Copy-Paste Ready)
```bash
# Day 1: Build and test parser
cargo build
cargo test --lib enum_parser::tests
# Day 2: Build and test expander
cargo build
cargo test --lib enum_expander::tests
# Day 3: Run integration tests
./target/release/hako apps/tests/enum/test_enum_basic.hako
./target/release/hako apps/tests/enum/test_enum_option.hako
./target/release/hako apps/tests/enum/test_enum_multi.hako
# Day 4: Code quality checks
cargo clippy
cargo fmt
cargo test
# All enum tests at once
for test in apps/tests/enum/*.hako; do
echo "Running $test..."
./target/release/hako "$test" || echo "FAILED: $test"
done
```
---
## Key Design Principles
1. **Separation of Concerns**: Parser → AST → Expander → Engine (clear boundaries)
2. **Testability**: 3-layer testing (parser unit, expander unit, integration)
3. **Follows Existing Patterns**: Consistent with box_definition.rs style
4. **Minimal Changes**: Only 5 files modified + 8 files created
5. **Future-Proof**: Easy to extend for match expressions (Phase 19.2)
---
## FAQ (Quick Answers)
**Q: Where do I start?**
A: Read [IMPLEMENTATION_CHECKLIST.md](IMPLEMENTATION_CHECKLIST.md) and start Day 1
**Q: What if I get stuck?**
A: Check [enum-module-architecture.md](enum-module-architecture.md) for detailed design
**Q: How do I run tests?**
A: See "Quick Commands" section above
**Q: What about match expressions?**
A: Phase 19.2 (future work) - hooks are in place for easy integration
**Q: Will this break existing code?**
A: No - all changes are additive, no existing functionality modified
**Q: How do I generate documentation?**
A: `cargo doc --open` for Rust docs, markdown files for user docs
---
## Next Steps
1. ✅ Review this summary
2. ✅ Read [IMPLEMENTATION_CHECKLIST.md](IMPLEMENTATION_CHECKLIST.md)
3. ✅ Start Day 1: Parser + AST
4. ✅ Follow checklist day by day
5. ✅ Celebrate when done! 🎉
---
**Document Version**: 1.0
**Last Updated**: 2025-10-08
**Status**: Ready for Implementation ✅

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,678 @@
# Phase 19: @enum/@match Macro Implementation (Choice A'')
**Status**: CURRENT (2025-10-08)
**Timeline**: 9-14 days (2-3 weeks)
**Approach**: Choice A'' (Macro-Only) - NO VariantBox Core
**Progress**: Day 4/14 (29% complete) ✅ Week 1 blocked on VM bug
---
## 🎯 Overview
Implement pattern matching for Hakorune selfhost compiler using **macro-only approach**.
**Strategic Context**:
- **Choice A'' (Macro-Only)**: Best of both worlds
- **Timeline**: 9-14 days (vs 28-42 days for full implementation)
- **Quality Target**: "ガチガチ大作戦" (rock-solid)
- **User's Intent**: Avoid "中途半端" (half-baked implementation)
**Current Status** (2025-10-08):
- ✅ Day 1: Parser extension (COMPLETED)
- ✅ Day 2: Macro expansion (COMPLETED)
- ✅ Day 3: Test coverage expansion (COMPLETED - 10/10 tests PASS)
- ✅ Day 4: Investigation (COMPLETED - VM bug identified, NOT macro bug)
- ⏸️ Day 5: BLOCKED on VM equals() bug fix
---
## 📋 Scope
### ✅ In Scope
1. **@enum マクロ** (Week 1)
- Auto-generate constructors + helper functions
- Syntax: `@enum Result { Ok(value) Err(error) }`
- Output: Static box with constructors + `is_*()` + `unwrap_*()` methods
- Internal: Use existing Box types + `_tag` field
2. **@match マクロ** (Week 2-3)
- Pattern matching syntax
- Syntax: `@match result { Ok(v) => ... Err(e) => ... }`
- Desugar to: if-else chains
- Runtime exhaustiveness check (panic on unknown tag)
3. **Option/Result Rewrite**
- Rewrite existing Option/Result with @enum
- Backward compatibility maintained
- Migration guide for selfhost code
4. **Mini-VM Integration**
- Apply @match to 3-5 Mini-VM files
- Replace null checks with @match Option
- Replace error codes with @match Result
### ❌ Out of Scope (Phase 20+)
- VariantBox Core implementation
- EnumSchemaBox
- SymbolBox (tag optimization)
- Compile-time exhaustiveness checking
- Advanced patterns (guards, literals, nested patterns)
---
## 🏗️ Implementation Plan
### Week 1: @enum Macro (4-5 days)
#### Day 1: Parser Extension ✅ COMPLETED (2025-10-08)
**Goal**: @enum syntax parsing works
**Status**: ✅ All tests passing
**Deliverables**:
- ✅ TokenType::AT added to tokenizer
- ✅ EnumVariant struct + ASTNode::EnumDeclaration
- ✅ enum_parser.rs (150 lines, clean modular design)
- ✅ Integration with parse_declaration_statement()
- ✅ Test execution successful (@enum Result/Option)
**Files Modified**:
- `src/tokenizer/kinds.rs` - AT token
- `src/tokenizer/engine.rs` - @ character recognition
- `src/ast.rs` - EnumVariant struct + EnumDeclaration variant
- `src/ast/utils.rs` - Pattern matching (4 locations)
- `src/parser/declarations/enum_parser.rs` - NEW (150 lines)
- `src/parser/declarations/mod.rs` - Module export
- `src/parser/statements/declarations.rs` - @ dispatch
- `src/parser/statements/mod.rs` - TokenType::AT recognition
**Test Results**:
- ✅ cargo check: PASS
- ✅ cargo build --release: PASS
- ✅ Runtime test: @enum Result/Option parses correctly
**AST Structure Implemented**:
```rust
pub enum ASTNode {
// ...
EnumDeclaration {
name: String,
variants: Vec<EnumVariant>,
}
}
pub struct EnumVariant {
name: String,
fields: Vec<String>, // field names
}
```
**Example Syntax Working**:
```hakorune
@enum Result {
Ok(value)
Err(error)
}
@enum Option {
Some(value)
None
}
```
#### Day 2: Macro Expansion ✅ COMPLETED (2025-10-08)
**Goal**: EnumDeclaration → Box + Static Box generation
**Status**: ✅ All tests passing
**File**: `src/macro/engine.rs` (+323 lines)
**Deliverables**:
- ✅ Program flat_map support for multi-node expansion
- ✅ expand_enum_to_boxes() main expansion function
- ✅ build_enum_birth_method() - null field initialization
- ✅ build_enum_is_method() - is_Ok()/is_Err() predicates
- ✅ build_enum_as_method() - as_Ok()/as_Err() extractors
- ✅ build_enum_constructor() - Ok(v)/Err(e)/None() constructors
- ✅ Integration with MacroEngine::expand_node()
- ✅ Smoke test suite (5/5 tests PASS)
**Test Results**:
- ✅ cargo build --release: PASS
- ✅ Manual test: Result.Ok/Err - PASS
- ✅ Manual test: Option.Some/None (zero-field) - PASS
- ✅ Smoke test: enum_macro_basic.sh (5/5) - PASS
**Actual Time**: ~4 hours
**Desugaring Example**:
```hakorune
// Input
@enum Result {
Ok(value)
Err(error)
}
// Output
static box Result {
// Constructors
Ok(v) {
local r = new ResultBox()
r._tag = "Ok"
r._value = v
return r
}
Err(e) {
local r = new ResultBox()
r._tag = "Err"
r._error = e
return r
}
// Helpers
is_ok(r) { return r._tag == "Ok" }
is_err(r) { return r._tag == "Err" }
unwrap_ok(r) {
if r._tag != "Ok" {
panic("unwrap_ok called on Err")
}
return r._value
}
unwrap_err(r) {
if r._tag != "Err" {
panic("unwrap_err called on Ok")
}
return r._error
}
}
```
#### Day 3: Test Coverage Expansion ✅ COMPLETED (2025-10-08)
**Goal**: Expand test coverage from 5 to 10 patterns
**Status**: ✅ All tests passing
**Files Modified**:
- `tools/smokes/v2/profiles/quick/selfhost/enum_macro_basic.sh` (+133 lines)
**Test Patterns Completed**:
1-5. Basic tests (from Day 2)
6. Multi-field variant (3+ fields)
7. String-heavy variants
8. Tag comparison (is_* with multiple variants)
9. toString() representation
10. Single variant edge case
**Results**:
- ✅ 10/10 tests PASS
- ✅ enum_macro_basic.sh smoke test fully functional
- ⚠️ equals() issue discovered (see Day 4)
**Actual Time**: ~1 hour
#### Day 4: Investigation - equals() Stack Overflow ✅ COMPLETED (2025-10-08)
**Goal**: Fix equals() stack overflow issue
**Status**: ✅ Root cause identified + Solution confirmed - NOT an @enum macro bug
**Investigation Process**:
1. Created minimal test case without @enum → Same crash
2. Implemented manual equals() → Method never called
3. Traced to VM layer → eq_vm() infinite recursion
4. ChatGPT Code: 3 VM-level fix attempts → All failed
5. ChatGPT Pro: Root cause analysis + MIR-level solution → Correct approach
**Key Findings**:
- **Root Cause**: `operator_guard_intercept_entry()` calls `eval_cmp()` before fn context update
- **Bug Type**: Architectural issue - operator guard intercepts ALL boxcalls
- **Scope**: ALL Box types (not @enum-specific)
- **Evidence**: Simple box without @enum crashes identically
**Test Evidence**:
```hakorune
// Test 1: Simple box (no @enum) - CRASHES
box SimpleBox { value }
local s1 = new SimpleBox()
local s2 = new SimpleBox()
s1.value = 42
s2.value = 42
if s1.equals(s2) { } // STACK OVERFLOW
// Test 2: Manual equals() - CRASHES BEFORE METHOD ENTRY
box SimpleBox {
value
equals(other) {
print("Never printed") // Method never called
return me.value == other.value
}
}
```
### Resolution Path
**Three Failed Attempts** (ChatGPT Code):
1. VM-level fix in `eq_vm()` - Reference equality check
2. VM-level fix v2 - Improved dispatch logic
3. VM-level fix v3 - Method lookup optimization
**Result**: All still caused stack overflow
**Why VM fixes failed**: Operator guard is architectural - intercepts ALL boxcalls for operator checking. VM-level fix would break operator semantics or require complex recursion detection.
**Correct Solution** (ChatGPT Pro): MIR-level transformation
**Approach**: Lower `equals()` calls to `op_eq()` runtime function
```
// Before (high-level MIR)
boxcall recv=v%1 method="equals" args=[v%2] dst=v%3
// After (lowered MIR)
externcall interface="nyrt.ops" method="op_eq" args=[v%1, v%2] dst=v%3
```
**Why this is correct**:
- Separates comparison semantics from method dispatch
- Works for VM, LLVM, and WASM backends
- No VM changes needed (operator guard stays intact)
- Follows existing pattern (`op_to_string`, `op_hash`)
**Implementation Plan** (4 phases, 8-12 hours):
1. Runtime function (1-2h): Add `op_eq()` to extern registry
2. MIR lowering (2-3h): Transform `boxcall equals``externcall op_eq`
3. LLVM/WASM support (3-4h): Implement in all backends
4. Integration testing (2-3h): Full @enum test suite
**Conclusion**:
-@enum macro implementation is CORRECT
- ✅ Bug is in VM operator guard architecture
- ✅ Solution identified: MIR-level lowering (correct architectural fix)
- 📋 Detailed issue doc: `docs/development/issues/equals-stack-overflow.md`
**Timeline Update**:
- Day 4: Investigation complete (2 hours)
- Day 4-5: Implement fix (8-12 hours estimated)
- Day 6: Integration testing (originally Day 5)
**Actual Time**: ~2 hours investigation + 8-12 hours implementation (in progress)
#### Day 5: Selfhost Integration ⏸️ BLOCKED
**Blocking Issue**: VM equals() bug must be fixed first
**Status**: Waiting for VM fix
**Planned Tasks** (when unblocked):
- [ ] Option/Result defined with @enum
- [ ] Full integration test suite
- [ ] Backward compatibility verification
---
### Week 2-3: @match Macro (5-9 days)
#### Day 1-3: Parser Extension (Rust)
**File**: `src/parser/mod.rs`
**Tasks**:
- [ ] Add `@match` syntax parsing
- [ ] Parse pattern syntax: `Tag(bindings)`
- [ ] Create AST node: `ASTNode::MatchExpression`
**AST Structure**:
```rust
pub enum ASTNode {
// ...
MatchExpression {
scrutinee: Box<ASTNode>,
arms: Vec<MatchArm>,
}
}
pub struct MatchArm {
pattern: Pattern,
body: Box<ASTNode>,
}
pub enum Pattern {
Variant {
tag: String,
bindings: Vec<String>,
}
}
```
**Example**:
```hakorune
@match result {
Ok(value) => console.log(value)
Err(error) => console.error(error)
}
```
#### Day 4-7: Macro Engine (Hakorune)
**File**: `apps/macros/match/match_macro.hako`
**Tasks**:
- [ ] Implement @match desugaring
- [ ] Generate if-else chains
- [ ] Add runtime exhaustiveness check
**Desugaring Example**:
```hakorune
// Input
@match result {
Ok(value) => {
console.log("Success: " + value)
return value
}
Err(error) => {
console.error("Error: " + error)
return null
}
}
// Output
local __match_scrutinee = result
if __match_scrutinee._tag == "Ok" {
local value = __match_scrutinee._value
console.log("Success: " + value)
return value
} else if __match_scrutinee._tag == "Err" {
local error = __match_scrutinee._error
console.error("Error: " + error)
return null
} else {
panic("Non-exhaustive match: unknown tag '" + __match_scrutinee._tag + "'")
}
```
#### Day 8-9: Integration Testing
**Files**:
- `apps/tests/match_patterns.hako` (15 test patterns)
- `selfhost/vm/boxes/*_with_match.hako` (3-5 files)
**Test Patterns**:
1. Simple 2-arm match
2. Multi-arm match (3+ arms)
3. Match with bindings
4. Match with multiple bindings
5. Match with zero-field variant
6. Match with return in arms
7. Match with early return
8. Nested match expressions
9. Match in loop
10. Match in if condition
11. Option pattern matching
12. Result pattern matching
13. Custom enum pattern matching
14. Non-exhaustive match (should panic)
15. All arms covered (no panic)
**Mini-VM Integration**:
- [ ] Rewrite `mini_vm_core.hako` error handling with @match
- [ ] Rewrite `instruction_scanner.hako` null checks with @match
- [ ] Rewrite `op_handlers.hako` result handling with @match
**Success Criteria**:
- [ ] 15/15 tests PASS
- [ ] 3-5 Mini-VM files successfully migrated
- [ ] No manual `if box.is_tag()` in migrated files
- [ ] No null checks in migrated files
- [ ] No error codes (-1/-2/0) in migrated files
---
## ✅ Success Criteria
### Phase 19 Complete = ALL of the following
1. **@enum Macro Functional**
- [ ] 10/10 @enum tests PASS
- [ ] Option/Result defined with @enum
- [ ] Constructors auto-generated
- [ ] Helpers auto-generated
2. **@match Macro Functional**
- [ ] 15/15 @match tests PASS
- [ ] Correct desugaring to if-else
- [ ] Runtime exhaustiveness check works
- [ ] Panic on non-exhaustive match
3. **Selfhost Code Application**
- [ ] 3-5 Mini-VM files migrated to @match
- [ ] null checks → @match Option
- [ ] error codes → @match Result
- [ ] NO manual tag checking (`if box.is_tag()`)
4. **Smoke Tests**
- [ ] Quick profile ALL PASS
- [ ] Integration profile ALL PASS
- [ ] No performance regression
5. **Documentation**
- [ ] @enum/@match user guide
- [ ] Migration guide (null → Option, -1/-2 → Result)
- [ ] Phase 20 migration plan (VariantBox Core)
---
## 🚨 Risks and Mitigation
### 🔴 Critical Risks
1. **@syntax Parser Extension Complexity**
- Impact: High (Rust parser extension could be difficult)
- Probability: Medium (Phase 16 has @derive experience)
- Mitigation:
- Analyze Phase 16 @derive implementation in detail
- Start with simple syntax, iterate
- Fallback: Use `enum!()` macro syntax instead of `@enum`
2. **Macro Expansion Complexity**
- Impact: High (bugs in desugared code)
- Probability: Medium (200-350 lines of macro code)
- Mitigation:
- Comprehensive test suite (25 patterns)
- Reference: loop_normalize_macro.nyash (393 lines)
- ChatGPT Pro code review
### 🟡 Medium Risks
3. **Compatibility with Existing Option/Result**
- Impact: Medium (migration period conflicts)
- Probability: Low (can use separate names)
- Mitigation:
- Implement as `option_enum.hako` / `result_enum.hako`
- Gradual migration (3-5 files at a time)
- Compatibility layer if needed
4. **Performance Degradation**
- Impact: Medium (desugared code efficiency)
- Probability: Low (if-else is VM-optimized)
- Mitigation:
- Benchmark measurements
- Optimize desugared code if needed
### 🟢 Minor Risks
5. **No Exhaustiveness Checking**
- Impact: Low (runtime errors catch issues)
- Probability: Certain (static checking is Phase 25)
- Mitigation:
- Document clearly
- Tests cover all patterns
- Add static checking in Phase 25
---
## 🔄 Rollback Plan
### If Phase 19 Fails
**Criteria for Failure**:
- Week 3 end: 50%+ of 25 tests FAIL
- Performance degradation >2x
- Parser extension technically impossible
**Rollback Options**:
1. **Option A: Revert to Strategy C** (Recommended)
- Implement enum MVP (basic implementation only)
- Defer @match to Phase 20
- Duration: +2 weeks (total 5-7 weeks)
- Rationale: "Half-baked" is bad, but basic enum is better than complete failure
2. **Option B: Revert to Strategy B**
- Abandon enum completely
- Prioritize Mini-VM implementation
- Accept technical debt (quality compromise)
**Recommended**: Option A (Strategy C Rollback)
---
## 📊 Dependencies
### Prerequisites
- ✅ Phase 15.7 completion (selfhost achieved)
- ✅ StringBox/ArrayBox/MapBox stable
- ✅ Macro system basics (Phase 16 provisional)
### Recommended
- StringBox comparison efficiency (SymbolBox deferred to Phase 20+)
- Parser extension experience
### Blocks
- Mini-VM migration (starts Week 4, Step 2)
---
## 📚 References
### Existing Implementations
- **Phase 20 VariantBox Design**: [DESIGN.md](../phase-20-variant-box/DESIGN.md)
- **Result Box Design**: [RESULT_BOX_COMPLETE_DESIGN.md](../phase-20-variant-box/RESULT_BOX_COMPLETE_DESIGN.md)
- **Phase 16 Macro Revolution**: [README.md](../phase-16-macro-revolution/README.md)
### Reference Code
**Existing Macros**:
- `apps/macros/loop_normalize_macro.nyash` (393 lines) - Complex desugaring example
- `apps/macros/if_match_normalize_macro.nyash` (404 lines) - Pattern-matching-like syntax
- `src/macro/pattern.rs` (252 lines) - Rust pattern matching implementation
**Existing Option/Result**:
- `apps/lib/boxes/option.hako` - Existing implementation (commit: e441b2ba)
- `apps/lib/boxes/result.hako` - Existing implementation (commit: e441b2ba)
- `selfhost/vm/boxes/result_box.hako` (34 lines) - Mini-VM implementation
### Strategic Context
- **Strategy Decision**: [STRATEGY_DECISION.md](../../current/main/STRATEGY_DECISION.md)
- **Mini-VM Plan**: [mini_vm_migration_plan.md](../../current/main/mini_vm_migration_plan.md)
- **Choice A'' Analysis**: [CHOICE_A_DOUBLE_PRIME.md](../../current/main/CHOICE_A_DOUBLE_PRIME.md) (to be created)
---
## 🎯 Next Actions
### Day 0: Preparation (0.5 days)
**Environment Check**:
- [ ] Hakorune build verification
- [ ] Baseline smoke tests
- [ ] Phase 16 macro system verification
**Design Review**:
- [ ] Read Phase 20 VariantBox design
- [ ] Study @derive implementation (`src/macro/`)
- [ ] Study loop_normalize_macro.nyash (desugaring patterns)
**Task Preparation**:
- [ ] Create progress tracking file
- [ ] Create lessons learned file
- [ ] Prepare Week 1 task list
### Day 1: Start @enum Implementation
**Task**: Parser extension for @enum
- [ ] Analyze `src/parser/mod.rs`
- [ ] Design `@enum` syntax
- [ ] Add AST node `EnumDeclaration`
- [ ] Create minimal test case
---
## 📝 Deliverables
### Code
**Macros**:
- `apps/macros/enum/enum_macro.hako` (100-150 lines)
- `apps/macros/match/match_macro.hako` (150-200 lines)
**Libraries**:
- `apps/lib/boxes/option_enum.hako` (60-80 lines)
- `apps/lib/boxes/result_enum.hako` (60-80 lines)
**Tests**:
- `apps/tests/enum_basic.hako` (10 patterns)
- `apps/tests/match_patterns.hako` (15 patterns)
**Integration**:
- 3-5 Mini-VM files rewritten with @match
### Documentation
**Guides**:
- `docs/guides/enum-match-guide.md` - @enum/@match user guide
- `docs/guides/pattern-matching-migration.md` - Migration from null/error codes
**Design**:
- `docs/private/roadmap/phases/phase-19-enum-match/README.md` - This file
- `docs/private/roadmap/phases/phase-19-enum-match/LESSONS.md` - Lessons learned
**Planning**:
- `docs/private/roadmap/phases/phase-20-variant-box/README.md` - Updated with migration plan
---
## 🎓 Expected Outcomes
### Technical
- ✅ Complete pattern matching capability
- ✅ Type-safe error handling
- ✅ No "half-baked" period
- ✅ Foundation for Phase 20 VariantBox Core
### Quality
- ✅ Selfhost code: 100% @match (no manual tag checking)
- ✅ Error handling: 100% @match Result (no -1/-2/0)
- ✅ Null handling: 100% @match Option (no null checks)
- ✅ Technical debt: Minimal (predictable desugared code)
### Timeline
- ✅ Pattern matching in 2-3 weeks (vs 4-6 weeks for full implementation)
- ✅ Half the time of Choice A (Full enum)
- ✅ Same quality as Choice A for selfhost purposes
---
**Created**: 2025-10-08
**Status**: ACTIVE
**Owner**: Phase 19 Implementation Team
**User Intent**: "ガチガチ大作戦" (Rock-Solid Selfhosting)

View File

@ -0,0 +1,372 @@
# Phase 19 Day 1 Completion Report - @enum Parser Extension
**Date**: 2025-10-08
**Status**: ✅ COMPLETED
**Duration**: 1 day (estimated 1-2 days)
**Progress**: Day 1/14 (7%)
---
## 🎯 Goal
Implement parser support for `@enum` syntax in Hakorune compiler.
**Success Criteria**:
- ✅ Parse `@enum` declarations
- ✅ Create appropriate AST nodes
- ✅ Integrate with existing parser infrastructure
- ✅ Pass compilation tests
---
## ✅ Deliverables
### 1. TokenType Extension
**File**: `src/tokenizer/kinds.rs`
**Change**: Added `AT` token type for `@` character recognition.
```rust
pub enum TokenType {
// ... existing tokens
AT, // NEW: @ for macro syntax
}
```
### 2. Tokenizer Extension
**File**: `src/tokenizer/engine.rs`
**Change**: Added `@` character recognition in tokenizer.
```rust
'@' => {
self.advance();
Token::new(TokenType::AT, "@".to_string(), start_pos)
}
```
### 3. AST Extension
**File**: `src/ast.rs`
**Changes**:
- Added `EnumVariant` struct
- Added `ASTNode::EnumDeclaration` variant
```rust
pub struct EnumVariant {
pub name: String,
pub fields: Vec<String>,
}
pub enum ASTNode {
// ... existing variants
EnumDeclaration {
name: String,
variants: Vec<EnumVariant>,
},
}
```
### 4. AST Utility Functions
**File**: `src/ast/utils.rs`
**Changes**: Added pattern matching for `EnumDeclaration` in 4 locations:
- `clone_node()`
- `format_node()`
- `find_functions()`
- `collect_box_names()`
```rust
ASTNode::EnumDeclaration { name, variants } => {
// Implementation for each utility function
}
```
### 5. Enum Parser Implementation
**File**: `src/parser/declarations/enum_parser.rs` (NEW)
**Lines**: 150
**Quality**: Clean modular design
**Key Functions**:
- `parse_enum_declaration()` - Main entry point
- `parse_enum_variant()` - Parse individual variants
- Error handling with descriptive messages
**Syntax Supported**:
```hakorune
@enum Result {
Ok(value)
Err(error)
}
@enum Option {
Some(value)
None
}
```
### 6. Parser Integration
**File**: `src/parser/declarations/mod.rs`
**Change**: Exported `enum_parser` module.
```rust
pub mod enum_parser;
```
**File**: `src/parser/statements/declarations.rs`
**Change**: Added `@` token dispatch to `enum_parser`.
```rust
if self.peek().token_type == TokenType::AT {
return enum_parser::parse_enum_declaration(self);
}
```
**File**: `src/parser/statements/mod.rs`
**Change**: Added `TokenType::AT` recognition.
```rust
TokenType::AT => {
return parse_declaration_statement(parser);
}
```
---
## 📊 Statistics
### Code Metrics
- **New Files**: 1 (`enum_parser.rs`)
- **Modified Files**: 6
- **Lines Added**: ~150 (mostly `enum_parser.rs`)
- **Lines Modified**: ~20 (AST utilities + integration points)
### Files Changed Summary
| File | Type | Lines Changed | Description |
|------|------|---------------|-------------|
| `src/tokenizer/kinds.rs` | Modified | +1 | Added AT token |
| `src/tokenizer/engine.rs` | Modified | +4 | @ character recognition |
| `src/ast.rs` | Modified | +8 | EnumVariant + ASTNode variant |
| `src/ast/utils.rs` | Modified | +12 | Pattern matching in 4 functions |
| `src/parser/declarations/enum_parser.rs` | NEW | +150 | Complete parser implementation |
| `src/parser/declarations/mod.rs` | Modified | +1 | Module export |
| `src/parser/statements/declarations.rs` | Modified | +3 | @ dispatch |
| `src/parser/statements/mod.rs` | Modified | +3 | AT token recognition |
**Total**: ~182 lines added/modified
---
## 🧪 Testing
### Build Tests
```bash
cargo check
# Result: ✅ PASS
cargo build --release
# Result: ✅ PASS
```
### Runtime Tests
**Test Code**:
```hakorune
@enum Result {
Ok(value)
Err(error)
}
@enum Option {
Some(value)
None
}
```
**Result**: ✅ PASS - Both enums parsed correctly
**Verification**:
- AST nodes created successfully
- Variants captured correctly
- Fields recognized properly
- No parser errors
---
## 💡 Implementation Highlights
### Clean Architecture
1. **Modular Design**: Separate `enum_parser.rs` module
2. **Clear Separation**: Tokenizer → AST → Parser integration
3. **Minimal Changes**: Only necessary modifications to existing code
4. **Type Safety**: Strong typing throughout
### Error Handling
Comprehensive error messages for:
- Missing enum name
- Missing opening brace
- Invalid variant syntax
- Missing variant name
- Missing closing brace
### Extensibility
Design allows for future extensions:
- Generic parameters (future)
- Variant attributes (future)
- Complex field types (future)
---
## 🎓 Lessons Learned
### What Went Well
1. **Clean Separation**: Modular design made implementation straightforward
2. **Existing Patterns**: Phase 16 `@derive` provided excellent reference
3. **Strong Types**: Rust's type system caught errors early
4. **Test-Driven**: Runtime tests validated implementation immediately
### Challenges Encountered
1. **AST Utilities**: Required updates in 4 locations (clone, format, find, collect)
- **Solution**: Systematic review of all utility functions
2. **Parser Integration**: Multiple integration points
- **Solution**: Clear dispatch logic at each level
3. **Token Recognition**: @ character needed tokenizer support
- **Solution**: Simple addition to tokenizer engine
### Best Practices Applied
1. **Incremental Testing**: Tested after each major change
2. **Code Review**: Reviewed existing `@derive` implementation first
3. **Documentation**: Clear comments in code
4. **Consistency**: Followed existing code patterns
---
## 🔄 Next Steps (Day 2)
### Macro Expansion Implementation
**File**: `src/macro/enum_expander.rs` (NEW)
**Tasks**:
1. Create `enum_expander.rs` in `src/macro/`
2. Implement `enum_to_box_ast()` transformation
3. Generate box with `_tag` field
4. Generate static box with constructors
5. Generate helper methods (`is_*`, `as_*`)
6. Integrate with `MacroEngine::expand_node()`
7. Write unit tests (10 patterns)
8. Write integration tests (3 .hako files)
**Estimated Time**: 6-8 hours
**Desugaring Example**:
```hakorune
// Input
@enum Result {
Ok(value)
Err(error)
}
// Output
box ResultBox {
_tag: StringBox
_value: Box
_error: Box
}
static box Result {
Ok(v) {
local r = new ResultBox()
r._tag = "Ok"
r._value = v
return r
}
Err(e) {
local r = new ResultBox()
r._tag = "Err"
r._error = e
return r
}
is_ok(r) { return r._tag == "Ok" }
is_err(r) { return r._tag == "Err" }
unwrap_ok(r) {
if r._tag != "Ok" {
panic("unwrap_ok called on Err")
}
return r._value
}
unwrap_err(r) {
if r._tag != "Err" {
panic("unwrap_err called on Ok")
}
return r._error
}
}
```
---
## 📚 References
### Implementation Files
- `src/parser/declarations/enum_parser.rs` - Main implementation
- `src/ast.rs` - AST node definitions
- `src/tokenizer/kinds.rs` - Token types
### Related Work
- **Phase 16**: `@derive` macro implementation
- **Phase 20**: VariantBox Core design (future reference)
### Documentation
- [Phase 19 README](README.md)
- [Phase 19 Strategy Decision](../../current/main/STRATEGY_DECISION.md)
- [00_MASTER_ROADMAP](../00_MASTER_ROADMAP.md)
---
## 📝 Summary
Day 1 successfully completed all objectives:
**Parser Extension**: Complete `@enum` syntax support
**AST Integration**: Clean AST node design
**Tests Passing**: All build and runtime tests pass
**Quality**: Clean, modular, extensible code
**Progress**: 7% of Phase 19 complete (Day 1/14)
**Timeline**: On track for 2-3 week completion
**Next**: Day 2 - Macro expansion implementation
---
**Report Created**: 2025-10-08
**Author**: Phase 19 Implementation Team
**Status**: Day 1 ✅ COMPLETED

File diff suppressed because it is too large Load Diff