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
|
package org.zwobble.couscous.ast;
import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Types;
import org.zwobble.couscous.values.InternalCouscousValue;
import static org.zwobble.couscous.ast.MethodCallNode.methodCall;
import static org.zwobble.couscous.ast.MethodCallNode.staticMethodCall;
import static org.zwobble.couscous.ast.TypeCoercionNode.coerce;
import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.util.ExtraLists.list;
public class Operations {
public static ExpressionNode same(ExpressionNode left, ExpressionNode right) {
return staticMethodCall(InternalCouscousValue.REF, "same", list(left, right), Types.BOOLEAN);
}
public static ExpressionNode not(ExpressionNode value) {
if (value.getType().equals(Types.BOOLEAN)) {
return OperationNode.operation(
Operator.BOOLEAN_NOT, list(value),
Types.BOOLEAN);
} else {
throw new IllegalArgumentException("Can only negate booleans");
}
}
public static ExpressionNode booleanAnd(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.BOOLEAN_AND, left, right);
}
public static ExpressionNode booleanOr(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.BOOLEAN_OR, left, right);
}
public static ExpressionNode integerAdd(ExpressionNode left, ExpressionNode right) {
return integerOperation(Operator.ADD, left, right);
}
public static ExpressionNode integerSubtract(ExpressionNode left, ExpressionNode right) {
return integerOperation(Operator.SUBTRACT, left, right);
}
public static ExpressionNode integerMultiply(ExpressionNode left, ExpressionNode right) {
return integerOperation(Operator.MULTIPLY, left, right);
}
public static ExpressionNode integerDivide(ExpressionNode left, ExpressionNode right) {
return integerOperation(Operator.DIVIDE, left, right);
}
public static ExpressionNode integerMod(ExpressionNode left, ExpressionNode right) {
return integerOperation(Operator.MOD, left, right);
}
public static ExpressionNode integerOperation(Operator operator, ExpressionNode left, ExpressionNode right) {
return new OperationNode(operator, list(left, right), Types.INT);
}
public static ExpressionNode equal(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.EQUALS, left, right);
}
public static ExpressionNode notEqual(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.NOT_EQUALS, left, right);
}
public static ExpressionNode greaterThan(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.GREATER_THAN, left, right);
}
public static ExpressionNode greaterThanOrEqual(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.GREATER_THAN_OR_EQUAL, left, right);
}
public static ExpressionNode lessThan(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.LESS_THAN, left, right);
}
public static ExpressionNode lessThanOrEqual(ExpressionNode left, ExpressionNode right) {
return booleanOperation(Operator.LESS_THAN_OR_EQUAL, left, right);
}
private static ExpressionNode booleanOperation(Operator operator, ExpressionNode left, ExpressionNode right) {
return new OperationNode(operator, list(left, right), Types.BOOLEAN);
}
public static ExpressionNode boxInt(ExpressionNode value) {
return typeCoercion(value, Types.BOXED_INT);
}
public static ExpressionNode unboxInt(ExpressionNode value) {
return typeCoercion(value, Types.INT);
}
public static ExpressionNode instanceOf(ExpressionNode value, ScalarType type) {
return new InstanceOfNode(value, type);
}
public static ExpressionNode methodEquals(ExpressionNode left, ExpressionNode right) {
return methodCall(left, "equals", list(coerce(right, Types.OBJECT)), Types.BOOLEAN);
}
}
|