Skip to content

Commit 4fe41c4

Browse files
committed
Improve backslash operator context handling and RuntimeList.createReference
- Detect function calls (BinaryOperatorNode with '(') and use SCALAR context - This fixes \PVBM where PVBM is a constant sub - Implement RuntimeList.createReference() for single-element lists - Preserve LIST context for arrays/hashes to fix tie regression
1 parent 8479fd7 commit 4fe41c4

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/main/java/org/perlonjava/codegen/EmitOperator.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,20 @@ static void handleCreateReference(EmitterVisitor emitterVisitor, OperatorNode no
893893
node.operand.accept(emitterVisitor.with(RuntimeContextType.LIST));
894894
}
895895
} else {
896-
node.operand.accept(emitterVisitor.with(RuntimeContextType.LIST));
896+
// Determine context based on operand type
897+
// Function calls and scalar expressions should use SCALAR context
898+
// Arrays, hashes, and lists should use LIST context
899+
int contextType = RuntimeContextType.LIST;
900+
901+
if (node.operand instanceof BinaryOperatorNode binOp && binOp.operator.equals("(")) {
902+
// Function call - use SCALAR context to get single return value
903+
contextType = RuntimeContextType.SCALAR;
904+
} else if (node.operand instanceof OperatorNode op && op.operator.equals("$")) {
905+
// Scalar variable - use SCALAR context
906+
contextType = RuntimeContextType.SCALAR;
907+
}
908+
909+
node.operand.accept(emitterVisitor.with(contextType));
897910
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
898911
"org/perlonjava/runtime/RuntimeBase",
899912
"createReference",

src/main/java/org/perlonjava/runtime/RuntimeList.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,20 @@ public RuntimeScalar scalar() {
324324
}
325325

326326
/**
327-
* Throws an exception as creating a reference of a list is not implemented.
327+
* Creates a reference from a list.
328+
* For single-element lists (e.g., from constant subs), creates a reference to that element.
329+
* For empty or multi-element lists, this is an error in scalar context.
328330
*
329-
* @throws PerlCompilerException Always thrown as creating a reference is not implemented.
331+
* @return A RuntimeScalar reference to the list element
332+
* @throws PerlCompilerException if the list doesn't contain exactly one element
330333
*/
331334
public RuntimeScalar createReference() {
332-
// TODO
333-
throw new PerlCompilerException("TODO - create reference of list not implemented");
335+
if (elements.size() == 1) {
336+
// Single element list - create reference to that element
337+
return elements.get(0).scalar().createReference();
338+
}
339+
// Empty or multi-element list in reference context is an error
340+
throw new PerlCompilerException("Can't create reference to list with " + elements.size() + " elements");
334341
}
335342

336343
/**

0 commit comments

Comments
 (0)