diff options
Diffstat (limited to 'src')
14 files changed, 270 insertions, 24 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java new file mode 100644 index 0000000..ae3e29b --- /dev/null +++ b/src/main/java/org/zwobble/couscous/ast/IfStatementNode.java @@ -0,0 +1,90 @@ +package org.zwobble.couscous.ast; + +import java.util.List; + +import org.zwobble.couscous.ast.visitors.StatementNodeMapper; + +public class IfStatementNode implements StatementNode { + public static IfStatementNode ifStatement( + ExpressionNode condition, + List<StatementNode> trueBranch, + List<StatementNode> falseBranch) { + return new IfStatementNode(condition, trueBranch, falseBranch); + } + + private final ExpressionNode condition; + private final List<StatementNode> trueBranch; + private final List<StatementNode> falseBranch; + + private IfStatementNode( + ExpressionNode condition, + List<StatementNode> trueBranch, + List<StatementNode> falseBranch) { + this.condition = condition; + this.trueBranch = trueBranch; + this.falseBranch = falseBranch; + } + + public ExpressionNode getCondition() { + return condition; + } + + public List<StatementNode> getTrueBranch() { + return trueBranch; + } + + public List<StatementNode> getFalseBranch() { + return falseBranch; + } + + @Override + public <T> T accept(StatementNodeMapper<T> visitor) { + return visitor.visit(this); + } + + @Override + public String toString() { + return "IfStatementNode(condition=" + condition + ", trueBranch=" + + trueBranch + ", falseBranch=" + falseBranch + ")"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((condition == null) ? 0 : condition.hashCode()); + result = prime * result + + ((falseBranch == null) ? 0 : falseBranch.hashCode()); + result = prime * result + + ((trueBranch == null) ? 0 : trueBranch.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + IfStatementNode other = (IfStatementNode) obj; + if (condition == null) { + if (other.condition != null) + return false; + } else if (!condition.equals(other.condition)) + return false; + if (falseBranch == null) { + if (other.falseBranch != null) + return false; + } else if (!falseBranch.equals(other.falseBranch)) + return false; + if (trueBranch == null) { + if (other.trueBranch != null) + return false; + } else if (!trueBranch.equals(other.trueBranch)) + return false; + return true; + } +} diff --git a/src/main/java/org/zwobble/couscous/ast/StatementNode.java b/src/main/java/org/zwobble/couscous/ast/StatementNode.java index 7a1b25b..1186619 100644 --- a/src/main/java/org/zwobble/couscous/ast/StatementNode.java +++ b/src/main/java/org/zwobble/couscous/ast/StatementNode.java @@ -27,6 +27,12 @@ public interface StatementNode extends Node { visitor.visit(localVariableDeclaration); return null; } + + @Override + public Void visit(IfStatementNode ifStatement) { + visitor.visit(ifStatement); + return null; + } }); } } 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 8a88052..ce6bb52 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitor.java @@ -6,6 +6,7 @@ import org.zwobble.couscous.ast.ConstructorCallNode; import org.zwobble.couscous.ast.ConstructorNode; import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.FieldAccessNode; +import org.zwobble.couscous.ast.IfStatementNode; import org.zwobble.couscous.ast.LiteralNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.MethodCallNode; @@ -30,6 +31,7 @@ public interface NodeVisitor { void visit(ReturnNode returnNode); void visit(ExpressionStatementNode expressionStatement); void visit(LocalVariableDeclarationNode localVariableDeclaration); + void visit(IfStatementNode ifStatement); 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 index 8408b7a..fe57a28 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitorWithEmptyDefaults.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitorWithEmptyDefaults.java @@ -6,6 +6,7 @@ import org.zwobble.couscous.ast.ConstructorCallNode; import org.zwobble.couscous.ast.ConstructorNode; import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.FieldAccessNode; +import org.zwobble.couscous.ast.IfStatementNode; import org.zwobble.couscous.ast.LiteralNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.MethodCallNode; @@ -66,6 +67,10 @@ public interface NodeVisitorWithEmptyDefaults extends NodeVisitor { } @Override + default void visit(IfStatementNode ifStatement) { + } + + @Override default void visit(ClassNode classNode) { } diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java index 9424e39..1bcc226 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/NodeVisitors.java @@ -1,19 +1,20 @@ package org.zwobble.couscous.ast.visitors; +import java.util.List; + import org.zwobble.couscous.ast.AssignmentNode; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.ConstructorCallNode; import org.zwobble.couscous.ast.ConstructorNode; -import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.FieldAccessNode; +import org.zwobble.couscous.ast.IfStatementNode; 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.StatementNode; import org.zwobble.couscous.ast.StaticMethodCallNode; import org.zwobble.couscous.ast.TernaryConditionalNode; import org.zwobble.couscous.ast.ThisReferenceNode; @@ -56,25 +57,19 @@ public class NodeVisitors { public void visit(MethodCallNode methodCall) { visitor.visit(methodCall); methodCall.getReceiver().accept(this); - for (ExpressionNode argument : methodCall.getArguments()) { - argument.accept(this); - } + visitAll(methodCall.getArguments()); } @Override public void visit(StaticMethodCallNode staticMethodCall) { visitor.visit(staticMethodCall); - for (ExpressionNode argument : staticMethodCall.getArguments()) { - argument.accept(this); - } + visitAll(staticMethodCall.getArguments()); } @Override public void visit(ConstructorCallNode call) { visitor.visit(call); - for (ExpressionNode argument : call.getArguments()) { - argument.accept(this); - } + visitAll(call.getArguments()); } @Override @@ -99,27 +94,34 @@ public class NodeVisitors { visitor.visit(localVariableDeclaration); localVariableDeclaration.getInitialValue().accept(this); } - + + @Override + public void visit(IfStatementNode ifStatement) { + ifStatement.getCondition().accept(visitor); + visitAll(ifStatement.getTrueBranch()); + visitAll(ifStatement.getFalseBranch()); + } + @Override public void visit(ClassNode classNode) { visitor.visit(classNode); classNode.getConstructor().accept(this); - for (MethodNode method : classNode.getMethods()) { - method.accept(this); - } + visitAll(classNode.getMethods()); } @Override public void visit(MethodNode methodNode) { - for (StatementNode statement : methodNode.getBody()) { - statement.accept(this); - } + visitAll(methodNode.getBody()); } @Override public void visit(ConstructorNode constructorNode) { - for (StatementNode statement : constructorNode.getBody()) { - statement.accept(this); + visitAll(constructorNode.getBody()); + } + + private <T extends Node> void visitAll(List<T> nodes) { + for (Node node : nodes) { + node.accept(this); } } }); diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java b/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java index 4bae481..fe639bd 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/StatementNodeMapper.java @@ -1,6 +1,7 @@ package org.zwobble.couscous.ast.visitors; import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.IfStatementNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.ReturnNode; @@ -8,4 +9,5 @@ public interface StatementNodeMapper<T> { T visit(ReturnNode returnNode); T visit(ExpressionStatementNode expressionStatement); T visit(LocalVariableDeclarationNode localVariableDeclaration); + T visit(IfStatementNode ifStatement); } 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 fb1851c..75b9350 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; + import org.zwobble.couscous.ast.AssignmentNode; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.ConstructorCallNode; @@ -13,6 +14,7 @@ import org.zwobble.couscous.ast.ConstructorNode; import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.FieldAccessNode; +import org.zwobble.couscous.ast.IfStatementNode; import org.zwobble.couscous.ast.LiteralNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.MethodCallNode; @@ -45,11 +47,13 @@ import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValueVisitor; import org.zwobble.couscous.values.StringValue; import org.zwobble.couscous.values.UnitValue; + import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; + import static com.google.common.collect.Iterators.singletonIterator; import static java.util.Arrays.asList; import static org.zwobble.couscous.backends.python.ast.PythonAssignmentNode.pythonAssignment; @@ -59,6 +63,7 @@ import static org.zwobble.couscous.backends.python.ast.PythonCallNode.pythonCall import static org.zwobble.couscous.backends.python.ast.PythonClassNode.pythonClass; import static org.zwobble.couscous.backends.python.ast.PythonConditionalExpressionNode.pythonConditionalExpression; import static org.zwobble.couscous.backends.python.ast.PythonFunctionDefinitionNode.pythonFunctionDefinition; +import static org.zwobble.couscous.backends.python.ast.PythonIfStatementNode.pythonIfStatement; import static org.zwobble.couscous.backends.python.ast.PythonImportAliasNode.pythonImportAlias; import static org.zwobble.couscous.backends.python.ast.PythonImportNode.pythonImport; import static org.zwobble.couscous.backends.python.ast.PythonIntegerLiteralNode.pythonIntegerLiteral; @@ -117,7 +122,6 @@ public class PythonCodeGenerator { private static Set<TypeName> findReferencedClasses(ClassNode classNode) { ImmutableSet.Builder<TypeName> imports = ImmutableSet.builder(); NodeVisitors.visitAll(classNode, new NodeVisitorWithEmptyDefaults(){ - @Override public void visit(StaticMethodCallNode staticMethodCall) { imports.add(staticMethodCall.getClassName()); @@ -168,10 +172,16 @@ public class PythonCodeGenerator { Iterable<String> argumentNames = Iterables.concat( method.isStatic() ? Collections.<String>emptyList() : asList("self"), explicitArgumentNames); - List<PythonStatementNode> pythonBody = method.getBody().stream().map(PythonCodeGenerator::generateStatement).collect(Collectors.toList()); + List<PythonStatementNode> pythonBody = generateStatements(method.getBody()); return pythonFunctionDefinition(method.getName(), ImmutableList.copyOf(argumentNames), new PythonBlock(pythonBody)); } + private static List<PythonStatementNode> generateStatements(List<StatementNode> statements) { + return statements.stream() + .map(PythonCodeGenerator::generateStatement) + .collect(Collectors.toList()); + } + private static PythonStatementNode generateStatement(StatementNode statement) { return statement.accept(new StatementGenerator()); } @@ -196,6 +206,14 @@ public class PythonCodeGenerator { 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()), + generateStatements(ifStatement.getTrueBranch()), + generateStatements(ifStatement.getFalseBranch())); + } } private static PythonExpressionNode generateExpression(ExpressionNode expression) { diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java index 2fb341f..4eea760 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java @@ -13,6 +13,7 @@ import org.zwobble.couscous.backends.python.ast.PythonConditionalExpressionNode; import org.zwobble.couscous.backends.python.ast.PythonExpressionNode; import org.zwobble.couscous.backends.python.ast.PythonFunctionDefinitionNode; import org.zwobble.couscous.backends.python.ast.PythonGetSliceNode; +import org.zwobble.couscous.backends.python.ast.PythonIfStatementNode; import org.zwobble.couscous.backends.python.ast.PythonImportNode; import org.zwobble.couscous.backends.python.ast.PythonIntegerLiteralNode; import org.zwobble.couscous.backends.python.ast.PythonModuleNode; @@ -192,6 +193,20 @@ public class PythonSerializer implements PythonNodeVisitor { }); }); } + + @Override + public void visit(PythonIfStatementNode ifStatement) { + writer.writeStatement(() -> { + writer.writeKeyword("if"); + writer.writeSpace(); + write(ifStatement.getCondition()); + writeBlock(ifStatement.getTrueBranch()); + }); + writer.writeStatement(() -> { + writer.writeKeyword("else"); + writeBlock(ifStatement.getFalseBranch()); + }); + } private void writeParenthesised(PythonExpressionNode expression) { writer.writeSymbol("("); diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIfStatementNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIfStatementNode.java new file mode 100644 index 0000000..313f722 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIfStatementNode.java @@ -0,0 +1,53 @@ +package org.zwobble.couscous.backends.python.ast; + +import java.util.List; + +import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor; + +public class PythonIfStatementNode implements PythonStatementNode { + public static PythonIfStatementNode pythonIfStatement( + PythonExpressionNode condition, + List<PythonStatementNode> trueBranch, + List<PythonStatementNode> falseBranch) { + return new PythonIfStatementNode( + condition, + new PythonBlock(trueBranch), + new PythonBlock(falseBranch)); + } + + private final PythonExpressionNode condition; + private final PythonBlock trueBranch; + private final PythonBlock falseBranch; + + private PythonIfStatementNode( + PythonExpressionNode condition, + PythonBlock trueBranch, + PythonBlock falseBranch) { + this.condition = condition; + this.trueBranch = trueBranch; + this.falseBranch = falseBranch; + } + + public PythonExpressionNode getCondition() { + return condition; + } + + public PythonBlock getTrueBranch() { + return trueBranch; + } + + public PythonBlock getFalseBranch() { + return falseBranch; + } + + @Override + public String toString() { + return "PythonIfStatementNode(condition=" + condition + ", trueBranch=" + + trueBranch + ", falseBranch=" + falseBranch + ")"; + } + + @Override + public void accept(PythonNodeVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java index a1ed7d5..fb8fa71 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java @@ -9,6 +9,7 @@ import org.zwobble.couscous.backends.python.ast.PythonClassNode; import org.zwobble.couscous.backends.python.ast.PythonConditionalExpressionNode; import org.zwobble.couscous.backends.python.ast.PythonFunctionDefinitionNode; import org.zwobble.couscous.backends.python.ast.PythonGetSliceNode; +import org.zwobble.couscous.backends.python.ast.PythonIfStatementNode; import org.zwobble.couscous.backends.python.ast.PythonImportNode; import org.zwobble.couscous.backends.python.ast.PythonIntegerLiteralNode; import org.zwobble.couscous.backends.python.ast.PythonModuleNode; @@ -36,6 +37,7 @@ public interface PythonNodeVisitor { void visit(PythonFunctionDefinitionNode functionDefinition); void visit(PythonAssignmentNode assignment); void visit(PythonImportNode importNode); + void visit(PythonIfStatementNode ifStatement); void visit(PythonModuleNode module); diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index e47106d..6f33b4d 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -3,19 +3,22 @@ package org.zwobble.couscous.interpreter; import java.util.List; import java.util.Optional; import java.util.stream.Stream; + import org.zwobble.couscous.ast.CallableNode; import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.IfStatementNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.ReturnNode; import org.zwobble.couscous.ast.StatementNode; import org.zwobble.couscous.ast.VariableNode; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; +import org.zwobble.couscous.interpreter.values.BooleanInterpreterValue; import org.zwobble.couscous.interpreter.values.InterpreterValue; import org.zwobble.couscous.interpreter.values.UnitInterpreterValue; + import static org.zwobble.couscous.interpreter.Evaluator.eval; public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> { - public static InterpreterValue callMethod(Environment environment, CallableNode method, Optional<InterpreterValue> thisValue, PositionalArguments arguments) { final org.zwobble.couscous.interpreter.Environment innerEnvironment = buildEnvironment(environment, method, thisValue, arguments); for (final org.zwobble.couscous.ast.StatementNode statement : method.getBody()) { @@ -38,7 +41,6 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> private static Stream<VariableNode> findDeclarations(List<StatementNode> body) { return body.stream().flatMap(statement -> statement.accept(new StatementNodeMapper<Stream<VariableNode>>(){ - @Override public Stream<VariableNode> visit(ReturnNode returnNode) { return Stream.empty(); @@ -53,6 +55,12 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> public Stream<VariableNode> visit(LocalVariableDeclarationNode localVariableDeclaration) { return Stream.of(localVariableDeclaration); } + + @Override + public Stream<VariableNode> visit(IfStatementNode ifStatement) { + // TODO: Handle declarations in branches + return Stream.empty(); + } })); } @@ -82,4 +90,23 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> environment.put(localVariableDeclaration, value); return Optional.empty(); } + + @Override + public Optional<InterpreterValue> visit(IfStatementNode ifStatement) { + BooleanInterpreterValue condition = (BooleanInterpreterValue) eval(environment, ifStatement.getCondition()); + if (condition.getValue()) { + return exec(ifStatement.getTrueBranch()); + } + return Optional.empty(); + } + + private Optional<InterpreterValue> exec(List<StatementNode> statements) { + for (StatementNode statement : statements) { + Optional<InterpreterValue> result = exec(environment, statement); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } }
\ No newline at end of file diff --git a/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java b/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java index f1af3a9..f77140b 100644 --- a/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java +++ b/src/test/java/org/zwobble/couscous/tests/BackendMethodTests.java @@ -9,11 +9,13 @@ import org.zwobble.couscous.ast.MethodNode; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValues; import org.zwobble.couscous.values.StringValue; + import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.zwobble.couscous.ast.AssignmentNode.assign; import static org.zwobble.couscous.ast.ExpressionStatementNode.expressionStatement; import static org.zwobble.couscous.ast.FormalArgumentNode.formalArg; +import static org.zwobble.couscous.ast.IfStatementNode.ifStatement; import static org.zwobble.couscous.ast.LiteralNode.literal; import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration; import static org.zwobble.couscous.ast.MethodNode.staticMethod; @@ -85,6 +87,16 @@ public abstract class BackendMethodTests { assertEquals(value("[updated value]"), result); } + @Test + public void whenConditionIsTrueIfStatementExecutesTrueBranch() { + MethodNode.Builder method = staticMethod("hello") + .statement(ifStatement( + literal(true), + asList(returns(literal("[true]"))), + asList(returns(literal("[false]"))))); + assertEquals(value("[true]"), runMethod(method)); + } + protected PrimitiveValue runMethod(MethodNode.Builder methodBuilder, PrimitiveValue... arguments) { MethodNode method = methodBuilder.build(); String className = "com.example.Program"; diff --git a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java index e112a86..124f34b 100644 --- a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java +++ b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java @@ -23,6 +23,7 @@ import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.FieldAccessNode; import org.zwobble.couscous.ast.FieldDeclarationNode; import org.zwobble.couscous.ast.FormalArgumentNode; +import org.zwobble.couscous.ast.IfStatementNode; import org.zwobble.couscous.ast.LiteralNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.MethodCallNode; @@ -65,6 +66,7 @@ public class ValueObjectTests { {FieldAccessNode.class}, {FieldDeclarationNode.class}, {FormalArgumentNode.class}, + {IfStatementNode.class}, {LiteralNode.class}, {LocalVariableDeclarationNode.class}, {MethodCallNode.class}, diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java index 0f21758..c3782aa 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java @@ -15,6 +15,7 @@ import static org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode. import static org.zwobble.couscous.backends.python.ast.PythonCallNode.pythonCall; import static org.zwobble.couscous.backends.python.ast.PythonConditionalExpressionNode.pythonConditionalExpression; import static org.zwobble.couscous.backends.python.ast.PythonGetSliceNode.pythonGetSlice; +import static org.zwobble.couscous.backends.python.ast.PythonIfStatementNode.pythonIfStatement; import static org.zwobble.couscous.backends.python.ast.PythonImportAliasNode.pythonImportAlias; import static org.zwobble.couscous.backends.python.ast.PythonImportNode.pythonImport; import static org.zwobble.couscous.backends.python.ast.PythonIntegerLiteralNode.pythonIntegerLiteral; @@ -154,6 +155,15 @@ public class PythonSerializerTests { } @Test + public void ifStatementIsSerializedWithIfKeyword() { + String output = serialize(pythonIfStatement( + pythonBooleanLiteral(true), + asList(pythonReturn(pythonIntegerLiteral(1))), + asList(pythonReturn(pythonIntegerLiteral(2))))); + assertEquals("if True:\n return 1\nelse:\n return 2\n", output); + } + + @Test public void moduleIsSerializedStatements() { PythonModuleNode classNode = pythonModule(asList(PASS)); String output = serialize(classNode); |
