diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-01-04 23:28:22 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-01-04 23:28:22 +0000 |
| commit | 75b69c7f4e7ed84f82c549e36a3928a48720cc26 (patch) | |
| tree | d400967b67b7e6ec7c922a586ae14c6cda35f6ed /src/main/java/org/zwobble/couscous/ast | |
| parent | bb0b36b86f841ec6340fe6e727ed2ea9db1c2d64 (diff) | |
Move type coercion decisions into the backends
Diffstat (limited to 'src/main/java/org/zwobble/couscous/ast')
9 files changed, 117 insertions, 29 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java index 0f1ab4f..c483bcd 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java @@ -56,6 +56,11 @@ public interface ExpressionNode extends Node { public T visit(FieldAccessNode fieldAccess) { return visitor.visit(fieldAccess); } + + @Override + public T visit(TypeCoercionNode typeCoercion) { + return visitor.visit(typeCoercion); + } }); } diff --git a/src/main/java/org/zwobble/couscous/ast/Node.java b/src/main/java/org/zwobble/couscous/ast/Node.java index 7c4d347..c9eed67 100644 --- a/src/main/java/org/zwobble/couscous/ast/Node.java +++ b/src/main/java/org/zwobble/couscous/ast/Node.java @@ -61,6 +61,12 @@ public interface Node { } @Override + public Void visit(TypeCoercionNode typeCoercion) { + visitor.visit(typeCoercion); + return null; + } + + @Override public Void visit(ReturnNode returnNode) { visitor.visit(returnNode); return null; diff --git a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java index ccb9854..7c3b90b 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -10,6 +10,7 @@ import org.zwobble.couscous.values.InternalCouscousValue; import org.zwobble.couscous.values.ObjectValues; import static java.util.Arrays.asList; +import static org.zwobble.couscous.ast.TypeCoercionNode.typeCoercion; import static org.zwobble.couscous.util.ExtraLists.eagerMap; public class StaticMethodCallNode implements ExpressionNode { @@ -18,35 +19,19 @@ public class StaticMethodCallNode implements ExpressionNode { } public static ExpressionNode boxInt(ExpressionNode value) { - return staticMethodCall( - InternalCouscousValue.REF, - "boxInt", - asList(value), - ObjectValues.BOXED_INT); + return typeCoercion(value, ObjectValues.BOXED_INT); } public static ExpressionNode unboxInt(ExpressionNode value) { - return staticMethodCall( - InternalCouscousValue.REF, - "unboxInt", - asList(value), - IntegerValue.REF); + return typeCoercion(value, IntegerValue.REF); } public static ExpressionNode boxBoolean(ExpressionNode value) { - return staticMethodCall( - InternalCouscousValue.REF, - "boxBoolean", - asList(value), - ObjectValues.BOXED_BOOLEAN); + return typeCoercion(value, ObjectValues.BOXED_BOOLEAN); } public static ExpressionNode unboxBoolean(ExpressionNode value) { - return staticMethodCall( - InternalCouscousValue.REF, - "unboxBoolean", - asList(value), - BooleanValue.REF); + return typeCoercion(value, BooleanValue.REF); } public static StaticMethodCallNode staticMethodCall( diff --git a/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java b/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java new file mode 100644 index 0000000..2c7b68e --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java @@ -0,0 +1,87 @@ +package org.zwobble.couscous.ast; + +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import org.zwobble.couscous.values.BooleanValue; +import org.zwobble.couscous.values.IntegerValue; + +import java.util.function.Function; + +public class TypeCoercionNode implements ExpressionNode { + public static TypeCoercionNode typeCoercion(ExpressionNode expression, TypeName type) { + return new TypeCoercionNode(expression, type); + } + + private final ExpressionNode expression; + private final TypeName type; + + private TypeCoercionNode(ExpressionNode expression, TypeName type) { + this.expression = expression; + this.type = type; + } + + public ExpressionNode getExpression() { + return expression; + } + + @Override + public TypeName getType() { + return type; + } + + public boolean isIntegerBox() { + return expression.getType().equals(IntegerValue.REF) && + !type.equals(IntegerValue.REF); + } + + public boolean isIntegerUnbox() { + return !expression.getType().equals(IntegerValue.REF) && + type.equals(IntegerValue.REF); + } + + public boolean isBooleanBox() { + return expression.getType().equals(BooleanValue.REF) && + !type.equals(BooleanValue.REF); + } + + public boolean isBooleanUnbox() { + return !expression.getType().equals(BooleanValue.REF) && + type.equals(BooleanValue.REF); + } + + @Override + public <T> T accept(ExpressionNodeMapper<T> visitor) { + return visitor.visit(this); + } + + @Override + public ExpressionNode replaceExpressions(Function<ExpressionNode, ExpressionNode> replace) { + return new TypeCoercionNode(replace.apply(expression), type); + } + + @Override + public String toString() { + return "TypeCoercionNode(" + + "expression=" + expression + + ", type=" + type + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TypeCoercionNode that = (TypeCoercionNode) o; + + if (!expression.equals(that.expression)) return false; + return type.equals(that.type); + + } + + @Override + public int hashCode() { + int result = expression.hashCode(); + result = 31 * result + type.hashCode(); + return result; + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java index 47ba9b6..8b65f35 100644 --- a/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java +++ b/src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java @@ -80,6 +80,11 @@ public class NodeStructure { } @Override + public Stream<? extends Node> visit(TypeCoercionNode typeCoercion) { + return Stream.of(typeCoercion.getExpression()); + } + + @Override public Stream<Node> visit(ReturnNode returnNode) { return Stream.of(returnNode.getValue()); } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java index c1c3e88..87b8598 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java @@ -1,14 +1,6 @@ package org.zwobble.couscous.ast.visitors; -import org.zwobble.couscous.ast.AssignmentNode; -import org.zwobble.couscous.ast.ConstructorCallNode; -import org.zwobble.couscous.ast.FieldAccessNode; -import org.zwobble.couscous.ast.LiteralNode; -import org.zwobble.couscous.ast.MethodCallNode; -import org.zwobble.couscous.ast.StaticMethodCallNode; -import org.zwobble.couscous.ast.TernaryConditionalNode; -import org.zwobble.couscous.ast.ThisReferenceNode; -import org.zwobble.couscous.ast.VariableReferenceNode; +import org.zwobble.couscous.ast.*; public interface ExpressionNodeMapper<T> { T visit(LiteralNode literal); @@ -20,4 +12,5 @@ public interface ExpressionNodeMapper<T> { T visit(StaticMethodCallNode staticMethodCall); T visit(ConstructorCallNode call); T visit(FieldAccessNode fieldAccess); + T visit(TypeCoercionNode typeCoercion); } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java index d38d7fa..4267c75 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java @@ -12,6 +12,7 @@ public interface NodeMapper<T> { T visit(StaticMethodCallNode staticMethodCall); T visit(ConstructorCallNode call); T visit(FieldAccessNode fieldAccess); + T visit(TypeCoercionNode typeCoercion); T visit(ReturnNode returnNode); T visit(ExpressionStatementNode expressionStatement); diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java index e4203e0..09cfcd3 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java @@ -55,6 +55,11 @@ public class NodeMapperWithDefault<T> implements NodeMapper<T> { } @Override + public T visit(TypeCoercionNode typeCoercion) { + return defaultValue; + } + + @Override public T visit(ReturnNode returnNode) { return defaultValue; } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java index 75e6da5..9f6be92 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java @@ -12,6 +12,7 @@ public interface NodeVisitor { void visit(StaticMethodCallNode staticMethodCall); void visit(ConstructorCallNode call); void visit(FieldAccessNode fieldAccess); + void visit(TypeCoercionNode typeCoercion); void visit(ReturnNode returnNode); void visit(ExpressionStatementNode expressionStatement); |
