aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-06 20:03:43 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-06 20:03:43 +0100
commit9d51478ffc90b4b7d059c38cae25beafe63eb40b (patch)
tree29814b4e7976a43db26f970b378045c5676ecb0a /src/main/java/org
parentab8b25ab08620df482d88c0e729fb9f53bca9f61 (diff)
Parse named arguments
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Parser.java36
-rw-r--r--src/main/java/org/shedlang/compiler/parser/TokenType.java2
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Tokeniser.java2
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, "\\)"),