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 --- .../ast/untyped/UntypedFunctionStatementNode.java | 2 +- .../compiler/ast/untyped/UntypedReturnNode.java | 9 ++++++ .../java/org/shedlang/compiler/parser/Parser.java | 36 ++++++++++++++++------ .../shedlang/compiler/typechecker/TypeChecker.java | 6 ++++ 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/ast/untyped/UntypedReturnNode.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionStatementNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionStatementNode.java index 45d71235..6ecff062 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionStatementNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedFunctionStatementNode.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.ast.untyped; -public sealed interface UntypedFunctionStatementNode extends UntypedNode permits UntypedExpressionStatementNode, UntypedValNode { +public sealed interface UntypedFunctionStatementNode extends UntypedNode permits UntypedExpressionStatementNode, UntypedReturnNode, UntypedValNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedReturnNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedReturnNode.java new file mode 100644 index 00000000..36230db8 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedReturnNode.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.ast.untyped; + +import org.shedlang.compiler.sources.Source; + +public record UntypedReturnNode( + UntypedExpressionNode expression, + Source source +) implements UntypedFunctionStatementNode { +} 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); diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index 626f1f92..4f8d051b 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -71,6 +71,9 @@ public class TypeChecker { case UntypedExpressionStatementNode expressionStatement -> List.of(); + case UntypedReturnNode return_ -> + List.of(); + case UntypedValNode val -> targetVariables(val.target()); }; @@ -307,6 +310,9 @@ public class TypeChecker { case UntypedExpressionStatementNode expressionStatement -> typeCheckExpressionStatement(expressionStatement, context); + case UntypedReturnNode return_ -> + throw new UnsupportedOperationException("TODO"); + case UntypedValNode val -> typeCheckVal(val, context); }; -- cgit v1.2.3