diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-05 22:26:29 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-05 22:26:29 +0100 |
| commit | 166a205aeb4c595b40b8ffe4c7d745b13031e3b3 (patch) | |
| tree | aa493482f4ca312c1f23913ebc2f57b71d8aa590 /src/main/java/org/zwobble/couscous/ast | |
| parent | 44e4b877baea47c0465e1029bdbedc848381999f (diff) | |
Add support for static method calls to Python backend
Diffstat (limited to 'src/main/java/org/zwobble/couscous/ast')
19 files changed, 301 insertions, 28 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java index 8989ef3..349b492 100644 --- a/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java +++ b/src/main/java/org/zwobble/couscous/ast/AssignmentNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.TypeReference; import static org.zwobble.couscous.ast.VariableReferenceNode.reference; @@ -17,7 +17,7 @@ public class AssignmentNode implements ExpressionNode { ExpressionNode value; @Override - public <T> T accept(ExpressionNodeVisitor<T> visitor) { + public <T> T accept(ExpressionNodeMapper<T> visitor) { return visitor.visit(this); } diff --git a/src/main/java/org/zwobble/couscous/ast/ClassNode.java b/src/main/java/org/zwobble/couscous/ast/ClassNode.java index 3d785d2..77480b5 100644 --- a/src/main/java/org/zwobble/couscous/ast/ClassNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ClassNode.java @@ -2,13 +2,15 @@ package org.zwobble.couscous.ast; import java.util.List; +import org.zwobble.couscous.ast.visitors.NodeVisitor; + import com.google.common.collect.ImmutableList; import lombok.Singular; import lombok.Value; @Value -public class ClassNode { +public class ClassNode implements Node { public static ClassNode.Builder builder(String name) { return new Builder(name); } @@ -40,4 +42,9 @@ public class ClassNode { // TODO Stronger notion of class names? Should look up the terminology return name.substring(name.lastIndexOf(".") + 1); } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java index bc27a99..297133d 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionNode.java @@ -1,9 +1,51 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import org.zwobble.couscous.ast.visitors.NodeVisitor; import org.zwobble.couscous.values.TypeReference; -public interface ExpressionNode { +public interface ExpressionNode extends Node { TypeReference getType(); - <T> T accept(ExpressionNodeVisitor<T> visitor); + <T> T accept(ExpressionNodeMapper<T> visitor); + + @Override + default void accept(NodeVisitor visitor) { + accept(new ExpressionNodeMapper<Void>() { + @Override + public Void visit(LiteralNode literal) { + visitor.visit(literal); + return null; + } + + @Override + public Void visit(VariableReferenceNode variableReference) { + visitor.visit(variableReference); + return null; + } + + @Override + public Void visit(AssignmentNode assignment) { + visitor.visit(assignment); + return null; + } + + @Override + public Void visit(TernaryConditionalNode ternaryConditional) { + visitor.visit(ternaryConditional); + return null; + } + + @Override + public Void visit(MethodCallNode methodCall) { + visitor.visit(methodCall); + return null; + } + + @Override + public Void visit(StaticMethodCallNode staticMethodCall) { + visitor.visit(staticMethodCall); + return null; + } + }); + } } diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java index ec04663..5bbe2b5 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; +import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import lombok.Value; @@ -9,7 +9,7 @@ public class ExpressionStatementNode implements StatementNode { ExpressionNode expression; @Override - public <T> T accept(StatementNodeVisitor<T> visitor) { + public <T> T accept(StatementNodeMapper<T> visitor) { return visitor.visit(this); } } diff --git a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java index 2d77cd4..a608104 100644 --- a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.PrimitiveValue; @@ -33,7 +33,7 @@ public class LiteralNode implements ExpressionNode { TypeReference type; @Override - public <T> T accept(ExpressionNodeVisitor<T> visitor) { + public <T> T accept(ExpressionNodeMapper<T> visitor) { return visitor.visit(this); } } diff --git a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java index cf6c5f0..2b5c63a 100644 --- a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; +import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.values.TypeReference; import static org.zwobble.couscous.ast.VariableDeclaration.var; @@ -21,7 +21,7 @@ public class LocalVariableDeclarationNode implements VariableNode, StatementNode ExpressionNode initialValue; @Override - public <T> T accept(StatementNodeVisitor<T> visitor) { + public <T> T accept(StatementNodeMapper<T> visitor) { return visitor.visit(this); } } diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java index f240971..e1358c2 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java @@ -2,7 +2,7 @@ package org.zwobble.couscous.ast; import java.util.List; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.TypeReference; import lombok.Value; @@ -23,7 +23,7 @@ public class MethodCallNode implements ExpressionNode { } @Override - public <T> T accept(ExpressionNodeVisitor<T> visitor) { + public <T> T accept(ExpressionNodeMapper<T> visitor) { return visitor.visit(this); } } diff --git a/src/main/java/org/zwobble/couscous/ast/MethodNode.java b/src/main/java/org/zwobble/couscous/ast/MethodNode.java index 91acbd5..e924299 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodNode.java @@ -2,13 +2,15 @@ package org.zwobble.couscous.ast; import java.util.List; +import org.zwobble.couscous.ast.visitors.NodeVisitor; + import lombok.Builder; import lombok.Singular; import lombok.Value; @Builder @Value -public class MethodNode { +public class MethodNode implements Node { public static MethodNodeBuilder staticMethod(String name) { return builder().isStatic(true).name(name); } @@ -19,4 +21,9 @@ public class MethodNode { List<FormalArgumentNode> arguments; @Singular("statement") List<StatementNode> body; + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/src/main/java/org/zwobble/couscous/ast/Node.java b/src/main/java/org/zwobble/couscous/ast/Node.java new file mode 100644 index 0000000..acde931 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/Node.java @@ -0,0 +1,7 @@ +package org.zwobble.couscous.ast; + +import org.zwobble.couscous.ast.visitors.NodeVisitor; + +public interface Node { + void accept(NodeVisitor visitor); +} diff --git a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java index 529dbb5..7f4a57e 100644 --- a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; +import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import lombok.Value; @@ -9,7 +9,7 @@ public class ReturnNode implements StatementNode { ExpressionNode value; @Override - public <T> T accept(StatementNodeVisitor<T> visitor) { + public <T> T accept(StatementNodeMapper<T> visitor) { return visitor.visit(this); } } diff --git a/src/main/java/org/zwobble/couscous/ast/StatementNode.java b/src/main/java/org/zwobble/couscous/ast/StatementNode.java index 773420e..7a1b25b 100644 --- a/src/main/java/org/zwobble/couscous/ast/StatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StatementNode.java @@ -1,7 +1,32 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; +import org.zwobble.couscous.ast.visitors.NodeVisitor; +import org.zwobble.couscous.ast.visitors.StatementNodeMapper; -public interface StatementNode { - <T> T accept(StatementNodeVisitor<T> visitor); +public interface StatementNode extends Node { + <T> T accept(StatementNodeMapper<T> visitor); + + @Override + default void accept(NodeVisitor visitor) { + accept(new StatementNodeMapper<Void>() { + @Override + public Void visit(ReturnNode returnNode) { + visitor.visit(returnNode); + return null; + } + + @Override + public Void visit(ExpressionStatementNode expressionStatement) { + visitor.visit(expressionStatement); + return null; + } + + @Override + public Void visit( + LocalVariableDeclarationNode localVariableDeclaration) { + visitor.visit(localVariableDeclaration); + 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 0228514..96e2e4c 100644 --- a/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StaticMethodCallNode.java @@ -2,7 +2,7 @@ package org.zwobble.couscous.ast; import java.util.List; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.TypeReference; import static java.util.Arrays.asList; @@ -24,7 +24,7 @@ public class StaticMethodCallNode implements ExpressionNode { List<ExpressionNode> arguments; @Override - public <T> T accept(ExpressionNodeVisitor<T> visitor) { + public <T> T accept(ExpressionNodeMapper<T> visitor) { return visitor.visit(this); } diff --git a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java index 8b30024..99b5f60 100644 --- a/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java +++ b/src/main/java/org/zwobble/couscous/ast/TernaryConditionalNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.TypeReference; import lombok.Value; @@ -12,7 +12,7 @@ public class TernaryConditionalNode implements ExpressionNode { ExpressionNode ifFalse; @Override - public <T> T accept(ExpressionNodeVisitor<T> visitor) { + public <T> T accept(ExpressionNodeMapper<T> visitor) { return visitor.visit(this); } diff --git a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java index 5499d50..fe47a84 100644 --- a/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java +++ b/src/main/java/org/zwobble/couscous/ast/VariableReferenceNode.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.ast; -import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; +import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; import org.zwobble.couscous.values.TypeReference; import lombok.Value; @@ -14,7 +14,7 @@ public class VariableReferenceNode implements ExpressionNode { VariableDeclaration referent; @Override - public <T> T accept(ExpressionNodeVisitor<T> visitor) { + public <T> T accept(ExpressionNodeMapper<T> visitor) { return visitor.visit(this); } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java index c47b942..2be2894 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/ExpressionNodeMapper.java @@ -7,7 +7,7 @@ import org.zwobble.couscous.ast.StaticMethodCallNode; import org.zwobble.couscous.ast.TernaryConditionalNode; import org.zwobble.couscous.ast.VariableReferenceNode; -public interface ExpressionNodeVisitor<T> { +public interface ExpressionNodeMapper<T> { T visit(LiteralNode literal); T visit(VariableReferenceNode variableReference); T visit(AssignmentNode assignment); diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java new file mode 100644 index 0000000..014b48e --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java @@ -0,0 +1,29 @@ +package org.zwobble.couscous.ast.visitors; + +import org.zwobble.couscous.ast.AssignmentNode; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.LiteralNode; +import org.zwobble.couscous.ast.LocalVariableDeclarationNode; +import org.zwobble.couscous.ast.MethodCallNode; +import org.zwobble.couscous.ast.MethodNode; +import org.zwobble.couscous.ast.ReturnNode; +import org.zwobble.couscous.ast.StaticMethodCallNode; +import org.zwobble.couscous.ast.TernaryConditionalNode; +import org.zwobble.couscous.ast.VariableReferenceNode; + +public interface NodeVisitor { + void visit(LiteralNode literal); + void visit(VariableReferenceNode variableReference); + void visit(AssignmentNode assignment); + void visit(TernaryConditionalNode ternaryConditional); + void visit(MethodCallNode methodCall); + void visit(StaticMethodCallNode staticMethodCall); + + void visit(ReturnNode returnNode); + void visit(ExpressionStatementNode expressionStatement); + void visit(LocalVariableDeclarationNode localVariableDeclaration); + + void visit(ClassNode classNode); + void visit(MethodNode methodNode); +} diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitorWithEmptyDefaults.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitorWithEmptyDefaults.java new file mode 100644 index 0000000..3a58614 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitorWithEmptyDefaults.java @@ -0,0 +1,59 @@ +package org.zwobble.couscous.ast.visitors; + +import org.zwobble.couscous.ast.AssignmentNode; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.LiteralNode; +import org.zwobble.couscous.ast.LocalVariableDeclarationNode; +import org.zwobble.couscous.ast.MethodCallNode; +import org.zwobble.couscous.ast.MethodNode; +import org.zwobble.couscous.ast.ReturnNode; +import org.zwobble.couscous.ast.StaticMethodCallNode; +import org.zwobble.couscous.ast.TernaryConditionalNode; +import org.zwobble.couscous.ast.VariableReferenceNode; + +public interface NodeVisitorWithEmptyDefaults extends NodeVisitor { + @Override + default void visit(LiteralNode literal) { + } + + @Override + default void visit(VariableReferenceNode variableReference) { + } + + @Override + default void visit(AssignmentNode assignment) { + } + + @Override + default void visit(TernaryConditionalNode ternaryConditional) { + } + + @Override + default void visit(MethodCallNode methodCall) { + } + + @Override + default void visit(StaticMethodCallNode staticMethodCall) { + } + + @Override + default void visit(ReturnNode returnNode) { + } + + @Override + default void visit(ExpressionStatementNode expressionStatement) { + } + + @Override + default void visit(LocalVariableDeclarationNode localVariableDeclaration) { + } + + @Override + default void visit(ClassNode classNode) { + } + + @Override + default void visit(MethodNode methodNode) { + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java new file mode 100644 index 0000000..88c6e10 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java @@ -0,0 +1,97 @@ +package org.zwobble.couscous.ast.visitors; + +import org.zwobble.couscous.ast.AssignmentNode; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.LiteralNode; +import org.zwobble.couscous.ast.LocalVariableDeclarationNode; +import org.zwobble.couscous.ast.MethodCallNode; +import org.zwobble.couscous.ast.MethodNode; +import org.zwobble.couscous.ast.Node; +import org.zwobble.couscous.ast.ReturnNode; +import org.zwobble.couscous.ast.StaticMethodCallNode; +import org.zwobble.couscous.ast.TernaryConditionalNode; +import org.zwobble.couscous.ast.VariableReferenceNode; + +import lombok.val; + +public class NodeVisitors { + public static void visitAll(Node node, NodeVisitor visitor) { + node.accept(new NodeVisitor() { + @Override + public void visit(LiteralNode literal) { + visitor.visit(literal); + } + + @Override + public void visit(VariableReferenceNode variableReference) { + visitor.visit(variableReference); + } + + @Override + public void visit(AssignmentNode assignment) { + visitor.visit(assignment); + assignment.getValue().accept(this); + visit(assignment.getTarget()); + } + + @Override + public void visit(TernaryConditionalNode ternaryConditional) { + visitor.visit(ternaryConditional); + ternaryConditional.getCondition().accept(this); + ternaryConditional.getIfTrue().accept(this); + ternaryConditional.getIfFalse().accept(this); + } + + @Override + public void visit(MethodCallNode methodCall) { + visitor.visit(methodCall); + methodCall.getReceiver().accept(this); + for (val argument : methodCall.getArguments()) { + argument.accept(this); + } + } + + @Override + public void visit(StaticMethodCallNode staticMethodCall) { + visitor.visit(staticMethodCall); + for (val argument : staticMethodCall.getArguments()) { + argument.accept(this); + } + } + + @Override + public void visit(ReturnNode returnNode) { + visitor.visit(returnNode); + returnNode.getValue().accept(this); + } + + @Override + public void visit(ExpressionStatementNode expressionStatement) { + visitor.visit(expressionStatement); + expressionStatement.getExpression().accept(this); + } + + @Override + public void visit(LocalVariableDeclarationNode localVariableDeclaration) { + visitor.visit(localVariableDeclaration); + localVariableDeclaration.getInitialValue().accept(this); + } + + @Override + public void visit(ClassNode classNode) { + visitor.visit(classNode); + for (val method : classNode.getMethods()) { + method.accept(this); + } + } + + @Override + public void visit(MethodNode methodNode) { + for (val statement : methodNode.getBody()) { + statement.accept(this); + } + } + }); + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java index 620f6f8..4bae481 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java @@ -4,7 +4,7 @@ import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.ReturnNode; -public interface StatementNodeVisitor<T> { +public interface StatementNodeMapper<T> { T visit(ReturnNode returnNode); T visit(ExpressionStatementNode expressionStatement); T visit(LocalVariableDeclarationNode localVariableDeclaration); |
