docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)
This commit is contained in:
@ -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
678
docs/private/roadmap/phases/phase-19-enum-match/README.md
Normal file
678
docs/private/roadmap/phases/phase-19-enum-match/README.md
Normal 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)
|
||||
@ -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
Reference in New Issue
Block a user