7.5 KiB
Phase 1.1 Implementation Plan: Explicit Pointer Types for Reference Types
Overview
This document details the implementation approach for transforming slices, maps, and channels from implicit reference types to explicit pointer types in the Moxa interpreter.
Current Implementation Analysis
Type System (type.go)
- sliceOf(): Creates
*itype{cat: sliceT, val: elementType, str: "[]T"} - mapOf(): Creates
*itype{cat: mapT, key: keyType, val: valueType, str: "map[K]V"} - chanOf(): Creates
*itype{cat: chanT/chanSendT/chanRecvT, val: elementType, str: "chan T"}
Composite Literal Parsing (cfg.go)
- Line 359-389:
compositeLitExprcase handles composite literal type inference - Currently accepts
[]T{...},map[K]V{...},chan Tdirectly
Indexing Operations (run.go)
- getIndexArray(): Line 1737 - Handles array indexing
arr[i] - getIndexMap(): Line 1786 - Handles map lookup
m[k] - Currently operates directly on slice/map values
Required Changes
1. Type Representation Changes (type.go)
Option A: Modify Type Constructors Directly
// Current:
func sliceOf(val *itype, opts ...itypeOption) *itype {
t := &itype{cat: sliceT, val: val, str: "[]" + val.str}
return t
}
// Moxie (Option A):
func sliceOf(val *itype, opts ...itypeOption) *itype {
innerT := &itype{cat: sliceT, val: val, str: "[]" + val.str}
t := ptrOf(innerT, opts...) // Wrap in pointer
return t
}
Pros: Simple, changes are localized
Cons: Breaks existing type checking logic, affects all code that checks typ.cat == sliceT
Option B: Add New Categories for Pointer-Wrapped Types
const (
// ... existing types ...
ptrSliceT // *[]T
ptrMapT // *map[K]V
ptrChanT // *chan T
)
func sliceOf(val *itype, opts ...itypeOption) *itype {
t := &itype{cat: ptrSliceT, val: val, str: "*[]" + val.str}
return t
}
Pros: Preserves backward compatibility, easier to distinguish Cons: Requires updating all switch statements that handle slice/map/chan types
Recommendation: Use Option B
Option B provides clearer semantics and makes it easier to maintain both Go and Moxie modes if needed.
2. Composite Literal Syntax (cfg.go)
Current behavior:
// Go syntax:
s := []int{1, 2, 3}
m := map[string]int{"a": 1}
Required Moxie syntax:
// Moxie syntax:
s := &[]int{1, 2, 3} // Must use & prefix
m := &map[string]int{"a": 1}
Implementation location: cfg.go lines 359-389 in compositeLitExpr case
Changes needed:
- Check if parent node is
addressExpr(&) - For slice/map/chan composite literals, require
&prefix - Error if
&is missing for these types - Update type assignment to use pointer types
3. Auto-Dereferencing for Operations (run.go, op.go)
Indexing: s[i] should work on *[]T
- Modify
getIndexArray()(line 1737) to auto-dereference pointers to slices - Check if
n.child[0].typ.cat == ptrSliceT, if so, dereference first
Map Access: m[k] should work on *map[K]V
- Modify
getIndexMap()(line 1786) to auto-dereference pointers to maps - Check if
n.child[0].typ.cat == ptrMapT, if so, dereference first
Range: for x := range s
- Modify range statement handling to auto-dereference
- Location: Search for
rangeStmthandling in cfg.go
Built-in Functions
len(s): Should work on*[]Tcap(s): Should work on*[]T- Both need to auto-dereference the pointer
4. Channel Operations
Channels are more complex due to send/receive operations:
// Current Go syntax:
ch := make(chan int)
ch <- 42
x := <-ch
// Moxie syntax:
ch := &chan int{cap: 10} // New syntax for channel creation
ch <- 42 // Auto-dereference for send
x := <-ch // Auto-dereference for receive
Changes needed:
- Remove
make()support for channels (will be in Phase 3) - Add composite literal syntax for channels:
&chan T{cap: n} - Auto-dereference in send operations
- Auto-dereference in receive operations
- Handle select statements
Implementation Strategy
Phase 1.1.1: Type System Foundation
- Add new type categories:
ptrSliceT,ptrMapT,ptrChanTtotype.go - Modify
sliceOf(),mapOf(),chanOf()to create pointer types - Update
catsarray andString()method - Update all type checking utility functions:
isSlice()→ check for bothsliceTandptrSliceTisMap()→ check for bothmapTandptrMapTisChan()→ check for bothchanTandptrChanT
Phase 1.1.2: Composite Literal Parsing
- Modify
compositeLitExprcase incfg.go - Enforce
&prefix for slice/map/chan literals - Add helpful error messages for missing
& - Update tests
Phase 1.1.3: Auto-Dereferencing
- Update
getIndexArray()inrun.go - Update
getIndexMap()inrun.go - Update built-in functions (
len,cap, etc.) - Update range statement handling
- Update channel send/receive operations
Phase 1.1.4: Testing
- Create test files for new syntax
- Test slice operations with pointer types
- Test map operations with pointer types
- Test channel operations with pointer types
- Test nil checking behavior
- Test error messages for syntax errors
Potential Issues and Solutions
Issue 1: Reflection Type Compatibility
Problem: reflect.Type for *[]T vs []T are different
Solution: Update refType() and frameType() methods in type.go to handle pointer-wrapped types correctly
Issue 2: Assignment Compatibility
Problem: Cannot assign *[]T to []T
Solution: Update type checking in cfg.go to understand the new semantics
Issue 3: Nil Checks
Problem: Slices/maps/channels can now be nil pointers Solution:
- Add explicit nil checks before dereferencing
- Update runtime to panic with clear messages on nil dereference
Issue 4: Built-in Function Compatibility
Problem: append() expects []T not *[]T
Solution: This will be addressed in Phase 2.2 when append() is removed and | operator is added
Testing Strategy
Unit Tests
- Test type creation with new pointer types
- Test composite literal parsing with
&prefix - Test error messages for missing
& - Test auto-dereferencing in all operations
Integration Tests
- Test complex programs using slices
- Test complex programs using maps
- Test complex programs using channels
- Test interaction between different types
Regression Tests
- Ensure existing Go code still works (if compatibility mode is maintained)
- Ensure no performance regression
Files to Modify
-
interp/type.go
- Add new type categories
- Modify type constructor functions
- Update utility functions
-
interp/cfg.go
- Update
compositeLitExprhandling - Add
&prefix requirement - Update type inference
- Update
-
interp/run.go
- Update indexing functions
- Update built-in functions
- Add auto-dereferencing
-
interp/op.go (if needed)
- May need regeneration if operators are affected
-
interp/ast.go (minimal changes)
- May need to add new action types if needed
Estimated Complexity
- High: This touches fundamental interpreter behavior
- Risk: Medium to High - could break existing functionality
- Testing Burden: High - requires comprehensive testing
Next Steps
- ✅ Create this implementation plan
- Get user approval for approach
- Implement Phase 1.1.1 (Type System Foundation)
- Implement Phase 1.1.2 (Composite Literal Parsing)
- Implement Phase 1.1.3 (Auto-Dereferencing)
- Implement Phase 1.1.4 (Testing)
- Document changes and create examples