From 107ce1646e24b0d30f7fc42e831a7e5f03daecc3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 30 Sep 2023 11:01:22 +0100 Subject: Parse when expressions --- .../java/org/shedlang/compiler/parser/Parser.java | 41 +++++++++++++++++++++- .../org/shedlang/compiler/parser/TokenType.java | 2 ++ .../org/shedlang/compiler/parser/Tokeniser.java | 2 ++ 3 files changed, 44 insertions(+), 1 deletion(-) (limited to 'src/main/java/org/shedlang/compiler/parser') 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 tokens) { var start = tokens.position(); @@ -824,6 +825,44 @@ public class Parser { return new UntypedTypeLevelReferenceNode(name, source); } + private static UntypedExpressionNode parseWhen(TokenIterator 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 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 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) ); -- cgit v1.2.3