From 9d51478ffc90b4b7d059c38cae25beafe63eb40b Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 6 Jun 2023 20:03:43 +0100 Subject: Parse named arguments --- .../java/org/shedlang/compiler/parser/Parser.java | 36 ++++++++++++++++++---- .../org/shedlang/compiler/parser/TokenType.java | 2 ++ .../org/shedlang/compiler/parser/Tokeniser.java | 2 ++ 3 files changed, 34 insertions(+), 6 deletions(-) (limited to 'src/main/java') 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 tokens) { - var start = tokens.position(); + var argsStart = tokens.position(); + + var positional = new ArrayList(); + var named = new ArrayList(); - 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 List 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, "\\)"), -- cgit v1.2.3