7.9 KiB
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:
ptrSliceT- Represents*[]TptrMapT- Represents*map[K]VptrChanT,ptrChanSendT,ptrChanRecvT- Represents*chan Tvariants
- Updated
catsstring 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 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 to handle pointer-wrapped types in:
compositeLitExprcases (lines 1457-1460)compositeGeneratorfunction (lines 2976-2979)- Range statement handling for maps and slices (lines 183, 202)
- Updated interp/gta.go to handle new types in
definedType()(line 448, 453) - Updated interp/generic.go for generic type inference (lines 228, 231)
4. Runtime Support for Literals ✅
- Modified
arrayLit()in interp/run.go to create pointer-wrapped slices- Handles
*[]Tby creating a pointer to a slice - Auto-dereferencing for element assignment
- Handles
- Modified
mapLit()in interp/run.go to create pointer-wrapped maps- Handles
*map[K]Vby creating a pointer to a map - Auto-dereferencing for element assignment
- Handles
5. Address and Dereference Operations
- Separated
addressExprandstarExprhandling in interp/type.go:addressExpr(&): Creates pointer-wrapped types viaptrOf()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
itypefor dereferenced type doesn't have proper reflection type set
Known Issues
1. Type Mismatch on Dereference Assignment
Location: interp/type.go
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:
- Use existing slice/map/chan types from scope instead of creating new ones
- Call proper type initialization after creating new itype
- Use sliceOf/mapOf/chanOf functions with options to create dereferenced types
Next Steps
High Priority
-
Fix starExpr dereference type creation
- Ensure proper
rtypeinitialization - Consider using existing types or proper constructor functions
- Ensure proper
-
Implement auto-dereferencing for indexing
- Modify indexing operations in interp/run.go
s[i]should work on*[]intby auto-dereferencingm[k]should work on*map[K]Vby auto-dereferencing
-
Update built-in functions
len()andcap()should work on*[]T- Handle auto-dereferencing in built-in function implementations
Medium Priority
-
Channel support
- Implement composite literal syntax for channels:
&chan T{cap: n} - This will require parser changes for the new syntax
- Implement composite literal syntax for channels:
-
Range statement auto-dereferencing
for x := range sshould work on*[]T- Already partially implemented, needs testing
-
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 - 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 - 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 - 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 - Updated type definition checking
- Lines 448, 453: Handle new pointer types
Generic Type Inference
- 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 - Main test file (currently has deref issues)
- _test/simple_test.go - Simplified test for debugging
Test Results
# 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
- User writes:
s := &[]int{1, 2, 3} - Parser creates:
compositeLitExprwitharrayTypewrapped inaddressExpr - Type resolution:
arrayType(no length) →sliceOf()→sliceTaddressExpr→ptrOf(sliceT)→ptrSliceT
- Code generation:
arrayLit()creates*[]intvalue - Runtime: Stores pointer to slice in variable
Deference Flow (Currently Broken)
- User writes:
deref := *s - Parser creates:
starExprwrapping identifiers - Type resolution:
shas typeptrSliceTstarExprshould convert tosliceT- BUG: Created
sliceTdoesn't have properrtype
- 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