diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-06-06 20:03:43 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-06-06 20:03:43 +0100 |
| commit | 9d51478ffc90b4b7d059c38cae25beafe63eb40b (patch) | |
| tree | 29814b4e7976a43db26f970b378045c5676ecb0a /src/main/java/org | |
| parent | ab8b25ab08620df482d88c0e729fb9f53bca9f61 (diff) | |
Parse named arguments
Diffstat (limited to 'src/main/java/org')
3 files changed, 34 insertions, 6 deletions
diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java index 47c9d286..855634e7 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -31,18 +31,42 @@ public class Parser { } private static UntypedArgsNode parseArgs(TokenIterator<TokenType> tokens) { - var start = tokens.position(); + var argsStart = tokens.position(); + + var positional = new ArrayList<UntypedExpressionNode>(); + var named = new ArrayList<UntypedNamedArgNode>(); - var positional = parseMany( + parseMany( () -> tokens.isNext(TokenType.SYMBOL_PAREN_CLOSE), - () -> parseTopLevelExpression(tokens), + () -> { + if (tokens.trySkip(TokenType.SYMBOL_DOT)) { + var argStart = tokens.position(); + + var argName = tokens.nextValue(TokenType.IDENTIFIER); + tokens.skip(TokenType.SYMBOL_EQUALS); + var expression = parseTopLevelExpression(tokens); + + var argEnd = tokens.position(); + var argSource = argStart.to(argEnd); + + named.add(new UntypedNamedArgNode(argName, expression, argSource)); + } else { + var expression = parseTopLevelExpression(tokens); + // TODO: +// if (named.isEmpty()) { +// throw new PositionalArgAfterNamedArgError(tokens.peek()); +// } + positional.add(expression); + } + return null; + }, () -> tokens.trySkip(TokenType.SYMBOL_COMMA) ); - var end = tokens.position(); - var source = start.to(end); + var argsEnd = tokens.position(); + var argsSource = argsStart.to(argsEnd); - return new UntypedArgsNode(positional, List.of(), source); + return new UntypedArgsNode(positional, named, argsSource); } private static <T> List<T> parseMany( diff --git a/src/main/java/org/shedlang/compiler/parser/TokenType.java b/src/main/java/org/shedlang/compiler/parser/TokenType.java index fe01939a..41f18350 100644 --- a/src/main/java/org/shedlang/compiler/parser/TokenType.java +++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java @@ -11,6 +11,8 @@ public enum TokenType { SYMBOL_BANG, SYMBOL_COMMA, + SYMBOL_DOT, + SYMBOL_EQUALS, 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 0475d799..e604609c 100644 --- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java +++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java @@ -21,6 +21,8 @@ public class Tokeniser { List.of( RegexTokeniser.rule(TokenType.SYMBOL_BANG, "!"), RegexTokeniser.rule(TokenType.SYMBOL_COMMA, ","), + RegexTokeniser.rule(TokenType.SYMBOL_DOT, "\\."), + RegexTokeniser.rule(TokenType.SYMBOL_EQUALS, "="), RegexTokeniser.rule(TokenType.SYMBOL_PAREN_OPEN, "\\("), RegexTokeniser.rule(TokenType.SYMBOL_PAREN_CLOSE, "\\)"), |
