diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-06-06 19:42:44 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-06-06 19:42:44 +0100 |
| commit | 9d66911592c3e3f34aaafdd09c7dd9d96e720e18 (patch) | |
| tree | 0e033546c49d221163f85d60f52f608a8b8f137e /src/main/java | |
| parent | 7c358460db1c42a5b7e79b7c6706ebf2adcff39f (diff) | |
Parse call with no effects and no args
Diffstat (limited to 'src/main/java')
7 files changed, 78 insertions, 11 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/UntypedArgsNode.java b/src/main/java/org/shedlang/compiler/ast/UntypedArgsNode.java new file mode 100644 index 00000000..4896bdc6 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/UntypedArgsNode.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.ast; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +public record UntypedArgsNode( + List<UntypedExpressionNode> positional, + List<UntypedNamedArgNode> named, + Source source +) implements UntypedNode { +} diff --git a/src/main/java/org/shedlang/compiler/ast/UntypedCallNode.java b/src/main/java/org/shedlang/compiler/ast/UntypedCallNode.java new file mode 100644 index 00000000..4b95885f --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/UntypedCallNode.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.ast; + +import org.shedlang.compiler.sources.Source; + +public record UntypedCallNode( + UntypedExpressionNode receiver, + UntypedArgsNode args, + boolean hasEffects, + Source source +) implements UntypedExpressionNode { +} diff --git a/src/main/java/org/shedlang/compiler/ast/UntypedExpressionNode.java b/src/main/java/org/shedlang/compiler/ast/UntypedExpressionNode.java index 0799550b..fcabfe0d 100644 --- a/src/main/java/org/shedlang/compiler/ast/UntypedExpressionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/UntypedExpressionNode.java @@ -1,5 +1,5 @@ package org.shedlang.compiler.ast; public sealed interface UntypedExpressionNode extends UntypedNode - permits UntypedReferenceNode, UntypedStringLiteralNode { + permits UntypedCallNode, UntypedReferenceNode, UntypedStringLiteralNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/UntypedNamedArgNode.java b/src/main/java/org/shedlang/compiler/ast/UntypedNamedArgNode.java new file mode 100644 index 00000000..149747f1 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/UntypedNamedArgNode.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.ast; + +import org.shedlang.compiler.sources.Source; + +public record UntypedNamedArgNode( + String name, + UntypedExpressionNode expression, + Source source +) implements UntypedNode { +} diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java index d4383fda..528c4c76 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -1,19 +1,46 @@ package org.shedlang.compiler.parser; -import org.shedlang.compiler.ast.UntypedExpressionNode; -import org.shedlang.compiler.ast.UntypedNamespaceNode; -import org.shedlang.compiler.ast.UntypedReferenceNode; -import org.shedlang.compiler.ast.UntypedStringLiteralNode; +import org.shedlang.compiler.ast.*; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.tokeniser.TokenIterator; import org.shedlang.compiler.tokeniser.UnexpectedTokenException; +import java.util.List; import java.util.regex.Pattern; public class Parser { private Parser() { } + private static UntypedExpressionNode parseCall(UntypedExpressionNode receiver, TokenIterator<TokenType> tokens) { + var start = receiver.source().start(); + + tokens.skip(TokenType.SYMBOL_PAREN_OPEN); + var args = parseArgs(tokens); + tokens.skip(TokenType.SYMBOL_PAREN_CLOSE); + + var end = tokens.position(); + var source = start.to(end); + + return new UntypedCallNode(receiver, args, false, source); + } + + private static UntypedArgsNode parseArgs(TokenIterator<TokenType> tokens) { + return new UntypedArgsNode(List.of(), List.of(), tokens.position()); + } + + private static UntypedExpressionNode parsePrimaryExpression(TokenIterator<TokenType> tokens) { + return switch (tokens.peek().tokenType()) { + + case IDENTIFIER -> parseReference(tokens); + + case STRING -> parseStringLiteral(tokens); + + default -> + throw new UnexpectedTokenException("expression", tokens.peek()); + }; + } + private static UntypedExpressionNode parseStringLiteral(TokenIterator<TokenType> tokens) { var start = tokens.position(); @@ -55,14 +82,13 @@ public class Parser { } static UntypedExpressionNode parseTopLevelExpression(TokenIterator<TokenType> tokens) { - return switch (tokens.peek().tokenType()) { - - case IDENTIFIER -> parseReference(tokens); + var left = parsePrimaryExpression(tokens); - case STRING -> parseStringLiteral(tokens); + while (tokens.isNext(TokenType.SYMBOL_PAREN_OPEN)) { + left = parseCall(left, tokens); + } - default -> throw new UnexpectedTokenException("expression", tokens.peek()); - }; + return left; } static UntypedNamespaceNode parseNamespace(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 a7f56c35..772d031d 100644 --- a/src/main/java/org/shedlang/compiler/parser/TokenType.java +++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java @@ -8,4 +8,8 @@ public enum TokenType { WHITESPACE, KEYWORD_FUN, + + SYMBOL_COMMA, + SYMBOL_PAREN_OPEN, + SYMBOL_PAREN_CLOSE, } diff --git a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java index 091212df..28aebb46 100644 --- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java +++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java @@ -19,6 +19,10 @@ public class Tokeniser { private static final RegexTokeniser<TokenType> tokeniser = new RegexTokeniser<>( TokenType.UNKNOWN, List.of( + RegexTokeniser.rule(TokenType.SYMBOL_COMMA, ","), + RegexTokeniser.rule(TokenType.SYMBOL_PAREN_OPEN, "\\("), + RegexTokeniser.rule(TokenType.SYMBOL_PAREN_CLOSE, "\\)"), + RegexTokeniser.rule(TokenType.IDENTIFIER, "[A-Za-z][A-Za-z0-9]*"), RegexTokeniser.rule(TokenType.STRING, "\"(?:[^\\\\\"\n\r]|\\\\.)*\""), RegexTokeniser.rule(TokenType.WHITESPACE, "[\r\n\t ]+") |
