aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/ast
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-01-04 23:28:22 +0000
committerMichael Williamson <mike@zwobble.org>2016-01-04 23:28:22 +0000
commit75b69c7f4e7ed84f82c549e36a3928a48720cc26 (patch)
treed400967b67b7e6ec7c922a586ae14c6cda35f6ed /src/main/java/org/zwobble/couscous/ast
parentbb0b36b86f841ec6340fe6e727ed2ea9db1c2d64 (diff)
Move type coercion decisions into the backends
Diffstat (limited to 'src/main/java/org/zwobble/couscous/ast')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/ExpressionNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/Node.java6
-rw-r--r--src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java25
-rw-r--r--src/main/java/org/zwobble/couscous/ast/TypeCoercionNode.java87
-rw-r--r--src/main/java/org/zwobble/couscous/ast/structure/NodeStructure.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java11
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeMapper.java1
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeMapperWithDefault.java5
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java1
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);