From eda05cc1e2f845b4e7c3eeea505c535432240197 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 30 Mar 2016 14:16:10 +0100 Subject: Read extended operands in infix operations --- .../frontends/java/JavaExpressionReader.java | 32 ++++++++++++++-------- src/main/java/org/zwobble/couscous/util/Fold.java | 9 ++++++ .../frontends/java/ExpressionReadingTests.java | 3 ++ 3 files changed, 32 insertions(+), 12 deletions(-) (limited to 'src') 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 72cba9b..4adb92c 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaExpressionReader.java @@ -1,5 +1,6 @@ package org.zwobble.couscous.frontends.java; +import com.google.common.collect.Iterables; import org.eclipse.jdt.core.dom.*; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.types.Type; @@ -19,8 +20,8 @@ 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; import static org.zwobble.couscous.frontends.java.JavaTypes.typeOf; -import static org.zwobble.couscous.util.ExtraLists.concat; -import static org.zwobble.couscous.util.ExtraLists.list; +import static org.zwobble.couscous.util.ExtraLists.*; +import static org.zwobble.couscous.util.Fold.foldLeft; public class JavaExpressionReader { private final Scope scope; @@ -264,10 +265,7 @@ public class JavaExpressionReader { private ExpressionNode readInfixExpression(InfixExpression expression) { if (isPrimitiveOperation(expression)) { Operator operator = readOperator(expression.getOperator()); - return readPrimitiveOperation( - operator, - expression.getLeftOperand(), - expression.getRightOperand()); + return readPrimitiveOperation(operator, operands(expression)); } else { ExpressionNode left = readExpression(Types.OBJECT, expression.getLeftOperand()); ExpressionNode right = readExpression(Types.OBJECT, expression.getRightOperand()); @@ -281,7 +279,17 @@ public class JavaExpressionReader { } } + private Iterable operands(InfixExpression expression) { + @SuppressWarnings("unchecked") + List extendedOperands = expression.extendedOperands(); + return Iterables.concat( + list(expression.getLeftOperand()), + list(expression.getRightOperand()), + extendedOperands); + } + private static boolean isPrimitiveOperation(InfixExpression expression) { + // TODO: consider expression.extendedOperands Type leftOperandType = typeOf(expression.getLeftOperand()); Type rightOperandType = typeOf(expression.getRightOperand()); return isPrimitive(leftOperandType) @@ -329,17 +337,17 @@ public class JavaExpressionReader { left, coerceExpression( left.getType(), - readPrimitiveOperation(operator, expression.getLeftHandSide(), expression.getRightHandSide()))); + readPrimitiveOperation(operator, list(expression.getLeftHandSide(), expression.getRightHandSide())))); } } - private ExpressionNode readPrimitiveOperation(Operator operator, Expression leftJava, Expression rightJava) { - ExpressionNode left = readUnboxedExpression(leftJava); - ExpressionNode right = readUnboxedExpression(rightJava); - return operation( + private ExpressionNode readPrimitiveOperation(Operator operator, Iterable javaOperands) { + List operands = eagerMap(javaOperands, operand -> readUnboxedExpression(operand)); + return foldLeft(operands, (left, right) -> operation( operator, list(left, right), - operator.isBoolean() ? Types.BOOLEAN : left.getType()); + operator.isBoolean() ? Types.BOOLEAN : left.getType()) + ); } private ExpressionNode readCastExpression(CastExpression expression) { diff --git a/src/main/java/org/zwobble/couscous/util/Fold.java b/src/main/java/org/zwobble/couscous/util/Fold.java index e86454e..bda680d 100644 --- a/src/main/java/org/zwobble/couscous/util/Fold.java +++ b/src/main/java/org/zwobble/couscous/util/Fold.java @@ -2,6 +2,7 @@ package org.zwobble.couscous.util; import com.google.common.collect.Lists; +import java.util.Iterator; import java.util.List; import java.util.function.BiFunction; @@ -13,6 +14,14 @@ public class Fold { } return value; } + public static T foldLeft(Iterable iterable, BiFunction function) { + Iterator iterator = iterable.iterator(); + T value = iterator.next(); + while (iterator.hasNext()) { + value = function.apply(value, iterator.next()); + } + return value; + } public static V foldRight(List iterable, V initialValue, BiFunction function) { return foldLeft(Lists.reverse(iterable), initialValue, function); diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java index b1f5049..2f35064 100644 --- a/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java +++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/ExpressionReadingTests.java @@ -260,6 +260,9 @@ public class ExpressionReadingTests { assertEquals( integerMultiply(literal(1), literal(2)), readIntExpression("1 * 2")); + assertEquals( + integerMultiply(integerMultiply(literal(1), literal(2)), literal(3)), + readIntExpression("1 * 2 * 3")); assertEquals( integerDivide(literal(1), literal(2)), readIntExpression("1 / 2")); -- cgit v1.2.3