diff options
3 files changed, 96 insertions, 1 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java index 36c6b9c..baef84a 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -18,6 +18,8 @@ import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.InfixExpression; +import org.eclipse.jdt.core.dom.InfixExpression.Operator; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Modifier; @@ -48,6 +50,9 @@ import org.zwobble.couscous.ast.StaticMethodCallNode; import org.zwobble.couscous.ast.TernaryConditionalNode; import org.zwobble.couscous.ast.ThisReferenceNode; import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.values.BooleanValue; +import org.zwobble.couscous.values.IntegerValue; + import com.google.common.collect.Lists; import static java.util.Arrays.asList; import static org.zwobble.couscous.ast.ExpressionStatementNode.expressionStatement; @@ -174,6 +179,9 @@ public class JavaReader { case ASTNode.CLASS_INSTANCE_CREATION: return readClassInstanceCreation((ClassInstanceCreation)expression); + case ASTNode.INFIX_EXPRESSION: + return readInfixExpression((InfixExpression)expression); + case ASTNode.CONDITIONAL_EXPRESSION: return readConditionalExpression((ConditionalExpression)expression); @@ -185,7 +193,7 @@ public class JavaReader { } } - + private static ExpressionNode readBooleanLiteral(BooleanLiteral expression) { return LiteralNode.literal(expression.booleanValue()); } @@ -252,6 +260,53 @@ public class JavaReader { return Lists.transform((List<Expression>)javaArguments, JavaReader::readExpression); } + private static ExpressionNode readInfixExpression(InfixExpression expression) { + JavaOperator operator = readOperator(expression.getOperator()); + return MethodCallNode.methodCall( + readExpression(expression.getLeftOperand()), + operator.methodName, + asList(readExpression(expression.getRightOperand())), + operator.returnValue); + } + + private static JavaOperator readOperator(Operator operator) { + if (operator == Operator.PLUS) { + return JavaOperator.of("add", IntegerValue.REF); + } else if (operator == Operator.MINUS) { + return JavaOperator.of("subtract", IntegerValue.REF); + } else if (operator == Operator.TIMES) { + return JavaOperator.of("multiply", IntegerValue.REF); + } else if (operator == Operator.DIVIDE) { + return JavaOperator.of("divide", IntegerValue.REF); + } else if (operator == Operator.REMAINDER) { + return JavaOperator.of("mod", IntegerValue.REF); + } else if (operator == Operator.GREATER) { + return JavaOperator.of("greaterThan", BooleanValue.REF); + } else if (operator == Operator.GREATER_EQUALS) { + return JavaOperator.of("greaterThanOrEqual", BooleanValue.REF); + } else if (operator == Operator.LESS) { + return JavaOperator.of("lessThan", BooleanValue.REF); + } else if (operator == Operator.LESS_EQUALS) { + return JavaOperator.of("lessThanOrEqual", BooleanValue.REF); + } else { + throw new RuntimeException("Unrecognised operator: " + operator); + } + } + + private static class JavaOperator { + private static JavaOperator of(String methodName, TypeName returnValue) { + return new JavaOperator(methodName, returnValue); + } + + private final String methodName; + private final TypeName returnValue; + + private JavaOperator(String methodName, TypeName returnValue) { + this.methodName = methodName; + this.returnValue = returnValue; + } + } + private static ExpressionNode readConditionalExpression(ConditionalExpression expression) { return TernaryConditionalNode.ternaryConditional(readExpression(expression.getExpression()), readExpression(expression.getThenExpression()), readExpression(expression.getElseExpression())); } diff --git a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java index 74b0ae4..b1101ec 100644 --- a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java +++ b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java @@ -3,6 +3,7 @@ package org.zwobble.couscous.tests; import java.nio.file.Files; import java.util.List; +import org.junit.Ignore; import org.junit.Test; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.TypeName; @@ -21,6 +22,13 @@ public class JavaToPythonTests { assertEquals(value(42), evalExpression("42")); } + @Test + @Ignore("WIP") + public void canUseOperatorsOnPrimitives() { + assertEquals(value(3), evalExpression("1 + 2")); + assertEquals(value(false), evalExpression("1 > 2")); + } + private PrimitiveValue evalExpression(String expressionSource) { try { final java.lang.String javaClass = "package com.example;" + "public class Example {" + " public static Object main() {" + " return " + expressionSource + ";" + " }" + "}"; 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 d01830f..ecb4d2a 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 @@ -144,6 +144,38 @@ public class JavaReaderTests { } @Test + public void canUseOperatorsOnIntegers() { + assertEquals( + methodCall(literal(1), "add", asList(literal(2)), IntegerValue.REF), + readExpression("1 + 2")); + assertEquals( + methodCall(literal(1), "subtract", asList(literal(2)), IntegerValue.REF), + readExpression("1 - 2")); + assertEquals( + methodCall(literal(1), "multiply", asList(literal(2)), IntegerValue.REF), + readExpression("1 * 2")); + assertEquals( + methodCall(literal(1), "divide", asList(literal(2)), IntegerValue.REF), + readExpression("1 / 2")); + assertEquals( + methodCall(literal(1), "mod", asList(literal(2)), IntegerValue.REF), + readExpression("1 % 2")); + + assertEquals( + methodCall(literal(1), "greaterThan", asList(literal(2)), BooleanValue.REF), + readExpression("1 > 2")); + assertEquals( + methodCall(literal(1), "greaterThanOrEqual", asList(literal(2)), BooleanValue.REF), + readExpression("1 >= 2")); + assertEquals( + methodCall(literal(1), "lessThan", asList(literal(2)), BooleanValue.REF), + readExpression("1 < 2")); + assertEquals( + methodCall(literal(1), "lessThanOrEqual", asList(literal(2)), BooleanValue.REF), + readExpression("1 <= 2")); + } + + @Test public void canReadTernaryConditionals() { assertEquals( ternaryConditional(literal(true), literal(1), literal(2)), |
