From 0c1f2b55c8b6753c128a34acf1a6cb160350e824 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 1 Nov 2023 22:42:06 +0000 Subject: Handle behaviour of if expressions properly --- .../parser/ParserExpressionStatementTests.java | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/parser/ParserExpressionStatementTests.java b/src/test/java/org/shedlang/compiler/parser/ParserExpressionStatementTests.java index 13698b85..bc414be1 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserExpressionStatementTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserExpressionStatementTests.java @@ -1,10 +1,19 @@ package org.shedlang.compiler.parser; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.untyped.Untyped; +import org.shedlang.compiler.ast.untyped.UntypedBlockNode; +import org.shedlang.compiler.ast.untyped.UntypedFunctionStatementBehaviour; +import org.shedlang.compiler.parser.errors.InconsistentBlockBehaviourError; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.shedlang.compiler.ast.untyped.UntypedNodeMatchers.*; import static org.shedlang.compiler.parser.ParserTesting.parseString; import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; import static org.zwobble.precisely.Matchers.isSequence; public class ParserExpressionStatementTests { @@ -82,4 +91,110 @@ public class ParserExpressionStatementTests { ) )); } + + @Nested + public class BranchBehaviourTests { + @Test + public void whenAllBranchesContinueThenExpressionStatementContinues() { + var blocks = List.of( + blockWithBehaviour(UntypedFunctionStatementBehaviour.CONTINUE), + blockWithBehaviour(UntypedFunctionStatementBehaviour.CONTINUE) + ); + + var result = Parser.expressionStatementBehaviour(blocks); + + assertThat(result, equalTo(UntypedFunctionStatementBehaviour.CONTINUE)); + } + + @Test + public void whenAllBranchesBlockThenExpressionStatementBlockReturns() { + var blocks = List.of( + blockWithBehaviour(UntypedFunctionStatementBehaviour.BLOCK_RETURN), + blockWithBehaviour(UntypedFunctionStatementBehaviour.BLOCK_RETURN) + ); + + var result = Parser.expressionStatementBehaviour(blocks); + + assertThat(result, equalTo(UntypedFunctionStatementBehaviour.BLOCK_RETURN)); + } + + @Test + public void whenAllBranchesTerminateThenExpressionStatementTerminates() { + var blocks = List.of( + blockWithBehaviour(UntypedFunctionStatementBehaviour.TERMINATE), + blockWithBehaviour(UntypedFunctionStatementBehaviour.TERMINATE) + ); + + var result = Parser.expressionStatementBehaviour(blocks); + + assertThat(result, equalTo(UntypedFunctionStatementBehaviour.TERMINATE)); + } + + @Test + public void whenBranchesTerminateOrContinueThenExpressionStatementContinues() { + var blocks = List.of( + blockWithBehaviour(UntypedFunctionStatementBehaviour.TERMINATE), + blockWithBehaviour(UntypedFunctionStatementBehaviour.CONTINUE), + blockWithBehaviour(UntypedFunctionStatementBehaviour.TERMINATE) + ); + + var result = Parser.expressionStatementBehaviour(blocks); + + assertThat(result, equalTo(UntypedFunctionStatementBehaviour.CONTINUE)); + } + + @Test + public void whenBranchesTerminateOrBlockReturnThenExpressionStatementBlockReturns() { + var blocks = List.of( + blockWithBehaviour(UntypedFunctionStatementBehaviour.TERMINATE), + blockWithBehaviour(UntypedFunctionStatementBehaviour.BLOCK_RETURN), + blockWithBehaviour(UntypedFunctionStatementBehaviour.TERMINATE) + ); + + var result = Parser.expressionStatementBehaviour(blocks); + + assertThat(result, equalTo(UntypedFunctionStatementBehaviour.BLOCK_RETURN)); + } + + @Test + public void whenBranchesContinueOrBlockReturnThenErrorIsThrown() { + var blocks = List.of( + blockWithBehaviour(UntypedFunctionStatementBehaviour.CONTINUE), + blockWithBehaviour(UntypedFunctionStatementBehaviour.BLOCK_RETURN) + ); + + assertThrows( + InconsistentBlockBehaviourError.class, + () -> Parser.expressionStatementBehaviour(blocks) + ); + } + + @Test + public void whenThereAreNoBranchesThenExpressionStatementTerminates() { + var blocks = List.of(); + + var result = Parser.expressionStatementBehaviour(blocks); + + assertThat(result, equalTo(UntypedFunctionStatementBehaviour.TERMINATE)); + } + + private UntypedBlockNode blockWithBehaviour(UntypedFunctionStatementBehaviour behaviour) { + var statement = switch (behaviour) { + case TERMINATE -> + Untyped.functionReturn(Untyped.intLiteral(0)); + + case BLOCK_RETURN -> + Untyped.blockReturn(Untyped.intLiteral(0)); + + case CONTINUE -> + Untyped.expressionStatement(Untyped.intLiteral(0)); + }; + + var block = Untyped.block(List.of(statement)); + + assertThat(block.behaviour(), equalTo(behaviour)); + + return block; + } + } } -- cgit v1.2.3