From 3a3f549c3ff0e59bcefef29e1b870686aebec532 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 24 Jan 2016 15:48:29 +0000 Subject: Introduce separate OperationNode that can be desugarred --- .../org/zwobble/couscous/ast/OperationNode.java | 75 ++++++++++++++++++++++ .../java/org/zwobble/couscous/ast/Operations.java | 34 +++++----- .../frontends/java/JavaExpressionReader.java | 17 ++--- 3 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/ast/OperationNode.java (limited to 'src/main/java') 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 arguments, TypeName type) { + return new OperationNode(operator, arguments, type); + } + + private final Operator operator; + private final List arguments; + private TypeName type; + + OperationNode(Operator operator, List 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 accept(ExpressionNodeMapper 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()); } -- cgit v1.2.3