aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-01-24 15:48:29 +0000
committerMichael Williamson <mike@zwobble.org>2016-01-24 15:48:29 +0000
commit3a3f549c3ff0e59bcefef29e1b870686aebec532 (patch)
treec0f0644a90ff65a22bd21ac2271f4db9894a0738 /src
parent5941365d936f73e48381db5eb444345e5f358e75 (diff)
Introduce separate OperationNode that can be desugarred
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/OperationNode.java75
-rw-r--r--src/main/java/org/zwobble/couscous/ast/Operations.java34
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java17
-rw-r--r--src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java7
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java2
5 files changed, 109 insertions, 26 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/OperationNode.java b/src/main/java/org/zwobble/couscous/ast/OperationNode.java
new file mode 100644
index 0000000..c3447ef
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/ast/OperationNode.java
@@ -0,0 +1,75 @@
+package org.zwobble.couscous.ast;
+
+import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
+import org.zwobble.couscous.ast.visitors.NodeTransformer;
+
+import java.util.List;
+
+public class OperationNode implements ExpressionNode {
+ public static OperationNode operation(Operator operator, List<ExpressionNode> arguments, TypeName type) {
+ return new OperationNode(operator, arguments, type);
+ }
+
+ private final Operator operator;
+ private final List<ExpressionNode> arguments;
+ private TypeName type;
+
+ OperationNode(Operator operator, List<ExpressionNode> arguments, TypeName type) {
+ this.operator = operator;
+ this.arguments = arguments;
+ this.type = type;
+ }
+
+ public ExpressionNode desugar() {
+ return MethodCallNode.methodCall(
+ arguments.get(0),
+ operator.getMethodName(),
+ arguments.subList(1, arguments.size()),
+ type);
+ }
+
+ @Override
+ public TypeName getType() {
+ return type;
+ }
+
+ @Override
+ public <T> T accept(ExpressionNodeMapper<T> visitor) {
+ return desugar().accept(visitor);
+ }
+
+ @Override
+ public ExpressionNode transform(NodeTransformer transformer) {
+ return desugar().transform(transformer);
+ }
+
+ @Override
+ public String toString() {
+ return "OperationNode(" +
+ "operator=" + operator +
+ ", arguments=" + arguments +
+ ", type=" + type +
+ ')';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ OperationNode that = (OperationNode) o;
+
+ if (operator != that.operator) return false;
+ if (!arguments.equals(that.arguments)) return false;
+ return type.equals(that.type);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = operator.hashCode();
+ result = 31 * result + arguments.hashCode();
+ result = 31 * result + type.hashCode();
+ return result;
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/ast/Operations.java b/src/main/java/org/zwobble/couscous/ast/Operations.java
index 40d9672..5af2f8b 100644
--- a/src/main/java/org/zwobble/couscous/ast/Operations.java
+++ b/src/main/java/org/zwobble/couscous/ast/Operations.java
@@ -26,63 +26,63 @@ public class Operations {
}
public static ExpressionNode booleanAnd(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.BOOLEAN_AND.getMethodName(), left, right);
+ return booleanOperation(Operator.BOOLEAN_AND, left, right);
}
public static ExpressionNode booleanOr(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.BOOLEAN_OR.getMethodName(), left, right);
+ return booleanOperation(Operator.BOOLEAN_OR, left, right);
}
public static ExpressionNode integerAdd(ExpressionNode left, ExpressionNode right) {
- return integerOperation(Operator.ADD.getMethodName(), left, right);
+ return integerOperation(Operator.ADD, left, right);
}
public static ExpressionNode integerSubtract(ExpressionNode left, ExpressionNode right) {
- return integerOperation(Operator.SUBTRACT.getMethodName(), left, right);
+ return integerOperation(Operator.SUBTRACT, left, right);
}
public static ExpressionNode integerMultiply(ExpressionNode left, ExpressionNode right) {
- return integerOperation(Operator.MULTIPLY.getMethodName(), left, right);
+ return integerOperation(Operator.MULTIPLY, left, right);
}
public static ExpressionNode integerDivide(ExpressionNode left, ExpressionNode right) {
- return integerOperation(Operator.DIVIDE.getMethodName(), left, right);
+ return integerOperation(Operator.DIVIDE, left, right);
}
public static ExpressionNode integerMod(ExpressionNode left, ExpressionNode right) {
- return integerOperation(Operator.MOD.getMethodName(), left, right);
+ return integerOperation(Operator.MOD, left, right);
}
- public static MethodCallNode integerOperation(String methodName, ExpressionNode left, ExpressionNode right) {
- return methodCall(left, methodName, list(right), IntegerValue.REF);
+ public static ExpressionNode integerOperation(Operator operator, ExpressionNode left, ExpressionNode right) {
+ return new OperationNode(operator, list(left, right), IntegerValue.REF);
}
public static ExpressionNode equal(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.EQUALS.getMethodName(), left, right);
+ return booleanOperation(Operator.EQUALS, left, right);
}
public static ExpressionNode notEqual(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.NOT_EQUALS.getMethodName(), left, right);
+ return booleanOperation(Operator.NOT_EQUALS, left, right);
}
public static ExpressionNode greaterThan(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.GREATER_THAN.getMethodName(), left, right);
+ return booleanOperation(Operator.GREATER_THAN, left, right);
}
public static ExpressionNode greaterThanOrEqual(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.GREATER_THAN_OR_EQUAL.getMethodName(), left, right);
+ return booleanOperation(Operator.GREATER_THAN_OR_EQUAL, left, right);
}
public static ExpressionNode lessThan(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.LESS_THAN.getMethodName(), left, right);
+ return booleanOperation(Operator.LESS_THAN, left, right);
}
public static ExpressionNode lessThanOrEqual(ExpressionNode left, ExpressionNode right) {
- return booleanOperation(Operator.LESS_THAN_OR_EQUAL.getMethodName(), left, right);
+ return booleanOperation(Operator.LESS_THAN_OR_EQUAL, left, right);
}
- private static ExpressionNode booleanOperation(String methodName, ExpressionNode left, ExpressionNode right) {
- return methodCall(left, methodName, list(right), BooleanValue.REF);
+ private static ExpressionNode booleanOperation(Operator operator, ExpressionNode left, ExpressionNode right) {
+ return new OperationNode(operator, list(left, right), BooleanValue.REF);
}
public static ExpressionNode boxInt(ExpressionNode value) {
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
index 86a3868..ba08fd8 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java
@@ -14,6 +14,7 @@ import static org.zwobble.couscous.ast.CastNode.cast;
import static org.zwobble.couscous.ast.ConstructorCallNode.constructorCall;
import static org.zwobble.couscous.ast.LiteralNode.literal;
import static org.zwobble.couscous.ast.MethodCallNode.staticMethodCall;
+import static org.zwobble.couscous.ast.OperationNode.operation;
import static org.zwobble.couscous.ast.Operations.not;
import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion;
import static org.zwobble.couscous.frontends.java.JavaOperators.readOperator;
@@ -270,10 +271,11 @@ public class JavaExpressionReader {
Operator operator = readOperator(expression.getOperator());
return AssignmentNode.assign(
(AssignableExpressionNode) readExpressionWithoutBoxing(expression.getOperand()),
- MethodCallNode.methodCall(
- readExpression(IntegerValue.REF, expression.getOperand()),
- operator.getMethodName(),
- list(literal(1)),
+ operation(
+ operator,
+ list(
+ readExpression(IntegerValue.REF, expression.getOperand()),
+ literal(1)),
IntegerValue.REF));
}
}
@@ -304,10 +306,9 @@ public class JavaExpressionReader {
private ExpressionNode readPrimitiveOperation(Operator operator, Expression leftJava, Expression rightJava) {
ExpressionNode left = readUnboxedExpression(leftJava);
ExpressionNode right = readUnboxedExpression(rightJava);
- return MethodCallNode.methodCall(
- left,
- operator.getMethodName(),
- list(right),
+ return operation(
+ operator,
+ list(left, right),
operator.isBoolean() ? BooleanValue.REF : left.getType());
}
diff --git a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
index a9be381..ce8ab87 100644
--- a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java
@@ -55,6 +55,7 @@ public class ValueObjectTests {
{LocalVariableDeclarationNode.class},
{MethodCallNode.class},
{MethodNode.class},
+ {OperationNode.class},
{ReturnNode.class},
{StaticReceiver.class},
{TernaryConditionalNode.class},
@@ -135,6 +136,8 @@ public class ValueObjectTests {
return list("[list 1]");
} else if (type.equals(Set.class)) {
return Collections.singleton("[set 1]");
+ } else if (type.equals(Operator.class)) {
+ return Operator.DIVIDE;
} else if (type.equals(Identifier.class)) {
return TestIds.id((String)generateFirstInstance(String.class));
} else if (type.equals(PrimitiveValue.class)) {
@@ -159,6 +162,8 @@ public class ValueObjectTests {
return list("[list 2]");
} else if (type.equals(Set.class)) {
return Collections.singleton("[set 2]");
+ } else if (type.equals(Operator.class)) {
+ return Operator.MULTIPLY;
} else if (type.equals(Identifier.class)) {
return TestIds.id((String)generateSecondInstance(String.class));
} else if (type.equals(PrimitiveValue.class)) {
@@ -183,6 +188,8 @@ public class ValueObjectTests {
return list("[list]");
} else if (type.equals(Set.class)) {
return Collections.singleton("[set]");
+ } else if (type.equals(Operator.class)) {
+ return Operator.ADD;
} else if (type.equals(Identifier.class)) {
return TestIds.id((String)generateInstance(String.class));
} else if (type.equals(PrimitiveValue.class)) {
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
index cb1f3ac..6bc0816 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
@@ -470,7 +470,7 @@ public class JavaReaderTests {
assertEquals(
assign(
reference(argument),
- integerOperation(operator.getMethodName(), reference(argument), literal(2))),
+ integerOperation(operator, reference(argument), literal(2))),
statement.getExpression());
}