-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathEmitBinaryOperatorNode.java
More file actions
104 lines (76 loc) · 5.06 KB
/
EmitBinaryOperatorNode.java
File metadata and controls
104 lines (76 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package org.perlonjava.backend.jvm;
import org.perlonjava.app.cli.CompilerOptions;
import org.objectweb.asm.Opcodes;
import org.perlonjava.frontend.analysis.EmitterVisitor;
import org.perlonjava.frontend.astnode.BinaryOperatorNode;
import org.perlonjava.runtime.operators.OperatorHandler;
import org.perlonjava.runtime.runtimetypes.PerlCompilerException;
public class EmitBinaryOperatorNode {
public static void emitBinaryOperatorNode(EmitterVisitor emitterVisitor, BinaryOperatorNode node) {
if (CompilerOptions.DEBUG_ENABLED) emitterVisitor.ctx.logDebug("visit(BinaryOperatorNode) %s in context %s"
.formatted(node.operator, emitterVisitor.ctx.contextType));
switch (node.operator) {
// Logical operators with short-circuit evaluation
case "||", "or" ->
EmitLogicalOperator.emitLogicalOperator(emitterVisitor, node, Opcodes.IFNE, "getBoolean");
case "||=" -> EmitLogicalOperator.emitLogicalAssign(emitterVisitor, node, Opcodes.IFNE, "getBoolean");
case "&&", "and" ->
EmitLogicalOperator.emitLogicalOperator(emitterVisitor, node, Opcodes.IFEQ, "getBoolean");
case "&&=" -> EmitLogicalOperator.emitLogicalAssign(emitterVisitor, node, Opcodes.IFEQ, "getBoolean");
case "//" ->
EmitLogicalOperator.emitLogicalOperator(emitterVisitor, node, Opcodes.IFNE, "getDefinedBoolean");
case "//=" ->
EmitLogicalOperator.emitLogicalAssign(emitterVisitor, node, Opcodes.IFNE, "getDefinedBoolean");
case "xor", "^^" -> EmitLogicalOperator.emitXorOperator(emitterVisitor, node);
// Assignment operator
case "=" -> EmitVariable.handleAssignOperator(emitterVisitor, node);
// String concatenation
case "." -> EmitOperator.handleConcatOperator(emitterVisitor, node);
// Dereference operators
case "->" -> Dereference.handleArrowOperator(emitterVisitor, node);
case "[" -> Dereference.handleArrayElementOperator(emitterVisitor, node, "get");
case "{" -> Dereference.handleHashElementOperator(emitterVisitor, node, "get");
case "(" -> EmitSubroutine.handleApplyOperator(emitterVisitor, node);
// Array manipulation
case "push", "unshift" -> EmitOperator.handlePushOperator(emitterVisitor, node);
// Higher-order functions
case "map", "sort", "grep", "all", "any" -> EmitOperator.handleMapOperator(emitterVisitor, node);
// I/O operations
case "eof", "printf", "print", "say" -> EmitOperator.handleSayOperator(emitterVisitor, node);
case "close", "readline", "fileno", "getc", "tell" ->
EmitOperator.handleReadlineOperator(emitterVisitor, node);
case "binmode", "seek", "sysseek" -> EmitOperator.handleBinmodeOperator(emitterVisitor, node);
// String operations
case "join", "sprintf" -> EmitOperator.handleSubstr(emitterVisitor, node);
case "split" -> EmitOperator.handleSplit(emitterVisitor, node);
case "x" -> EmitOperator.handleRepeat(emitterVisitor, node);
// Regex operations
case "!~" -> EmitRegex.handleNotBindRegex(emitterVisitor, node);
case "=~" -> EmitRegex.handleBindRegex(emitterVisitor, node);
// Compound assignment operators
case "**=", "+=", "*=", "&=", "&.=", "binary&=", "<<=", "-=", "/=",
"|=", "|.=", "binary|=", ">>=", ".=", "%=", "^=", "^.=",
"binary^=", "x=", "^^=" -> EmitBinaryOperator.handleCompoundAssignment(emitterVisitor, node);
// Range and flip-flop operators
case "..." -> EmitLogicalOperator.emitFlipFlopOperator(emitterVisitor, node);
case ".." -> EmitBinaryOperator.handleRangeOrFlipFlop(emitterVisitor, node);
// Comparison operators (chained)
case "<", ">", "<=", ">=", "lt", "gt", "le", "ge",
"==", "!=", "eq", "ne" -> EmitOperatorChained.emitChainedComparison(emitterVisitor, node);
// Binary operators
case "%", "&", "&.", "binary&", "*", "**", "+", "-", "/",
"<<", "<=>", ">>", "^", "^.", "binary^", "|", "|.", "binary|",
"bless", "cmp", "isa", "~~" -> {
// Check if uninitialized warnings are enabled at compile time
// Use warn variant for zero-overhead when warnings disabled
boolean warnUninit = emitterVisitor.ctx.symbolTable.isWarningCategoryEnabled("uninitialized");
OperatorHandler handler = warnUninit
? OperatorHandler.getWarn(node.operator)
: OperatorHandler.get(node.operator);
EmitBinaryOperator.handleBinaryOperator(emitterVisitor, node, handler);
}
default -> throw new PerlCompilerException(node.tokenIndex,
"Not implemented operator: " + node.operator, emitterVisitor.ctx.errorUtil);
}
}
}