diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-31 18:44:13 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-31 18:44:13 +0000 |
| commit | 971fb3c743df26c408d752f1bc4137e645f455a2 (patch) | |
| tree | 995caf9c1cfcc0e4d3ce7da683d59e95fb517d42 /src/main/java/org | |
| parent | a5e68ab6528f62c891479f387877118f90dfa2b8 (diff) | |
Add partial support for boxing integers
Diffstat (limited to 'src/main/java/org')
6 files changed, 76 insertions, 27 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java index 4af0701..36fea9f 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -5,6 +5,7 @@ import java.util.List; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.InternalCouscousValue; +import org.zwobble.couscous.values.ObjectValues; import static java.util.Arrays.asList; @@ -13,6 +14,14 @@ public class StaticMethodCallNode implements ExpressionNode { return staticMethodCall(InternalCouscousValue.REF, "same", asList(left, right), BooleanValue.REF); } + public static ExpressionNode boxInt(ExpressionNode value) { + return staticMethodCall( + InternalCouscousValue.REF, + "boxInt", + asList(value), + ObjectValues.BOXED_INT); + } + public static StaticMethodCallNode staticMethodCall( String className, String methodName, diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java index 0f8d963..c8e13b0 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaParser.java @@ -5,6 +5,8 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Hashtable; + import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; @@ -18,8 +20,17 @@ public class JavaParser { parser = ASTParser.newParser(AST.JLS8); parser.setBindingsRecovery(true); parser.setKind(ASTParser.K_COMPILATION_UNIT); - parser.setCompilerOptions(JavaCore.getOptions()); - parser.setEnvironment(new String[]{"/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar"}, new String[0], new String[0], false); + @SuppressWarnings("unchecked") + Hashtable<String, String> options = JavaCore.getOptions(); + options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); + options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); + options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); + parser.setCompilerOptions(options); + parser.setEnvironment( + new String[]{"/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar"}, + new String[]{"/usr/lib/jvm/java-8-openjdk-amd64/jre/src.zip"}, + new String[]{"UTF-8"}, + false); parser.setResolveBindings(true); } 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 c08e447..a74cb35 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -3,6 +3,8 @@ package org.zwobble.couscous.frontends.java; import java.io.IOException; import java.nio.file.Path; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.Assignment; @@ -53,6 +55,7 @@ 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 org.zwobble.couscous.values.ObjectValues; import static java.util.Arrays.asList; import static org.zwobble.couscous.ast.ExpressionStatementNode.expressionStatement; @@ -141,11 +144,12 @@ public class JavaReader { } private static StatementNode readReturnStatement(ReturnStatement statement) { - return ReturnNode.returns(readExpression(statement.getExpression())); + // TODO: set target type + return ReturnNode.returns(readExpressionWithoutBoxing(statement.getExpression())); } private static StatementNode readExpressionStatement(ExpressionStatement statement) { - return expressionStatement(readExpression(statement.getExpression())); + return expressionStatement(readExpressionWithoutBoxing(statement.getExpression())); } private static List<StatementNode> readVariableDeclarationStatement(VariableDeclarationStatement statement) { @@ -157,10 +161,19 @@ public class JavaReader { fragment.resolveBinding().getKey(), fragment.getName().getIdentifier(), type, - readExpression(fragment.getInitializer()))); + readExpression(type, fragment.getInitializer()))); } - private static ExpressionNode readExpression(Expression expression) { + private static ExpressionNode readExpression(TypeName targetType, Expression expression) { + ExpressionNode couscousExpression = readExpressionWithoutBoxing(expression); + if (couscousExpression.getType().equals(IntegerValue.REF) && !targetType.equals(IntegerValue.REF)) { + return StaticMethodCallNode.boxInt(couscousExpression); + } else { + return couscousExpression; + } + } + + private static ExpressionNode readExpressionWithoutBoxing(Expression expression) { switch (expression.getNodeType()) { case ASTNode.BOOLEAN_LITERAL: return readBooleanLiteral((BooleanLiteral)expression); @@ -236,13 +249,15 @@ public class JavaReader { } private static ExpressionNode readFieldAccess(FieldAccess expression) { - return FieldAccessNode.fieldAccess(readExpression(expression.getExpression()), expression.getName().getIdentifier(), typeOf(expression)); + return FieldAccessNode.fieldAccess(readExpressionWithoutBoxing(expression.getExpression()), expression.getName().getIdentifier(), typeOf(expression)); } private static ExpressionNode readMethodInvocation(MethodInvocation expression) { String methodName = expression.getName().getIdentifier(); @SuppressWarnings("unchecked") - List<ExpressionNode> arguments = readArguments(expression.arguments()); + List<ExpressionNode> arguments = readArguments( + expression.resolveMethodBinding(), + expression.arguments()); final TypeName type = typeOf(expression); IMethodBinding methodBinding = expression.resolveMethodBinding(); @@ -256,7 +271,7 @@ public class JavaReader { } else { ExpressionNode receiver = expression.getExpression() == null ? ThisReferenceNode.thisReference(receiverType) - : readExpression(expression.getExpression()); + : readExpressionWithoutBoxing(expression.getExpression()); return MethodCallNode.methodCall( receiver, methodName, @@ -270,18 +285,22 @@ public class JavaReader { List<Expression> arguments = expression.arguments(); return ConstructorCallNode.constructorCall( typeOf(expression), - readArguments(arguments)); + readArguments(expression.resolveConstructorBinding(), arguments)); } - private static List<ExpressionNode> readArguments(List<Expression> javaArguments) { - return eagerMap(javaArguments, JavaReader::readExpression); + private static List<ExpressionNode> readArguments(IMethodBinding method, List<Expression> javaArguments) { + return IntStream.range(0, javaArguments.size()) + .mapToObj(index -> readExpression( + typeOf(method.getParameterTypes()[index]), + javaArguments.get(index))) + .collect(Collectors.toList()); } private static ExpressionNode readInfixExpression(InfixExpression expression) { - final ExpressionNode left = readExpression(expression.getLeftOperand()); - final ExpressionNode right = readExpression(expression.getRightOperand()); - - if (left.getType().equals(IntegerValue.REF)) { + if (typeOf(expression.getLeftOperand()).equals(IntegerValue.REF)) { + ExpressionNode left = readExpression(IntegerValue.REF, expression.getLeftOperand()); + ExpressionNode right = readExpression(IntegerValue.REF, expression.getRightOperand()); + if (expression.getOperator() == Operator.NOT_EQUALS) { return MethodCallNode.not(methodCall(left, "equals", asList(right), BooleanValue.REF)); } else { @@ -293,6 +312,8 @@ public class JavaReader { operator.returnValue); } } else { + ExpressionNode left = readExpression(ObjectValues.OBJECT, expression.getLeftOperand()); + ExpressionNode right = readExpression(ObjectValues.OBJECT, expression.getRightOperand()); if (expression.getOperator() == Operator.EQUALS) { return StaticMethodCallNode.same(left, right); } else if (expression.getOperator() == Operator.NOT_EQUALS) { @@ -344,11 +365,18 @@ public class JavaReader { } private static ExpressionNode readConditionalExpression(ConditionalExpression expression) { - return TernaryConditionalNode.ternaryConditional(readExpression(expression.getExpression()), readExpression(expression.getThenExpression()), readExpression(expression.getElseExpression())); + TypeName type = typeOf(expression); + return TernaryConditionalNode.ternaryConditional( + readExpression(BooleanValue.REF, expression.getExpression()), + readExpression(type, expression.getThenExpression()), + readExpression(type, expression.getElseExpression())); } private static ExpressionNode readAssignment(Assignment expression) { - return AssignmentNode.assign((AssignableExpressionNode)readExpression(expression.getLeftHandSide()), readExpression(expression.getRightHandSide())); + ExpressionNode left = readExpressionWithoutBoxing(expression.getLeftHandSide()); + return AssignmentNode.assign( + (AssignableExpressionNode)left, + readExpression(left.getType(), expression.getRightHandSide())); } private static String generateClassName(CompilationUnit ast) { diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java index 30645d6..873805e 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpeterValue.java @@ -1,12 +1,12 @@ package org.zwobble.couscous.interpreter.values; -import org.zwobble.couscous.values.ObjectValue; +import org.zwobble.couscous.values.ObjectValues; import static java.util.Arrays.asList; public class InternalCouscousInterpeterValue { public static final ConcreteType TYPE = ConcreteType.classBuilder("_couscous") - .staticMethod("same", asList(ObjectValue.REF, ObjectValue.REF), + .staticMethod("same", asList(ObjectValues.OBJECT, ObjectValues.OBJECT), (environment, arguments) -> new BooleanInterpreterValue(arguments.get(0) == arguments.get(1))) diff --git a/src/main/java/org/zwobble/couscous/values/ObjectValue.java b/src/main/java/org/zwobble/couscous/values/ObjectValue.java deleted file mode 100644 index ea59ae0..0000000 --- a/src/main/java/org/zwobble/couscous/values/ObjectValue.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.zwobble.couscous.values; - -import org.zwobble.couscous.ast.TypeName; - -public class ObjectValue { - public static final TypeName REF = TypeName.of("java.lang.Object"); -} diff --git a/src/main/java/org/zwobble/couscous/values/ObjectValues.java b/src/main/java/org/zwobble/couscous/values/ObjectValues.java new file mode 100644 index 0000000..ee02a11 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/values/ObjectValues.java @@ -0,0 +1,8 @@ +package org.zwobble.couscous.values; + +import org.zwobble.couscous.ast.TypeName; + +public class ObjectValues { + public static final TypeName OBJECT = TypeName.of("java.lang.Object"); + public static final TypeName BOXED_INT = TypeName.of("java.lang.Integer"); +} |
