Files
hakorune/docs/private/roadmap/phases/phase-20-variant-box/@enum-quick-start.md

272 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# @enum Macro Implementation - Quick Start Guide
**✅ Status**: **Phase 19 完了2025-10-08** - @enum macro 完全実装済み
**Read this first**, then dive into the full spec: [@enum-macro-implementation-spec.md](./@enum-macro-implementation-spec.md)
---
## 🎉 実装状況2025-10-08完了
-**@enum macro**: 完全実装enum_parser.rs, macro/engine.rs
-**match式**: 完全実装match_expr.rs、literal/type patterns + guards対応
-**ResultBox Phase 1**: 実装完了apps/lib/boxes/result.hako, 103行
- ⚠️ **API競合**: 小文字版(Result.ok/err) vs @enum版(Result.Ok/Err) 共存中
**実装場所**:
- Parser: `src/parser/declarations/enum_parser.rs` (147行)
- Macro: `src/macro/engine.rs` (expand_enum_to_boxes関数)
- Match: `src/parser/expr/match_expr.rs` (392行)
---
## 30-Second Overview
**What**: Implement `@enum` macro that desugars to Box + Static Box
**How**: Macro-only (no IR changes, no VariantBox core)
**When**: ~~3-5 days~~ **✅ 完了2025-10-08**
---
## Core Design Pattern
### Input
```hakorune
@enum Result {
Ok(value)
Err(error)
}
```
### Output (Desugared)
```hakorune
box ResultBox {
_tag: StringBox // Discriminator
_value: Box // Ok's field
_error: Box // Err's field
birth() {
me._tag = ""
me._value = null
me._error = null
}
}
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(variant) { return variant._tag == "Ok" }
is_Err(variant) { return variant._tag == "Err" }
as_Ok(variant) {
if variant._tag != "Ok" {
print("[PANIC] Result.as_Ok: called on " + variant._tag)
return null
}
return variant._value
}
as_Err(variant) {
if variant._tag != "Err" {
print("[PANIC] Result.as_Err: called on " + variant._tag)
return null
}
return variant._error
}
}
```
---
## Key Rules
1. **Tag Field**: Always `_tag: StringBox` (discriminator)
2. **Field Naming**:
- Single field: `_value`
- Named fields: `_{field_name}` (e.g., `error``_error`)
- Multi-field: `_field1`, `_field2`, etc.
3. **All fields are Box-typed**: `Box` (runtime polymorphism)
4. **Constructors**: Variant name becomes static method
5. **Helpers**: `is_{Variant}(v)` and `as_{Variant}(v)` auto-generated
6. **Fail-Fast**: `as_*` panics if wrong variant
---
## Implementation Roadmap (5 Days)
### Day 1: Parser (6-8h)
- Add `@enum` token recognition
- Parse `@enum Name { Variant1(field) Variant2 }`
- Create AST nodes: `EnumDeclaration`, `EnumVariant`, `EnumField`
- Validation: duplicates, empty enum, reserved names
### Day 2: Macro Expansion (8-10h)
- Create `src/macro/enum_macro.rs`
- Implement `expand_enum()` → generates AST
- Generate data box (`{Name}Box` with `_tag` + all fields)
- Generate `birth()` method
### Day 3: Helpers (8-10h)
- Generate static box with constructors
- Generate `is_{Variant}()` methods
- Generate `as_{Variant}()` methods (single/multi-field)
- Handle edge cases (0-field variants, conflicts)
### Day 4: Tests (6-8h)
- 12 positive tests (basic, multi-variant, helpers, integration)
- 3 negative tests (errors)
- Test runner script
- Verify all tests pass
### Day 5: Integration (6-8h)
- Smoke tests
- Performance benchmark (vs old Option/Result)
- Migration guide
- Documentation update
---
## Files to Create/Modify
### New Files
- `src/parser/declarations/enum_parser.rs` - Parser logic
- `src/macro/enum_macro.rs` - Macro expansion
- `apps/lib/boxes/tests/enum_*.hako` - Test suite (8 files)
- `tools/run_enum_tests.sh` - Test runner
- `docs/guides/enum-migration-guide.md` - Migration guide
### Modified Files
- `src/parser/mod.rs` - Add enum parser invocation
- `src/parser/declarations/mod.rs` - Export enum parser
- `src/ast.rs` - Add `EnumDeclaration`, `EnumVariant`, `EnumField`
- `src/macro/mod.rs` - Integrate enum expansion
- `hako.toml` - Add v2 module aliases (optional)
---
## Critical Edge Cases
1. **Zero-field variant**: `None` → constructor takes no args
2. **Multi-field variant**: `as_*` returns `ArrayBox` with all fields
3. **Field conflicts**: Same field name across variants → shared storage (OK)
4. **Reserved names**: `birth`, `fini`, `new`, `me`, `this` → error
5. **Empty enum**: No variants → parse error
---
## Test Examples (Must Pass)
### Basic Usage
```hakorune
@enum Option { Some(value) None }
local opt = Option.Some(42)
print(opt._tag) // "Some"
print(opt._value) // "42"
if Option.is_Some(opt) {
local v = Option.as_Some(opt)
print(v) // "42"
}
```
### Panic Behavior
```hakorune
local err = Result.Err("failed")
local v = Result.as_Ok(err) // Panics!
// Output: [PANIC] Result.as_Ok: called on Err
// Returns: null
```
### Pattern Matching (Manual)
```hakorune
if result._tag == "Ok" {
print("Success: " + result._value)
}
if result._tag == "Err" {
print("Error: " + result._error)
}
```
---
## Migration Strategy (for existing Option/Result)
### Phase 1: Parallel Existence
- Keep old `option.hako` / `result.hako`
- Create new `option_v2.hako` / `result_v2.hako` with `@enum`
- Add module aliases in `hako.toml`
### Phase 2: Gradual Migration
- Migrate test files first
- Migrate non-critical tools
- Verify behavior parity
### Phase 3: Deprecation
- Rename old → `*_deprecated.hako`
- Rename v2 → main files
- Update all import sites
### Phase 4: Cleanup
- Delete deprecated files
- Update documentation
**Important**: NOT backward compatible. API changes:
- `Option.some(v)``Option.Some(v)` (capital S)
- `opt.is_some()``Option.is_Some(opt)` (static method)
- `opt._is_some``opt._tag == "Some"` (tag-based)
---
## Performance Expectations
- **String comparison**: Slightly slower than integer flags
- **Expected regression**: <10% (acceptable for MVP)
- **Future optimization**: String interning pointer comparison
---
## Success Criteria
- [ ] All 12 positive tests pass
- [ ] All 3 negative tests catch errors
- [ ] Smoke tests pass
- [ ] Performance <10% regression
- [ ] Documentation complete
- [ ] Migration guide written
---
## Risk Mitigation
1. **Parser conflicts**: Test with `@local` in same file
2. **Macro order**: Run @enum expansion early (before other macros)
3. **Field naming**: Reserve `_` prefix, validate in parser
4. **Error messages**: Preserve source spans, show original @enum location
5. **Debugging**: Add `NYASH_MACRO_TRACE=1` output
---
## Next Steps
1. Read full spec: [@enum-macro-implementation-spec.md](./@enum-macro-implementation-spec.md)
2. Start with Day 1 (Parser changes)
3. Follow daily checklist
4. Ask questions early (don't guess)
---
**Full Specification**: [@enum-macro-implementation-spec.md](./@enum-macro-implementation-spec.md) (13,000+ words, implementation-ready)