diff --git a/src/main/java/org/perlonjava/EmitterVisitor.java b/src/main/java/org/perlonjava/EmitterVisitor.java index e08c3c42..d3dc7bb5 100644 --- a/src/main/java/org/perlonjava/EmitterVisitor.java +++ b/src/main/java/org/perlonjava/EmitterVisitor.java @@ -495,6 +495,10 @@ private void handleUnaryBuiltin(UnaryOperatorNode node, String operator) throws // Unary operator with optional arguments, called without arguments // example: undef() ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/perlonjava/RuntimeScalar", operator, "()Lorg/perlonjava/RuntimeScalar;", false); + } else if (operator.equals("undef")) { + operator = "undefine"; + node.operand.accept(this.with(RuntimeContextType.RUNTIME)); + ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/RuntimeList", operator, "()Lorg/perlonjava/RuntimeList;", false); } else { node.operand.accept(this.with(RuntimeContextType.SCALAR)); ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/RuntimeScalar", operator, "()Lorg/perlonjava/RuntimeScalar;", false); diff --git a/src/main/java/org/perlonjava/Parser.java b/src/main/java/org/perlonjava/Parser.java index 55285252..f5cce0b1 100644 --- a/src/main/java/org/perlonjava/Parser.java +++ b/src/main/java/org/perlonjava/Parser.java @@ -319,9 +319,6 @@ private Node parsePrimary() { return new StringNode(token.text, tokenIndex); } switch (token.text) { - case "undef": - // Handle 'undef' keyword as a unary operator with no operand - return new UnaryOperatorNode("undef", null, tokenIndex); case "not": // Handle 'not' keyword as a unary operator with an operand operand = parseExpression(getPrecedence(token.text) + 1); @@ -329,16 +326,22 @@ private Node parsePrimary() { case "abs": case "log": case "rand": + case "undef": String text = token.text; operand = parseZeroOrOneList(0); if (((ListNode) operand).elements.isEmpty()) { - if (text.equals("rand")) { - // create "1" - operand = new NumberNode("1", tokenIndex); - } else { - // create `$_` variable - operand = new UnaryOperatorNode( + switch (text) { + case "undef": + break; // leave it empty + case "rand": + // create "1" + operand = new NumberNode("1", tokenIndex); + break; + default: + // create `$_` variable + operand = new UnaryOperatorNode( "$", new IdentifierNode("_", tokenIndex), tokenIndex); + break; } } return new UnaryOperatorNode(text, operand, tokenIndex); diff --git a/src/main/java/org/perlonjava/RuntimeArray.java b/src/main/java/org/perlonjava/RuntimeArray.java index 33d32d0e..7c86fa8e 100644 --- a/src/main/java/org/perlonjava/RuntimeArray.java +++ b/src/main/java/org/perlonjava/RuntimeArray.java @@ -276,6 +276,11 @@ public boolean getBooleanRef() { return true; } + public RuntimeArray undefine() { + this.elements.clear(); + return this; + } + // Convert the array to a string (for debugging purposes) @Override public String toString() { diff --git a/src/main/java/org/perlonjava/RuntimeHash.java b/src/main/java/org/perlonjava/RuntimeHash.java index 8f070c52..05ef2612 100644 --- a/src/main/java/org/perlonjava/RuntimeHash.java +++ b/src/main/java/org/perlonjava/RuntimeHash.java @@ -233,6 +233,11 @@ public boolean getBooleanRef() { return true; } + public RuntimeHash undefine() { + this.elements.clear(); + return this; + } + // Convert the hash to a string (for debugging purposes) @Override public String toString() { diff --git a/src/main/java/org/perlonjava/RuntimeList.java b/src/main/java/org/perlonjava/RuntimeList.java index 78b52656..273ba302 100644 --- a/src/main/java/org/perlonjava/RuntimeList.java +++ b/src/main/java/org/perlonjava/RuntimeList.java @@ -148,6 +148,20 @@ public Iterator iterator() { // Operators + // undefine the elements of the list + public RuntimeList undefine() { + for (RuntimeBaseEntity elem : elements) { + if (elem instanceof RuntimeScalar) { + ((RuntimeScalar) elem).undefine(); + } else if (elem instanceof RuntimeArray) { + ((RuntimeArray) elem).undefine(); + } else if (elem instanceof RuntimeHash) { + ((RuntimeHash) elem).undefine(); + } + } + return this; + } + public RuntimeScalar print() { StringBuilder sb = new StringBuilder(); for (RuntimeBaseEntity element : elements) { diff --git a/src/main/java/org/perlonjava/RuntimeScalar.java b/src/main/java/org/perlonjava/RuntimeScalar.java index d59595d3..3dd82410 100644 --- a/src/main/java/org/perlonjava/RuntimeScalar.java +++ b/src/main/java/org/perlonjava/RuntimeScalar.java @@ -449,6 +449,11 @@ public static RuntimeScalar undef() { return new RuntimeScalar(); } + public RuntimeScalar undefine() { + this.type = RuntimeScalarType.UNDEF; + return this; + } + public RuntimeScalar stringConcat(RuntimeScalar b) { return new RuntimeScalar(this + b.toString()); }