Files
moxa/phase-1.1-plan.md
mleku b974bb23ea
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
implement 1.1 explicit collection type pointers
2025-11-22 09:58:03 +00:00

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: compositeLitExpr case handles composite literal type inference
  • Currently accepts []T{...}, map[K]V{...}, chan T directly

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:

  1. Check if parent node is addressExpr (&)
  2. For slice/map/chan composite literals, require & prefix
  3. Error if & is missing for these types
  4. 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 rangeStmt handling in cfg.go

Built-in Functions

  • len(s): Should work on *[]T
  • cap(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:

  1. Remove make() support for channels (will be in Phase 3)
  2. Add composite literal syntax for channels: &chan T{cap: n}
  3. Auto-dereference in send operations
  4. Auto-dereference in receive operations
  5. Handle select statements

Implementation Strategy

Phase 1.1.1: Type System Foundation

  1. Add new type categories: ptrSliceT, ptrMapT, ptrChanT to type.go
  2. Modify sliceOf(), mapOf(), chanOf() to create pointer types
  3. Update cats array and String() method
  4. Update all type checking utility functions:
    • isSlice() → check for both sliceT and ptrSliceT
    • isMap() → check for both mapT and ptrMapT
    • isChan() → check for both chanT and ptrChanT

Phase 1.1.2: Composite Literal Parsing

  1. Modify compositeLitExpr case in cfg.go
  2. Enforce & prefix for slice/map/chan literals
  3. Add helpful error messages for missing &
  4. Update tests

Phase 1.1.3: Auto-Dereferencing

  1. Update getIndexArray() in run.go
  2. Update getIndexMap() in run.go
  3. Update built-in functions (len, cap, etc.)
  4. Update range statement handling
  5. Update channel send/receive operations

Phase 1.1.4: Testing

  1. Create test files for new syntax
  2. Test slice operations with pointer types
  3. Test map operations with pointer types
  4. Test channel operations with pointer types
  5. Test nil checking behavior
  6. 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

  1. interp/type.go

    • Add new type categories
    • Modify type constructor functions
    • Update utility functions
  2. interp/cfg.go

    • Update compositeLitExpr handling
    • Add & prefix requirement
    • Update type inference
  3. interp/run.go

    • Update indexing functions
    • Update built-in functions
    • Add auto-dereferencing
  4. interp/op.go (if needed)

    • May need regeneration if operators are affected
  5. 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

  1. Create this implementation plan
  2. Get user approval for approach
  3. Implement Phase 1.1.1 (Type System Foundation)
  4. Implement Phase 1.1.2 (Composite Literal Parsing)
  5. Implement Phase 1.1.3 (Auto-Dereferencing)
  6. Implement Phase 1.1.4 (Testing)
  7. Document changes and create examples