From fa240b137df27cf6a938eb0432ef62ad7ba718e4 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 5 Jul 2023 21:45:09 +0100 Subject: Parse implicit return --- .../java/org/shedlang/compiler/parser/Parser.java | 36 ++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) (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 b1794c6c..a2b7b09b 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -71,16 +71,40 @@ public class Parser { return new UntypedArgsNode(positional, named, argsSource); } + private static List parseBlock(TokenIterator tokens) { + tokens.skip(TokenType.SYMBOL_BRACE_OPEN); + + if (tokens.trySkip(TokenType.SYMBOL_BRACE_CLOSE)) { + return List.of(); + } + + var body = new ArrayList(); + + while (true) { + var statement = parseFunctionStatement(tokens); + + body.add(statement); + + if (tokens.isNext(TokenType.SYMBOL_BRACE_CLOSE) || statement instanceof UntypedReturnNode) { + tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); + return body; + } + } + } + private static UntypedFunctionStatementNode parseExpressionStatement(TokenIterator tokens) { var start = tokens.position(); var expression = parseTopLevelExpression(tokens); - tokens.skip(TokenType.SYMBOL_SEMICOLON); + + var isReturn = !tokens.trySkip(TokenType.SYMBOL_SEMICOLON); var end = tokens.position(); var source = start.to(end); - return new UntypedExpressionStatementNode(expression, source); + return isReturn + ? new UntypedReturnNode(expression, source) + : new UntypedExpressionStatementNode(expression, source); } private static UntypedNamespaceStatementNode parseFunctionDefinition(TokenIterator tokens) { @@ -103,13 +127,7 @@ public class Parser { tokens.skip(TokenType.SYMBOL_THIN_ARROW); var returnType = parseTopLevelTypeLevelExpression(tokens); - tokens.skip(TokenType.SYMBOL_BRACE_OPEN); - var body = parseMany( - () -> tokens.isNext(TokenType.SYMBOL_BRACE_CLOSE), - () -> parseFunctionStatement(tokens), - () -> true - ); - tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); + var body = parseBlock(tokens); var end = tokens.position(); var source = start.to(end); -- cgit v1.2.3