diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-07-15 11:57:28 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-07-15 11:57:28 +0100 |
| commit | 15c67a851605262ef165279d99964ce8a53a45f5 (patch) | |
| tree | 80927551aede98f3bdbfc3acc40660916f90ffe0 | |
| parent | 0970f5a5074da34fffaea70f3b42d012edb501c5 (diff) | |
Remove StatementNodeMapper
12 files changed, 26 insertions, 97 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java index c32efbc..462d2aa 100644 --- a/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ExpressionStatementNode.java @@ -1,7 +1,6 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.util.ExtraIterables; public class ExpressionStatementNode implements StatementNode { @@ -20,11 +19,6 @@ public class ExpressionStatementNode implements StatementNode { } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.EXPRESSION_STATEMENT; } diff --git a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java index 4a58251..66a2b60 100644 --- a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java @@ -2,7 +2,6 @@ package org.zwobble.couscous.ast; import com.google.common.collect.Iterables; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.util.ExtraIterables; import java.util.List; @@ -41,11 +40,6 @@ public class IfStatementNode implements StatementNode { } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.IF_STATEMENT; } diff --git a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java index 595adb1..172fe5e 100644 --- a/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LocalVariableDeclarationNode.java @@ -1,9 +1,8 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.identifiers.Identifier; -import org.zwobble.couscous.types.Type; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import org.zwobble.couscous.types.Type; import org.zwobble.couscous.util.ExtraIterables; import static org.zwobble.couscous.ast.TypeCoercionNode.coerce; @@ -51,11 +50,6 @@ public class LocalVariableDeclarationNode implements VariableNode, StatementNode } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.LOCAL_VARIABLE_DECLARATION; } diff --git a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java index 2c6d665..28a16f8 100644 --- a/src/main/java/org/zwobble/couscous/ast/ReturnNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ReturnNode.java @@ -1,7 +1,6 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.util.ExtraIterables; public class ReturnNode implements StatementNode { @@ -20,11 +19,6 @@ public class ReturnNode implements StatementNode { } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.RETURN; } diff --git a/src/main/java/org/zwobble/couscous/ast/StatementNode.java b/src/main/java/org/zwobble/couscous/ast/StatementNode.java index cdcd636..c18fe5d 100644 --- a/src/main/java/org/zwobble/couscous/ast/StatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StatementNode.java @@ -1,9 +1,7 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; public interface StatementNode extends Node { - <T> T accept(StatementNodeMapper<T> visitor); StatementNode transform(NodeTransformer transformer); } diff --git a/src/main/java/org/zwobble/couscous/ast/ThrowNode.java b/src/main/java/org/zwobble/couscous/ast/ThrowNode.java index 0b273c9..23e42c7 100644 --- a/src/main/java/org/zwobble/couscous/ast/ThrowNode.java +++ b/src/main/java/org/zwobble/couscous/ast/ThrowNode.java @@ -1,7 +1,6 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.util.ExtraIterables; public class ThrowNode implements StatementNode { @@ -20,11 +19,6 @@ public class ThrowNode implements StatementNode { } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.THROW; } diff --git a/src/main/java/org/zwobble/couscous/ast/TryNode.java b/src/main/java/org/zwobble/couscous/ast/TryNode.java index 9a61ecc..ae1890b 100644 --- a/src/main/java/org/zwobble/couscous/ast/TryNode.java +++ b/src/main/java/org/zwobble/couscous/ast/TryNode.java @@ -2,7 +2,6 @@ package org.zwobble.couscous.ast; import com.google.common.collect.Iterables; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import java.util.List; @@ -45,11 +44,6 @@ public class TryNode implements StatementNode { } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.TRY; } diff --git a/src/main/java/org/zwobble/couscous/ast/WhileNode.java b/src/main/java/org/zwobble/couscous/ast/WhileNode.java index 6cd5c51..63db222 100644 --- a/src/main/java/org/zwobble/couscous/ast/WhileNode.java +++ b/src/main/java/org/zwobble/couscous/ast/WhileNode.java @@ -2,7 +2,6 @@ package org.zwobble.couscous.ast; import com.google.common.base.Objects; import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.util.ExtraIterables; import java.util.List; @@ -29,11 +28,6 @@ public class WhileNode implements StatementNode { } @Override - public <T> T accept(StatementNodeMapper<T> visitor) { - return visitor.visit(this); - } - - @Override public int type() { return NodeTypes.WHILE; } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeMapper.java index 0637c44..fedbd47 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeMapper.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeMapper.java @@ -5,6 +5,7 @@ import org.zwobble.couscous.ast.Node; import java.util.HashMap; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; import static org.zwobble.couscous.util.ExtraMaps.entry; @@ -15,12 +16,22 @@ public class DynamicNodeMapper { // TODO: check return type -- at the very least, check the methods are consistent. public static <T, R> Function<Node, R> instantiate(T visitor, String methodName) { - Map.Entry<Class<?>, String> key = entry(visitor.getClass(), methodName); + Function<T, Function<Node, R>> builder = buildClassSupplier(visitor.getClass(), methodName); + return builder.apply(visitor); + } + + public static <T, R> BiFunction<Node, T, R> visitor(Class<T> clazz, String methodName) { + Function<T, Function<Node, R>> classSupplier = buildClassSupplier(clazz, methodName); + return (node, visitor) -> classSupplier.apply(visitor).apply(node); + } + + private static <T> Function buildClassSupplier(Class<?> visitorClass, String methodName) { + Map.Entry<Class<?>, String> key = entry(visitorClass, methodName); Function builder = VISITOR_BUILDERS.get(key); if (builder == null) { - builder = DynamicNodeVisitor.buildClassSupplier(visitor.getClass(), Function.class, methodName, MethodReturn.REFERENCE); + builder = DynamicNodeVisitor.buildClassSupplier(visitorClass, Function.class, methodName, MethodReturn.REFERENCE); VISITOR_BUILDERS.put(key, builder); } - return (Function<Node, R>) builder.apply(visitor); + return builder; } } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java deleted file mode 100644 index 5d88a60..0000000 --- a/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.zwobble.couscous.ast.visitors; - -import org.zwobble.couscous.ast.*; - -public interface StatementNodeMapper<T> { - T visit(ReturnNode returnNode); - T visit(ThrowNode throwNode); - T visit(ExpressionStatementNode expressionStatement); - T visit(LocalVariableDeclarationNode localVariableDeclaration); - T visit(IfStatementNode ifStatement); - T visit(WhileNode whileLoop); - T visit(TryNode tryStatement); -} diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java index 993b6aa..c520e2a 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -8,7 +8,6 @@ import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.structure.NodeStructure; import org.zwobble.couscous.ast.visitors.DynamicNodeMapper; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.backends.naming.Names; import org.zwobble.couscous.backends.python.ast.*; import org.zwobble.couscous.types.ScalarType; @@ -240,21 +239,16 @@ public class PythonCodeGenerator { } private static PythonStatementNode generateStatement(StatementNode statement) { - return statement.accept(new StatementGenerator()); + return StatementGenerator.VISITOR.apply(statement); } - private static class StatementGenerator implements StatementNodeMapper<PythonStatementNode> { - @Override + public static class StatementGenerator { + private static final Function<Node, PythonStatementNode> VISITOR = DynamicNodeMapper.instantiate(new StatementGenerator(), "visit"); + public PythonStatementNode visit(ReturnNode returnNode) { return pythonReturn(generateExpression(returnNode.getValue())); } - @Override - public PythonStatementNode visit(ThrowNode throwNode) { - throw new UnsupportedOperationException(); - } - - @Override public PythonStatementNode visit(ExpressionStatementNode expressionStatement) { if (expressionStatement.getExpression() instanceof AssignmentNode) { AssignmentNode assignment = (AssignmentNode)expressionStatement.getExpression(); @@ -264,12 +258,10 @@ public class PythonCodeGenerator { } } - @Override public PythonStatementNode visit(LocalVariableDeclarationNode declaration) { return pythonAssignment(pythonVariableReference(declaration.getDeclaration().getName()), generateExpression(declaration.getInitialValue())); } - @Override public PythonStatementNode visit(IfStatementNode ifStatement) { return pythonIfStatement( generateExpression(ifStatement.getCondition()), @@ -277,17 +269,11 @@ public class PythonCodeGenerator { generateStatements(ifStatement.getFalseBranch())); } - @Override public PythonStatementNode visit(WhileNode whileLoop) { return pythonWhile( generateExpression(whileLoop.getCondition()), generateStatements(whileLoop.getBody())); } - - @Override - public PythonStatementNode visit(TryNode tryStatement) { - throw new UnsupportedOperationException(); - } } public static PythonExpressionNode generateExpression(ExpressionNode expression) { diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index eba214b..0acb253 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -2,12 +2,12 @@ package org.zwobble.couscous.interpreter; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.visitors.DynamicNodeMapper; -import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.interpreter.values.InterpreterValue; import org.zwobble.couscous.interpreter.values.UnitInterpreterValue; import java.util.List; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Stream; @@ -16,7 +16,7 @@ import static org.zwobble.couscous.interpreter.Evaluator.eval; import static org.zwobble.couscous.interpreter.Evaluator.evalCondition; import static org.zwobble.couscous.util.ExtraIterables.forEach; -public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> { +public class Executor { public static InterpreterValue callMethod( Environment environment, MethodNode method, @@ -90,39 +90,34 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> return Optional.empty(); } + public static Optional<InterpreterValue> exec(Environment environment, StatementNode statement) { - return statement.accept(new Executor(environment)); + return EXEC.apply(statement, new Executor(environment)); } + + private static final BiFunction<Node, Executor, Optional<InterpreterValue>> EXEC = DynamicNodeMapper.visitor(Executor.class, "visit"); + private final Environment environment; private Executor(Environment environment) { this.environment = environment; } - @Override public Optional<InterpreterValue> visit(ReturnNode returnNode) { return Optional.of(eval(environment, returnNode.getValue())); } - @Override - public Optional<InterpreterValue> visit(ThrowNode throwNode) { - throw new UnsupportedOperationException(); - } - - @Override public Optional<InterpreterValue> visit(ExpressionStatementNode expressionStatement) { eval(environment, expressionStatement.getExpression()); return Optional.empty(); } - @Override public Optional<InterpreterValue> visit(LocalVariableDeclarationNode localVariableDeclaration) { final org.zwobble.couscous.interpreter.values.InterpreterValue value = eval(environment, localVariableDeclaration.getInitialValue()); environment.put(localVariableDeclaration, value); return Optional.empty(); } - @Override public Optional<InterpreterValue> visit(IfStatementNode ifStatement) { List<StatementNode> body = evalCondition(environment, ifStatement.getCondition()) ? ifStatement.getTrueBranch() @@ -130,7 +125,6 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> return exec(body); } - @Override public Optional<InterpreterValue> visit(WhileNode whileLoop) { while (evalCondition(environment, whileLoop.getCondition())) { Optional<InterpreterValue> result = exec(whileLoop.getBody()); @@ -141,11 +135,6 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> return Optional.empty(); } - @Override - public Optional<InterpreterValue> visit(TryNode tryStatement) { - throw new UnsupportedOperationException(); - } - private Optional<InterpreterValue> exec(List<StatementNode> statements) { for (StatementNode statement : statements) { Optional<InterpreterValue> result = exec(environment, statement); |
