aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-30 11:01:22 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-30 11:01:22 +0100
commit107ce1646e24b0d30f7fc42e831a7e5f03daecc3 (patch)
treebdcf0c83b78e5ef4272964b9fdfe3735f301eb29 /src/main/java
parentfa6b2a24aad096824790501550623a7c3c2418c1 (diff)
Parse when expressions
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedExpressionNode.java2
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenCaseNode.java10
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenNode.java12
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Parser.java41
-rw-r--r--src/main/java/org/shedlang/compiler/parser/TokenType.java2
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Tokeniser.java2
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java3
7 files changed, 70 insertions, 2 deletions
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 b1d7ba83..107bc20b 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, UntypedFieldAccessNode, UntypedIfNode, UntypedIntLiteralNode, UntypedReferenceNode, UntypedStringLiteralNode, UntypedTupleNode {
+ permits UntypedBinaryOperationNode, UntypedBoolLiteralNode, UntypedCallNode, UntypedFieldAccessNode, UntypedIfNode, UntypedIntLiteralNode, UntypedReferenceNode, UntypedStringLiteralNode, UntypedTupleNode, UntypedWhenNode {
}
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenCaseNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenCaseNode.java
new file mode 100644
index 00000000..7b3e95b9
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenCaseNode.java
@@ -0,0 +1,10 @@
+package org.shedlang.compiler.ast.untyped;
+
+import org.shedlang.compiler.sources.Source;
+
+public record UntypedWhenCaseNode(
+ UntypedTypeLevelExpressionNode caseType,
+ UntypedBlockNode body,
+ Source source
+) implements UntypedNode {
+}
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenNode.java
new file mode 100644
index 00000000..e8c2d348
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedWhenNode.java
@@ -0,0 +1,12 @@
+package org.shedlang.compiler.ast.untyped;
+
+import org.shedlang.compiler.sources.Source;
+
+import java.util.List;
+
+public record UntypedWhenNode(
+ UntypedExpressionNode expression,
+ List<UntypedWhenCaseNode> cases,
+ 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 84900688..71490933 100644
--- a/src/main/java/org/shedlang/compiler/parser/Parser.java
+++ b/src/main/java/org/shedlang/compiler/parser/Parser.java
@@ -540,6 +540,8 @@ public class Parser {
case KEYWORD_IF -> parseIf(tokens);
case KEYWORD_FALSE, KEYWORD_TRUE -> parseBoolLiteral(tokens);
+
+ case KEYWORD_WHEN -> parseWhen(tokens);
case STRING -> parseStringLiteral(tokens);
@@ -812,7 +814,6 @@ public class Parser {
return new UntypedTupleTypeNode(elements, source);
}
-
private static UntypedTypeLevelReferenceNode parseTypeLevelReference(TokenIterator<TokenType> tokens) {
var start = tokens.position();
@@ -824,6 +825,44 @@ public class Parser {
return new UntypedTypeLevelReferenceNode(name, source);
}
+ private static UntypedExpressionNode parseWhen(TokenIterator<TokenType> tokens) {
+ var start = tokens.position();
+
+ tokens.skip(TokenType.KEYWORD_WHEN);
+
+ tokens.skip(TokenType.SYMBOL_PAREN_OPEN);
+ var expression = parseTopLevelExpression(tokens);
+ tokens.skip(TokenType.SYMBOL_PAREN_CLOSE);
+
+ tokens.skip(TokenType.SYMBOL_BRACE_OPEN);
+ var cases = parseMany(
+ () -> tokens.isNext(TokenType.SYMBOL_BRACE_CLOSE),
+ () -> parseWhenCase(tokens),
+ () -> true
+ );
+ tokens.skip(TokenType.SYMBOL_BRACE_CLOSE);
+
+ var end = tokens.position();
+ var source = start.to(end);
+
+ return new UntypedWhenNode(expression, cases, source);
+ }
+
+ private static UntypedWhenCaseNode parseWhenCase(TokenIterator<TokenType> tokens) {
+ var start = tokens.position();
+
+ tokens.skip(TokenType.KEYWORD_IS);
+
+ var caseType = parseTopLevelTypeLevelExpression(tokens);
+
+ var body = parseBlock(tokens);
+
+ var end = tokens.position();
+ var source = start.to(end);
+
+ return new UntypedWhenCaseNode(caseType, body, source);
+ }
+
private static UntypedFunctionStatementNode parseWhile(
TokenIterator<TokenType> tokens
) {
diff --git a/src/main/java/org/shedlang/compiler/parser/TokenType.java b/src/main/java/org/shedlang/compiler/parser/TokenType.java
index 9c8183dc..e2350ae2 100644
--- a/src/main/java/org/shedlang/compiler/parser/TokenType.java
+++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java
@@ -14,12 +14,14 @@ public enum TokenType {
KEYWORD_FALSE,
KEYWORD_FUN,
KEYWORD_IF,
+ KEYWORD_IS,
KEYWORD_RETURN,
KEYWORD_STRUCT,
KEYWORD_SUMTYPE,
KEYWORD_TRUE,
KEYWORD_VAL,
KEYWORD_VAR,
+ KEYWORD_WHEN,
KEYWORD_WHILE,
SYMBOL_BANG,
diff --git a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java
index 7659d717..e7f04189 100644
--- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java
+++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java
@@ -18,12 +18,14 @@ public class Tokeniser {
Map.entry("false", TokenType.KEYWORD_FALSE),
Map.entry("fun", TokenType.KEYWORD_FUN),
Map.entry("if", TokenType.KEYWORD_IF),
+ Map.entry("is", TokenType.KEYWORD_IS),
Map.entry("return", TokenType.KEYWORD_RETURN),
Map.entry("struct", TokenType.KEYWORD_STRUCT),
Map.entry("sumtype", TokenType.KEYWORD_SUMTYPE),
Map.entry("true", TokenType.KEYWORD_TRUE),
Map.entry("val", TokenType.KEYWORD_VAL),
Map.entry("var", TokenType.KEYWORD_VAR),
+ Map.entry("when", TokenType.KEYWORD_WHEN),
Map.entry("while", TokenType.KEYWORD_WHILE)
);
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 7c3741e2..c630b9dc 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -406,6 +406,9 @@ public class TypeChecker {
case UntypedTupleNode untypedTuple ->
typeCheckTuple(untypedTuple, context);
+
+ case UntypedWhenNode untypedWhen ->
+ throw new UnsupportedOperationException();
};
}