Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
fglock committed Oct 21, 2024
1 parent f42a37a commit 0e03fba
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 91 deletions.
112 changes: 57 additions & 55 deletions src/main/java/org/perlonjava/codegen/EmitRegex.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,67 +57,69 @@ static void handleRegex(EmitterVisitor emitterVisitor, OperatorNode node) {
EmitterVisitor scalarVisitor = emitterVisitor.with(RuntimeContextType.SCALAR);
Node variable = null;

if (node.operator.equals("qx")) {
// static RuntimeScalar systemCommand(RuntimeScalar command)
operand.elements.get(0).accept(scalarVisitor);
emitterVisitor.pushCallContext();
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeIO",
"systemCommand",
"(Lorg/perlonjava/runtime/RuntimeScalar;I)Lorg/perlonjava/runtime/RuntimeDataProvider;", false);
if (emitterVisitor.ctx.contextType == RuntimeContextType.VOID) {
emitterVisitor.ctx.mv.visitInsn(Opcodes.POP);
}
return;
}

if (node.operator.equals("tr") || node.operator.equals("y")) {
// static RuntimeTransliterate compile(RuntimeScalar search, RuntimeScalar replace, RuntimeScalar modifiers)
operand.elements.get(0).accept(scalarVisitor);
operand.elements.get(1).accept(scalarVisitor);
operand.elements.get(2).accept(scalarVisitor);
if (operand.elements.size() > 3) {
variable = operand.elements.get(3);
switch (node.operator) {
case "qx" -> {
// static RuntimeScalar systemCommand(RuntimeScalar command)
operand.elements.getFirst().accept(scalarVisitor);
emitterVisitor.pushCallContext();
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeIO",
"systemCommand",
"(Lorg/perlonjava/runtime/RuntimeScalar;I)Lorg/perlonjava/runtime/RuntimeDataProvider;", false);
if (emitterVisitor.ctx.contextType == RuntimeContextType.VOID) {
emitterVisitor.ctx.mv.visitInsn(Opcodes.POP);
}
return;
}
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeTransliterate", "compile",
"(Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeTransliterate;", false);
case "tr", "y" -> {
// static RuntimeTransliterate compile(RuntimeScalar search, RuntimeScalar replace, RuntimeScalar modifiers)
operand.elements.get(0).accept(scalarVisitor);
operand.elements.get(1).accept(scalarVisitor);
operand.elements.get(2).accept(scalarVisitor);
if (operand.elements.size() > 3) {
variable = operand.elements.get(3);
}
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeTransliterate", "compile",
"(Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeTransliterate;", false);

// RuntimeScalar transliterate(RuntimeScalar originalString)
if (variable == null) {
// use `$_`
variable = new OperatorNode("$", new IdentifierNode("_", node.tokenIndex), node.tokenIndex);
}
variable.accept(scalarVisitor);
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/runtime/RuntimeTransliterate", "transliterate", "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);
if (emitterVisitor.ctx.contextType == RuntimeContextType.VOID) {
emitterVisitor.ctx.mv.visitInsn(Opcodes.POP);
// RuntimeScalar transliterate(RuntimeScalar originalString)
if (variable == null) {
// use `$_`
variable = new OperatorNode("$", new IdentifierNode("_", node.tokenIndex), node.tokenIndex);
}
variable.accept(scalarVisitor);
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/runtime/RuntimeTransliterate", "transliterate", "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);
if (emitterVisitor.ctx.contextType == RuntimeContextType.VOID) {
emitterVisitor.ctx.mv.visitInsn(Opcodes.POP);
}
return;
}
return;

} else if (node.operator.equals("replaceRegex")) {
// RuntimeBaseEntity replaceRegex(RuntimeScalar quotedRegex, RuntimeScalar string, RuntimeScalar replacement, int ctx)
operand.elements.get(0).accept(scalarVisitor);
operand.elements.get(1).accept(scalarVisitor);
operand.elements.get(2).accept(scalarVisitor);
if (operand.elements.size() > 3) {
variable = operand.elements.get(3);
case "replaceRegex" -> {
// RuntimeBaseEntity replaceRegex(RuntimeScalar quotedRegex, RuntimeScalar string, RuntimeScalar replacement, int ctx)
operand.elements.get(0).accept(scalarVisitor);
operand.elements.get(1).accept(scalarVisitor);
operand.elements.get(2).accept(scalarVisitor);
if (operand.elements.size() > 3) {
variable = operand.elements.get(3);
}
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeRegex", "getReplacementRegex",
"(Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);
}
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeRegex", "getReplacementRegex",
"(Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);

} else {
// RuntimeRegex.getQuotedRegex(RuntimeScalar patternString, RuntimeScalar modifiers)
operand.elements.get(0).accept(scalarVisitor);
operand.elements.get(1).accept(scalarVisitor);
if (operand.elements.size() > 2) {
variable = operand.elements.get(2);
default -> {
// RuntimeRegex.getQuotedRegex(RuntimeScalar patternString, RuntimeScalar modifiers)
operand.elements.get(0).accept(scalarVisitor);
operand.elements.get(1).accept(scalarVisitor);
if (operand.elements.size() > 2) {
variable = operand.elements.get(2);
}
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeRegex", "getQuotedRegex",
"(Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);
}
emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"org/perlonjava/runtime/RuntimeRegex", "getQuotedRegex",
"(Lorg/perlonjava/runtime/RuntimeScalar;Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);
}

if (node.operator.equals("quoteRegex")) {
// do not execute `qr//`
return;
Expand Down
26 changes: 10 additions & 16 deletions src/main/java/org/perlonjava/codegen/EmitterMethodCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,11 @@ public static String getVariableDescriptor(String varName) {
char firstChar = varName.charAt(0);

// Use a switch statement to determine the descriptor based on the first character
switch (firstChar) {
case '%':
return "Lorg/perlonjava/runtime/RuntimeHash;";
case '@':
return "Lorg/perlonjava/runtime/RuntimeArray;";
default:
return "Lorg/perlonjava/runtime/RuntimeScalar;";
}
return switch (firstChar) {
case '%' -> "Lorg/perlonjava/runtime/RuntimeHash;";
case '@' -> "Lorg/perlonjava/runtime/RuntimeArray;";
default -> "Lorg/perlonjava/runtime/RuntimeScalar;";
};
}

/**
Expand All @@ -71,14 +68,11 @@ public static String getVariableClassName(String varName) {
char firstChar = varName.charAt(0);

// Use a switch statement to determine the class name based on the first character
switch (firstChar) {
case '%':
return "org/perlonjava/runtime/RuntimeHash";
case '@':
return "org/perlonjava/runtime/RuntimeArray";
default:
return "org/perlonjava/runtime/RuntimeScalar";
}
return switch (firstChar) {
case '%' -> "org/perlonjava/runtime/RuntimeHash";
case '@' -> "org/perlonjava/runtime/RuntimeArray";
default -> "org/perlonjava/runtime/RuntimeScalar";
};
}

/**
Expand Down
33 changes: 13 additions & 20 deletions src/main/java/org/perlonjava/codegen/EmitterVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ private void handleArrayElementOperator(BinaryOperatorNode node) {
ArrayLiteralNode right = (ArrayLiteralNode) node.right;
if (right.elements.size() == 1) {
// Optimization: Extract the single element if the list has only one item
Node elem = right.elements.get(0);
Node elem = right.elements.getFirst();
elem.accept(this.with(RuntimeContextType.SCALAR));
} else {
// emit the [0] as a RuntimeList
Expand Down Expand Up @@ -400,7 +400,7 @@ public void handleHashElementOperator(BinaryOperatorNode node, String hashOperat
// emit the {x} as a RuntimeList
ListNode nodeRight = ((HashLiteralNode) node.right).asListNode();

Node nodeZero = nodeRight.elements.get(0);
Node nodeZero = nodeRight.elements.getFirst();
if (nodeRight.elements.size() == 1 && nodeZero instanceof IdentifierNode) {
// Convert IdentifierNode to StringNode: {a} to {"a"}
nodeRight.elements.set(0, new StringNode(((IdentifierNode) nodeZero).name, ((IdentifierNode) nodeZero).tokenIndex));
Expand Down Expand Up @@ -434,7 +434,7 @@ public void handleHashElementOperator(BinaryOperatorNode node, String hashOperat
// emit the {x} as a RuntimeList
ListNode nodeRight = ((HashLiteralNode) node.right).asListNode();

Node nodeZero = nodeRight.elements.get(0);
Node nodeZero = nodeRight.elements.getFirst();
if (nodeRight.elements.size() == 1 && nodeZero instanceof IdentifierNode) {
// Convert IdentifierNode to StringNode: {a} to {"a"}
nodeRight.elements.set(0, new StringNode(((IdentifierNode) nodeZero).name, ((IdentifierNode) nodeZero).tokenIndex));
Expand Down Expand Up @@ -537,7 +537,7 @@ private void handleArrowArrayDeref(BinaryOperatorNode node, String arrayOperatio
ArrayLiteralNode right = (ArrayLiteralNode) node.right;
if (right.elements.size() == 1) {
// Optimization: Extract the single element if the list has only one item
Node elem = right.elements.get(0);
Node elem = right.elements.getFirst();
elem.accept(this.with(RuntimeContextType.SCALAR));
} else {
// emit the [0] as a RuntimeList
Expand Down Expand Up @@ -570,7 +570,7 @@ public void handleArrowHashDeref(BinaryOperatorNode node, String hashOperation)
// emit the {0} as a RuntimeList
ListNode nodeRight = ((HashLiteralNode) node.right).asListNode();

Node nodeZero = nodeRight.elements.get(0);
Node nodeZero = nodeRight.elements.getFirst();
if (nodeRight.elements.size() == 1 && nodeZero instanceof IdentifierNode) {
// Convert IdentifierNode to StringNode: {a} to {"a"}
nodeRight.elements.set(0, new StringNode(((IdentifierNode) nodeZero).name, ((IdentifierNode) nodeZero).tokenIndex));
Expand All @@ -579,20 +579,13 @@ public void handleArrowHashDeref(BinaryOperatorNode node, String hashOperation)
ctx.logDebug("visit -> (HashLiteralNode) autoquote " + node.right);
nodeRight.accept(this.with(RuntimeContextType.SCALAR));

String methodName;
switch (hashOperation) {
case "get":
methodName = "hashDerefGet";
break;
case "delete":
methodName = "hashDerefDelete";
break;
case "exists":
methodName = "hashDerefExists";
break;
default:
throw new PerlCompilerException(node.tokenIndex, "Not implemented: hash operation: " + hashOperation, ctx.errorUtil);
}
String methodName = switch (hashOperation) {
case "get" -> "hashDerefGet";
case "delete" -> "hashDerefDelete";
case "exists" -> "hashDerefExists";
default ->
throw new PerlCompilerException(node.tokenIndex, "Not implemented: hash operation: " + hashOperation, ctx.errorUtil);
};

ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/runtime/RuntimeScalar", methodName, "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false);
}
Expand Down Expand Up @@ -643,7 +636,7 @@ private void handleArrayUnaryBuiltin(OperatorNode node, String operator) {
Node operand = node.operand;
ctx.logDebug("handleArrayUnaryBuiltin " + operand);
if (operand instanceof ListNode) {
operand = ((ListNode) operand).elements.get(0);
operand = ((ListNode) operand).elements.getFirst();
}
operand.accept(this.with(RuntimeContextType.LIST));
ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/runtime/RuntimeArray", operator, "()Lorg/perlonjava/runtime/RuntimeScalar;", false);
Expand Down

0 comments on commit 0e03fba

Please sign in to comment.