Skip to content

Commit

Permalink
fix code references with &
Browse files Browse the repository at this point in the history
  • Loading branch information
fglock committed Oct 21, 2024
1 parent 66dbfae commit a1fb1f3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
2 changes: 1 addition & 1 deletion FEATURE_MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
- ✔️ **Compound assignment operators**: Compound assignment operators are implemented.
- ✔️ **`package` declaration**: `package BLOCK` is also supported.
- ✔️ **Typeglob operations**: Operations like `*x = sub {}` are supported.
- ✔️ **Code references**: Code references like `&subr` are implemented.
- ✔️ **Code references**: Code references like `\&subr`, `\&$subname`, `\&{$subname}`, are implemented.
- ✔️ **Special literals**: `__PACKAGE__`, `__FILE__`, `__LINE__`
- ✔️ **`die` related operators**: `die`, `warn`, `exit` are supported.
-**`die` related features**: `$SIG{__DIE__}`, `$SIG{__WARN__}`, `PROPAGATE` are not yet supported.
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/org/perlonjava/codegen/EmitterVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -886,10 +886,21 @@ private void handleCreateReference(OperatorNode node) {
mv.visitInsn(Opcodes.POP);
}
} else {
if (node.operand instanceof OperatorNode && ((OperatorNode) node.operand).operator.equals("&")) {
// System.out.println("handleCreateReference of &var");
// &var is already a reference
node.operand.accept(this.with(RuntimeContextType.LIST));
if (node.operand instanceof OperatorNode operatorNode && operatorNode.operator.equals("&")) {
ctx.logDebug("Handle \\& " + operatorNode.operand);
if (operatorNode.operand instanceof OperatorNode || operatorNode.operand instanceof BlockNode) {
// \&$a or \&{$a}
operatorNode.operand.accept(this.with(RuntimeContextType.SCALAR));
ctx.mv.visitLdcInsn(ctx.symbolTable.getCurrentPackage());
ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
"org/perlonjava/runtime/RuntimeScalar",
"createCodeReference",
"(Ljava/lang/String;)Lorg/perlonjava/runtime/RuntimeScalar;",
false);
} else {
// assume \&var, which is already a reference
node.operand.accept(this.with(RuntimeContextType.LIST));
}
} else {
node.operand.accept(this.with(RuntimeContextType.LIST));
ctx.mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/perlonjava/runtime/RuntimeDataProvider", "createReference", "()Lorg/perlonjava/runtime/RuntimeScalar;", true);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/perlonjava/runtime/RuntimeScalar.java
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,13 @@ public RuntimeScalar createReference() {
return result;
}

// Return a reference to the subroutine with this name: \&$a
public RuntimeScalar createCodeReference(String packageName) {
String name = NameNormalizer.normalizeVariableName(this.toString(), packageName);
System.out.println("Creating code reference: " + name + " got: " + GlobalContext.getGlobalCodeRef(name));
return GlobalContext.getGlobalCodeRef(name);
}

public RuntimeScalar undefine() {
this.type = RuntimeScalarType.UNDEF;
return this;
Expand Down

0 comments on commit a1fb1f3

Please sign in to comment.