diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-09-30 11:01:22 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-09-30 11:01:22 +0100 |
| commit | 107ce1646e24b0d30f7fc42e831a7e5f03daecc3 (patch) | |
| tree | bdcf0c83b78e5ef4272964b9fdfe3735f301eb29 /src/main/java/org/shedlang/compiler/parser | |
| parent | fa6b2a24aad096824790501550623a7c3c2418c1 (diff) | |
Parse when expressions
Diffstat (limited to 'src/main/java/org/shedlang/compiler/parser')
3 files changed, 44 insertions, 1 deletions
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) ); |
