diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-09 19:13:02 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-09 19:13:02 +0100 |
| commit | bf55e95953edeefad8e83c034bfb4920d99c29ba (patch) | |
| tree | 7e5e5060bf88af358e90e4d03cccc4c80f7630a3 /src | |
| parent | de846b1c61ba146da38be8a347d1c70dece75e52 (diff) | |
Add UntypedBlockNode
Diffstat (limited to 'src')
10 files changed, 64 insertions, 41 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedBlockNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedBlockNode.java new file mode 100644 index 00000000..2d686147 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedBlockNode.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.ast.untyped; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +public record UntypedBlockNode( + List<UntypedFunctionStatementNode> statements, + Source source +) implements UntypedNode { +} diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java index 7f9e96aa..b2558e46 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java @@ -2,11 +2,9 @@ package org.shedlang.compiler.ast.untyped; import org.shedlang.compiler.sources.Source; -import java.util.List; - public record UntypedConditionalBranchNode( UntypedExpressionNode condition, - List<UntypedFunctionStatementNode> body, + UntypedBlockNode body, Source source ) implements UntypedNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNode.java index 7c01256d..a8a6fa71 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNode.java @@ -5,7 +5,6 @@ import org.pcollections.PVector; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.sources.Sources; -import java.util.List; import java.util.Optional; public record UntypedFunctionDefinitionNode( @@ -13,7 +12,7 @@ public record UntypedFunctionDefinitionNode( UntypedParamsNode params, Optional<UntypedTypeLevelExpressionNode> effect, UntypedTypeLevelExpressionNode returnType, - List<UntypedFunctionStatementNode> body, + UntypedBlockNode body, Source source ) implements UntypedNamespaceStatementNode { public static Builder builder() { @@ -41,7 +40,7 @@ public record UntypedFunctionDefinitionNode( new UntypedParamsNode(positionalParams, namedParams, Sources.NULL), effect, returnType, - body, + new UntypedBlockNode(body, Sources.NULL), Sources.NULL ); } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java index 6baff19c..96f6172a 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java @@ -6,7 +6,7 @@ import java.util.List; public record UntypedIfNode( List<UntypedConditionalBranchNode> conditionalBranches, - List<UntypedFunctionStatementNode> elseBody, + UntypedBlockNode elseBody, Source source ) implements UntypedExpressionNode { } diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java index 3243eb17..184c3fdd 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -104,11 +104,16 @@ public class Parser { return new UntypedArgsNode(positional, named, argsSource); } - private static List<UntypedFunctionStatementNode> parseBlock(TokenIterator<TokenType> tokens) { + private static UntypedBlockNode parseBlock(TokenIterator<TokenType> tokens) { + var start = tokens.position(); + tokens.skip(TokenType.SYMBOL_BRACE_OPEN); if (tokens.trySkip(TokenType.SYMBOL_BRACE_CLOSE)) { - return List.of(); + var end = tokens.position(); + var source = start.to(end); + + return new UntypedBlockNode(List.of(), source); } var body = new ArrayList<UntypedFunctionStatementNode>(); @@ -123,7 +128,11 @@ public class Parser { statement.behaviour() == UntypedFunctionStatementBehaviour.BLOCK_RETURN ) { tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); - return body; + + var end = tokens.position(); + var source = start.to(end); + + return new UntypedBlockNode(body, source); } } } @@ -273,7 +282,7 @@ public class Parser { var start = tokens.position(); var conditionalBranches = new ArrayList<UntypedConditionalBranchNode>(); - var elseBody = List.<UntypedFunctionStatementNode>of(); + var elseBody = Optional.<UntypedBlockNode>empty(); while (true) { var conditionalBranch = parseConditionalBranch(tokens); @@ -284,7 +293,7 @@ public class Parser { } if (!tokens.isNext(TokenType.KEYWORD_IF)) { - elseBody = parseBlock(tokens); + elseBody = Optional.of(parseBlock(tokens)); break; } @@ -295,7 +304,7 @@ public class Parser { return new UntypedIfNode( conditionalBranches, - elseBody, + elseBody.orElseGet(() -> new UntypedBlockNode(List.of(), end)), source ); } diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index a604ae0b..60df3484 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -344,7 +344,7 @@ public class TypeChecker { ); } - for (var statement : untyped.body()) { + for (var statement : untyped.body().statements()) { for (var targetVariable : targetVariables(statement)) { bodyEnvironment = bodyEnvironment.add( targetVariable.name(), @@ -361,7 +361,7 @@ public class TypeChecker { ); var bodyResult = bodyContext.mapWithContext( - untyped.body(), + untyped.body().statements(), TypeChecker::typeCheckFunctionStatement ); var typedBody = bodyResult.value(); diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNodeMatcher.java index 8dae4a31..b94432da 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNodeMatcher.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedFunctionDefinitionNodeMatcher.java @@ -29,7 +29,7 @@ public class UntypedFunctionDefinitionNodeMatcher extends MatcherBuilder<Untyped return new UntypedFunctionDefinitionNodeMatcher(submatchers); } - public UntypedFunctionDefinitionNodeMatcher withBody(Matcher<Iterable<? extends UntypedFunctionStatementNode>> body) { + public UntypedFunctionDefinitionNodeMatcher withBody(Matcher<UntypedBlockNode> body) { return with(has("body", x -> x.body(), body)); } diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java index dce29e55..8ea1e13b 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/UntypedNodeMatchers.java @@ -34,6 +34,12 @@ public class UntypedNodeMatchers { ); } + public static Matcher<UntypedBlockNode> isUntypedBlockNode( + Matcher<Iterable<? extends UntypedFunctionStatementNode>> statements + ) { + return has("statements", x -> x.statements(), statements); + } + public static Matcher<UntypedFunctionStatementNode> isUntypedBlockReturnNode( Matcher<UntypedExpressionNode> expression ) { @@ -49,7 +55,7 @@ public class UntypedNodeMatchers { public static Matcher<UntypedConditionalBranchNode> isUntypedConditionalBranchNode( Matcher<UntypedExpressionNode> condition, - Matcher<Iterable<? extends UntypedFunctionStatementNode>> body + Matcher<UntypedBlockNode> body ) { return instanceOf( UntypedConditionalBranchNode.class, @@ -89,7 +95,7 @@ public class UntypedNodeMatchers { public static Matcher<UntypedExpressionNode> isUntypedIfNode( Matcher<Iterable<? extends UntypedConditionalBranchNode>> conditionalBranches, - Matcher<Iterable<? extends UntypedFunctionStatementNode>> elseBody + Matcher<UntypedBlockNode> elseBody ) { return instanceOf( UntypedIfNode.class, diff --git a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java index 279309f6..d799fa4d 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserFunctionDefinitionTests.java @@ -25,7 +25,7 @@ public class ParserFunctionDefinitionTests { .withParams(isUntypedParamsNode(isSequence(), isSequence())) .withEffect(isOptionalEmpty()) .withReturnType(isUntypedTypeLevelReferenceNode("Unit")) - .withBody(isSequence()) + .withBody(isUntypedBlockNode(isSequence())) ); } @@ -196,11 +196,11 @@ public class ParserFunctionDefinitionTests { assertThat( node, isUntypedFunctionDefinitionNode() - .withBody(isSequence( + .withBody(isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedReferenceNode("a")), isUntypedExpressionStatementNode(isUntypedReferenceNode("b")), isUntypedExpressionStatementNode(isUntypedReferenceNode("c")) - )) + ))) ); } @@ -218,11 +218,11 @@ public class ParserFunctionDefinitionTests { assertThat( node, isUntypedFunctionDefinitionNode() - .withBody(isSequence( + .withBody(isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedReferenceNode("a")), isUntypedExpressionStatementNode(isUntypedReferenceNode("b")), isUntypedBlockReturnNode(isUntypedReferenceNode("c")) - )) + ))) ); } diff --git a/src/test/java/org/shedlang/compiler/parser/ParserIfTests.java b/src/test/java/org/shedlang/compiler/parser/ParserIfTests.java index 5de0988d..5814dbf1 100644 --- a/src/test/java/org/shedlang/compiler/parser/ParserIfTests.java +++ b/src/test/java/org/shedlang/compiler/parser/ParserIfTests.java @@ -18,12 +18,12 @@ public class ParserIfTests { isSequence( isUntypedConditionalBranchNode( isUntypedReferenceNode("a"), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(1)) - ) + )) ) ), - isSequence() + isUntypedBlockNode(isSequence()) )); } @@ -37,14 +37,14 @@ public class ParserIfTests { isSequence( isUntypedConditionalBranchNode( isUntypedReferenceNode("a"), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(1)) - ) + )) ) ), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(2)) - ) + )) )); } @@ -58,18 +58,18 @@ public class ParserIfTests { isSequence( isUntypedConditionalBranchNode( isUntypedReferenceNode("a"), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(1)) - ) + )) ), isUntypedConditionalBranchNode( isUntypedReferenceNode("b"), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(2)) - ) + )) ) ), - isSequence() + isUntypedBlockNode(isSequence()) )); } @@ -83,20 +83,20 @@ public class ParserIfTests { isSequence( isUntypedConditionalBranchNode( isUntypedReferenceNode("a"), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(1)) - ) + )) ), isUntypedConditionalBranchNode( isUntypedReferenceNode("b"), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(2)) - ) + )) ) ), - isSequence( + isUntypedBlockNode(isSequence( isUntypedExpressionStatementNode(isUntypedIntLiteralNode(3)) - ) + )) )); } } |
