aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-08 21:42:45 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-08 21:42:45 +0100
commitcf52b6e8a2ebf85b4be8b9065a755f3481eb43db (patch)
tree553f99eee5123f7b06ae34ff657d975adf37b240 /src/main/java
parentb018be7fb57e79b62e727c1fb00bfd474888ddf8 (diff)
Parse if expressions
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedConditionalBranchNode.java12
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedExpressionNode.java2
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedIfNode.java12
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Parser.java50
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java3
5 files changed, 78 insertions, 1 deletions
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<UntypedFunctionStatementNode> 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<UntypedConditionalBranchNode> conditionalBranches,
+ List<UntypedFunctionStatementNode> 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<TokenType> tokens) {
+ var start = tokens.position();
+
+ var conditionalBranches = new ArrayList<UntypedConditionalBranchNode>();
+ var elseBody = List.<UntypedFunctionStatementNode>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<TokenType> 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<TokenType> 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);