Some checks failed
Build Cross OS / Go (/go, oldstable, macos-latest) (push) Has been cancelled
Build Cross OS / Go (/go, oldstable, ubuntu-latest) (push) Has been cancelled
Build Cross OS / Go (/go, stable, macos-latest) (push) Has been cancelled
Build Cross OS / Go (/go, stable, ubuntu-latest) (push) Has been cancelled
Build Cross OS / Go (\go, oldstable, windows-latest) (push) Has been cancelled
Build Cross OS / Go (\go, stable, windows-latest) (push) Has been cancelled
Main / Linting (push) Has been cancelled
Main / Checks code and generated code (oldstable) (push) Has been cancelled
Main / Checks code and generated code (stable) (push) Has been cancelled
Main / Build and Test (oldstable) (push) Has been cancelled
Main / Build and Test (stable) (push) Has been cancelled
206 lines
7.9 KiB
Markdown
206 lines
7.9 KiB
Markdown
# Phase 1.1 Implementation Progress
|
|
|
|
## Summary
|
|
This document tracks the progress of implementing Phase 1.1: Explicit Pointer Types for Reference Types in the Moxa interpreter.
|
|
|
|
## Completed Work
|
|
|
|
### 1. Type System Foundation ✅
|
|
- Added new type categories to [interp/type.go](interp/type.go):
|
|
- `ptrSliceT` - Represents `*[]T`
|
|
- `ptrMapT` - Represents `*map[K]V`
|
|
- `ptrChanT`, `ptrChanSendT`, `ptrChanRecvT` - Represents `*chan T` variants
|
|
- Updated `cats` string array for new types
|
|
- Modified `ptrOf()` function to convert slice/map/chan types to pointer-wrapped variants when `&` is applied
|
|
|
|
### 2. Reflection Type Support ✅
|
|
- Updated `refType()` method in [interp/type.go](interp/type.go#L2122-L2139) to handle pointer-wrapped types
|
|
- Updated `frameType()` method to support new types
|
|
- Updated `isComplete()` function to check completeness of new pointer types
|
|
|
|
### 3. Composite Literal Support ✅
|
|
- Updated [interp/cfg.go](interp/cfg.go) to handle pointer-wrapped types in:
|
|
- `compositeLitExpr` cases (lines 1457-1460)
|
|
- `compositeGenerator` function (lines 2976-2979)
|
|
- Range statement handling for maps and slices (lines 183, 202)
|
|
- Updated [interp/gta.go](interp/gta.go) to handle new types in `definedType()` (line 448, 453)
|
|
- Updated [interp/generic.go](interp/generic.go) for generic type inference (lines 228, 231)
|
|
|
|
### 4. Runtime Support for Literals ✅
|
|
- Modified `arrayLit()` in [interp/run.go](interp/run.go#L2546-2570) to create pointer-wrapped slices
|
|
- Handles `*[]T` by creating a pointer to a slice
|
|
- Auto-dereferencing for element assignment
|
|
- Modified `mapLit()` in [interp/run.go](interp/run.go#L2580-2612) to create pointer-wrapped maps
|
|
- Handles `*map[K]V` by creating a pointer to a map
|
|
- Auto-dereferencing for element assignment
|
|
|
|
### 5. Address and Dereference Operations
|
|
- Separated `addressExpr` and `starExpr` handling in [interp/type.go](interp/type.go#L453-492):
|
|
- `addressExpr` (&): Creates pointer-wrapped types via `ptrOf()`
|
|
- `starExpr` (*): Dereferences pointer-wrapped types back to value types
|
|
|
|
## Current Status
|
|
|
|
### Working ✅
|
|
- Creating pointer-wrapped slices: `s := &[]int{1, 2, 3}` ✅
|
|
- Creating pointer-wrapped maps: `m := &map[string]int{"a": 1}` ✅
|
|
- Printing pointer-wrapped types ✅
|
|
|
|
### In Progress 🚧
|
|
- **Dereferencing pointer-wrapped types**: `deref := *s`
|
|
- Type creation works at compile-time
|
|
- Runtime assignment fails with type mismatch error
|
|
- **Issue**: Newly created `itype` for dereferenced type doesn't have proper reflection type set
|
|
|
|
## Known Issues
|
|
|
|
### 1. Type Mismatch on Dereference Assignment
|
|
**Location**: [interp/type.go](interp/type.go#L461-492)
|
|
|
|
**Problem**: When dereferencing `*s` where `s` is `*[]int`, we create a new `sliceT` itype, but it doesn't have the proper `rtype` field set, causing runtime type mismatches.
|
|
|
|
**Error**:
|
|
```
|
|
reflect.Set: value of type []int is not assignable to type int
|
|
```
|
|
|
|
**Root Cause**: The newly created `itype` in `starExpr` case doesn't go through proper type initialization that sets up reflection types.
|
|
|
|
**Potential Solutions**:
|
|
1. Use existing slice/map/chan types from scope instead of creating new ones
|
|
2. Call proper type initialization after creating new itype
|
|
3. Use sliceOf/mapOf/chanOf functions with options to create dereferenced types
|
|
|
|
## Next Steps
|
|
|
|
### High Priority
|
|
1. **Fix starExpr dereference type creation**
|
|
- Ensure proper `rtype` initialization
|
|
- Consider using existing types or proper constructor functions
|
|
|
|
2. **Implement auto-dereferencing for indexing**
|
|
- Modify indexing operations in [interp/run.go](interp/run.go)
|
|
- `s[i]` should work on `*[]int` by auto-dereferencing
|
|
- `m[k]` should work on `*map[K]V` by auto-dereferencing
|
|
|
|
3. **Update built-in functions**
|
|
- `len()` and `cap()` should work on `*[]T`
|
|
- Handle auto-dereferencing in built-in function implementations
|
|
|
|
### Medium Priority
|
|
4. **Channel support**
|
|
- Implement composite literal syntax for channels: `&chan T{cap: n}`
|
|
- This will require parser changes for the new syntax
|
|
|
|
5. **Range statement auto-dereferencing**
|
|
- `for x := range s` should work on `*[]T`
|
|
- Already partially implemented, needs testing
|
|
|
|
6. **Comprehensive testing**
|
|
- Test all operations with pointer-wrapped types
|
|
- Test nil pointer handling
|
|
- Test type compatibility and conversions
|
|
|
|
## Files Modified
|
|
|
|
### Core Type System
|
|
- [interp/type.go](interp/type.go) - Added new type categories, updated ptrOf(), separated address/star expr handling
|
|
- Lines 28-32: New type categories
|
|
- Lines 246-273: Modified ptrOf()
|
|
- Lines 453-492: Separated addressExpr and starExpr
|
|
|
|
### Configuration and Parsing
|
|
- [interp/cfg.go](interp/cfg.go) - Updated composite literal and range handling
|
|
- Lines 183, 202: Range statement updates
|
|
- Lines 1457-1460: Composite literal type checking
|
|
- Lines 2976-2979: Composite generator
|
|
|
|
### Runtime Execution
|
|
- [interp/run.go](interp/run.go) - Updated literal creation functions
|
|
- Lines 2546-2570: arrayLit() for pointer-wrapped slices
|
|
- Lines 2580-2612: mapLit() for pointer-wrapped maps
|
|
|
|
### Type Analysis
|
|
- [interp/gta.go](interp/gta.go) - Updated type definition checking
|
|
- Lines 448, 453: Handle new pointer types
|
|
|
|
### Generic Type Inference
|
|
- [interp/generic.go](interp/generic.go) - Updated type inference
|
|
- Lines 228, 231: Handle pointer-wrapped types in inference
|
|
|
|
## Testing
|
|
|
|
### Test Files Created
|
|
- [_test/moxie_phase1_1_test.go](_test/moxie_phase1_1_test.go) - Main test file (currently has deref issues)
|
|
- [_test/simple_test.go](_test/simple_test.go) - Simplified test for debugging
|
|
|
|
### Test Results
|
|
```bash
|
|
# Creating pointer-wrapped types works:
|
|
go run ./cmd/yaegi _test/simple_test.go
|
|
# Output: Slice created: &[1 2 3]
|
|
# Test completed!
|
|
|
|
# Dereferencing has issues (needs fix):
|
|
# Error: reflect.Set: value of type []int is not assignable to type int
|
|
```
|
|
|
|
## Architecture Notes
|
|
|
|
### Type Conversion Flow
|
|
1. **User writes**: `s := &[]int{1, 2, 3}`
|
|
2. **Parser creates**: `compositeLitExpr` with `arrayType` wrapped in `addressExpr`
|
|
3. **Type resolution**:
|
|
- `arrayType` (no length) → `sliceOf()` → `sliceT`
|
|
- `addressExpr` → `ptrOf(sliceT)` → `ptrSliceT`
|
|
4. **Code generation**: `arrayLit()` creates `*[]int` value
|
|
5. **Runtime**: Stores pointer to slice in variable
|
|
|
|
### Deference Flow (Currently Broken)
|
|
1. **User writes**: `deref := *s`
|
|
2. **Parser creates**: `starExpr` wrapping identifier `s`
|
|
3. **Type resolution**:
|
|
- `s` has type `ptrSliceT`
|
|
- `starExpr` should convert to `sliceT`
|
|
- **BUG**: Created `sliceT` doesn't have proper `rtype`
|
|
4. **Runtime**: Type mismatch when assigning
|
|
|
|
## Design Decisions
|
|
|
|
### Why Separate ptrSliceT instead of using ptrT?
|
|
Using separate categories (`ptrSliceT`, `ptrMapT`, etc.) instead of generic `ptrT` allows:
|
|
- Clearer type distinction in Moxie semantics
|
|
- Easier implementation of auto-dereferencing
|
|
- Better error messages
|
|
- Direct access to key/val types for maps without extra indirection
|
|
|
|
### Why Modify ptrOf() instead of sliceOf()?
|
|
Keeping `sliceOf()`, `mapOf()`, `chanOf()` creating non-pointer types and using `ptrOf()` to wrap them ensures:
|
|
- `&[]int{...}` syntax works naturally (address operator wraps the slice type)
|
|
- Type constructors remain simple
|
|
- Pointer wrapping is explicit in the code flow
|
|
|
|
## Performance Considerations
|
|
|
|
### Memory Impact
|
|
- Pointer-wrapped types add one level of indirection
|
|
- Reflection type creation might have slight overhead
|
|
- Overall impact should be minimal for most code
|
|
|
|
### Runtime Impact
|
|
- Auto-dereferencing adds minimal overhead (one pointer dereference)
|
|
- Composite literal creation slightly more complex
|
|
- Type checking remains O(1) with category-based switches
|
|
|
|
## Future Work (Post Phase 1.1)
|
|
|
|
- Phase 1.2: Remove platform-dependent integer types (`int`, `uint`)
|
|
- Phase 2.1: Mutable strings as `*[]byte`
|
|
- Phase 2.2: Concatenation operator `|`
|
|
- Phase 3: Built-in function modifications
|
|
|
|
## References
|
|
|
|
- [Moxie Implementation Plan](moxie-implementation.md)
|
|
- [Phase 1.1 Detailed Plan](phase-1.1-plan.md)
|