|
| 1 | +# Context-Aware Constant Folding (Future Enhancement) |
| 2 | + |
| 3 | +## Current Limitation |
| 4 | + |
| 5 | +The `ConstantFoldingVisitor.getConstantValue()` method currently treats all expressions as being in **scalar context**. This works for regex code blocks `(?{...})` because `$^R` always operates in scalar context, but it's not a complete solution for general constant folding. |
| 6 | + |
| 7 | +## The Issue |
| 8 | + |
| 9 | +Perl's context system (`RuntimeContextType`) affects how expressions evaluate: |
| 10 | + |
| 11 | +- **SCALAR context**: Empty list `()` returns `undef` |
| 12 | +- **LIST context**: Empty list `()` returns empty list `[]` |
| 13 | +- **VOID context**: Result is discarded |
| 14 | + |
| 15 | +### Current Implementation |
| 16 | + |
| 17 | +```java |
| 18 | +// In ConstantFoldingVisitor.getConstantValue() |
| 19 | +else if (node instanceof ListNode listNode) { |
| 20 | + // Handle empty list/statement - returns undef in scalar context |
| 21 | + if (listNode.elements.isEmpty()) { |
| 22 | + return RuntimeScalarCache.scalarUndef; // Always scalar context! |
| 23 | + } |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +This works for `(?{})` in regex because: |
| 28 | +1. Regex code blocks always evaluate in scalar context for `$^R` |
| 29 | +2. Empty blocks correctly return `undef` |
| 30 | + |
| 31 | +### Example Behavior |
| 32 | + |
| 33 | +```perl |
| 34 | +# Scalar context (current implementation correct) |
| 35 | +my $x = (?{}); # $x = undef ✅ |
| 36 | + |
| 37 | +# List context (not currently handled) |
| 38 | +my @x = (?{}); # @x = () - but we'd return (undef) ❌ |
| 39 | +``` |
| 40 | + |
| 41 | +## Future Enhancement |
| 42 | + |
| 43 | +To make constant folding fully context-aware: |
| 44 | + |
| 45 | +### 1. Add Context Parameter to getConstantValue() |
| 46 | + |
| 47 | +```java |
| 48 | +public static RuntimeScalar getConstantValue(Node node, int context) { |
| 49 | + // ... existing code ... |
| 50 | + |
| 51 | + if (node instanceof ListNode listNode) { |
| 52 | + if (listNode.elements.isEmpty()) { |
| 53 | + if (context == RuntimeContextType.SCALAR) { |
| 54 | + return RuntimeScalarCache.scalarUndef; |
| 55 | + } else if (context == RuntimeContextType.LIST) { |
| 56 | + // Return empty list representation |
| 57 | + return new RuntimeArray(); // Or appropriate empty list marker |
| 58 | + } |
| 59 | + } |
| 60 | + } |
| 61 | +} |
| 62 | +``` |
| 63 | + |
| 64 | +### 2. Thread Context Through Constant Folding |
| 65 | + |
| 66 | +The constant folding visitor would need to track context as it walks the AST: |
| 67 | + |
| 68 | +- Function arguments: LIST context |
| 69 | +- Scalar assignments: SCALAR context |
| 70 | +- Array assignments: LIST context |
| 71 | +- Ternary operator: Inherits from parent context |
| 72 | +- etc. |
| 73 | + |
| 74 | +### 3. Benefits |
| 75 | + |
| 76 | +- More accurate constant folding across all contexts |
| 77 | +- Could optimize more complex expressions |
| 78 | +- Better match Perl semantics |
| 79 | + |
| 80 | +## Current Status |
| 81 | + |
| 82 | +**NOT NEEDED NOW** - The current scalar-only implementation is sufficient for: |
| 83 | +- Regex code blocks `(?{...})` and `$^R` support |
| 84 | +- Most common constant folding use cases (numbers, strings, simple expressions) |
| 85 | + |
| 86 | +**FUTURE WORK** - Context-aware folding would be valuable for: |
| 87 | +- General-purpose optimization pass |
| 88 | +- More aggressive compile-time evaluation |
| 89 | +- Edge cases involving list/scalar context differences |
| 90 | + |
| 91 | +## References |
| 92 | + |
| 93 | +- `RuntimeContextType.java` - Defines SCALAR, LIST, VOID, RUNTIME contexts |
| 94 | +- `ConstantFoldingVisitor.java` - Current implementation |
| 95 | +- Perl documentation on contexts: `perldoc perldata` (CONTEXT section) |
| 96 | + |
| 97 | +## Related Code |
| 98 | + |
| 99 | +```java |
| 100 | +// Current usage in parseRegexCodeBlock (StringSegmentParser.java) |
| 101 | +RuntimeScalar constantValue = |
| 102 | + ConstantFoldingVisitor.getConstantValue(folded); // Always scalar context |
| 103 | + |
| 104 | +// Future enhanced version would be: |
| 105 | +RuntimeScalar constantValue = |
| 106 | + ConstantFoldingVisitor.getConstantValue(folded, RuntimeContextType.SCALAR); |
| 107 | +``` |
| 108 | + |
| 109 | +## Priority |
| 110 | + |
| 111 | +**LOW** - Current implementation is correct for all existing use cases. Only implement this if: |
| 112 | +1. We need more aggressive constant folding optimization |
| 113 | +2. We encounter bugs related to context mismatches |
| 114 | +3. We want to optimize list operations at compile time |
0 commit comments