aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/ast/Operations.java
blob: 308d0705274e42c8618631156caa942cff2e6c63 (plain)
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);
    }
}