From cf52b6e8a2ebf85b4be8b9065a755f3481eb43db Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 8 Jul 2023 21:42:45 +0100 Subject: Parse if expressions --- .../ast/untyped/UntypedConditionalBranchNode.java | 12 ++++++ .../ast/untyped/UntypedExpressionNode.java | 2 +- .../compiler/ast/untyped/UntypedIfNode.java | 12 ++++++ .../java/org/shedlang/compiler/parser/Parser.java | 50 ++++++++++++++++++++++ .../shedlang/compiler/typechecker/TypeChecker.java | 3 ++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java create mode 100644 src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java new file mode 100644 index 00000000..7f9e96aa --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.ast.untyped; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +public record UntypedConditionalBranchNode( + UntypedExpressionNode condition, + List body, + Source source +) implements UntypedNode { +} diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedExpressionNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedExpressionNode.java index cabf5876..729d8279 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedExpressionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedExpressionNode.java @@ -1,5 +1,5 @@ package org.shedlang.compiler.ast.untyped; public sealed interface UntypedExpressionNode extends UntypedNode - permits UntypedBinaryOperationNode, UntypedBoolLiteralNode, UntypedCallNode, UntypedIntLiteralNode, UntypedReferenceNode, UntypedStringLiteralNode { + permits UntypedBinaryOperationNode, UntypedBoolLiteralNode, UntypedCallNode, UntypedIfNode, UntypedIntLiteralNode, UntypedReferenceNode, UntypedStringLiteralNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java new file mode 100644 index 00000000..6baff19c --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.ast.untyped; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +public record UntypedIfNode( + List conditionalBranches, + List 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 bfb756db..4dd59eb4 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -248,6 +248,54 @@ public class Parser { }; } + private static UntypedExpressionNode parseIf(TokenIterator tokens) { + var start = tokens.position(); + + var conditionalBranches = new ArrayList(); + var elseBody = List.of(); + + while (true) { + var conditionalBranch = parseConditionalBranch(tokens); + conditionalBranches.add(conditionalBranch); + + if (!tokens.trySkip(TokenType.KEYWORD_ELSE)) { + break; + } + + if (!tokens.isNext(TokenType.KEYWORD_IF)) { + elseBody = parseBlock(tokens); + break; + } + + } + + var end = tokens.position(); + var source = start.to(end); + + return new UntypedIfNode( + conditionalBranches, + elseBody, + source + ); + } + + private static UntypedConditionalBranchNode parseConditionalBranch(TokenIterator tokens) { + var start = tokens.position(); + + tokens.skip(TokenType.KEYWORD_IF); + + tokens.skip(TokenType.SYMBOL_PAREN_OPEN); + var condition = parseTopLevelExpression(tokens); + tokens.skip(TokenType.SYMBOL_PAREN_CLOSE); + + var body = parseBlock(tokens); + + var end = tokens.position(); + var source = start.to(end); + + return new UntypedConditionalBranchNode(condition, body, source); + } + private static UntypedExpressionNode parseInt(TokenIterator tokens) { var start = tokens.position(); @@ -333,6 +381,8 @@ public class Parser { case IDENTIFIER -> parseReference(tokens); case INT -> parseInt(tokens); + + case KEYWORD_IF -> parseIf(tokens); case STRING -> parseStringLiteral(tokens); diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index 273f1898..afe7f565 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -276,6 +276,9 @@ public class TypeChecker { case UntypedCallNode untypedCall -> typeCheckCall(untypedCall, context); + case UntypedIfNode untypedIf -> + throw new UnsupportedOperationException("TODO"); + case UntypedIntLiteralNode untypedIntLiteral -> typeCheckIntLiteral(untypedIntLiteral, context); -- cgit v1.2.3