aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-05 21:30:56 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-05 21:30:56 +0100
commitf497e7f884856ca91f3697886db559af070a92ba (patch)
tree153550411103c5e17f51855957bedc25f74f8449 /src/main/java
parent69c3b150b872e0e3bb75cafa21e5e2e2eea768cb (diff)
Parse function definition params
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Parser.java35
-rw-r--r--src/main/java/org/shedlang/compiler/parser/PositionalParamAfterNamedParamError.java11
-rw-r--r--src/main/java/org/shedlang/compiler/parser/TokenType.java1
-rw-r--r--src/main/java/org/shedlang/compiler/parser/Tokeniser.java1
4 files changed, 44 insertions, 4 deletions
diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java
index 69d02075..b1794c6c 100644
--- a/src/main/java/org/shedlang/compiler/parser/Parser.java
+++ b/src/main/java/org/shedlang/compiler/parser/Parser.java
@@ -178,12 +178,39 @@ public class Parser {
}
private static UntypedParamsNode parseParams(TokenIterator<TokenType> tokens) {
- var start = tokens.position();
+ var paramsStart = tokens.position();
- var end = tokens.position();
- var source = start.to(end);
+ var positional = new ArrayList<UntypedParamNode>();
+ var named = new ArrayList<UntypedParamNode>();
+
+ parseMany(
+ () -> tokens.isNext(TokenType.SYMBOL_PAREN_CLOSE),
+ () -> {
+ var isNamed = tokens.trySkip(TokenType.SYMBOL_DOT);
+
+ var paramStart = tokens.position();
+
+ var name = tokens.nextValue(TokenType.IDENTIFIER);
+ tokens.skip(TokenType.SYMBOL_COLON);
+ var type = parseTopLevelTypeLevelExpression(tokens);
+ if (!isNamed && !named.isEmpty()) {
+ throw new PositionalParamAfterNamedParamError(type.source());
+ }
+
+ var paramEnd = tokens.position();
+ var paramSource = paramStart.to(paramEnd);
+
+ (isNamed ? named : positional).add(new UntypedParamNode(name, type, paramSource));
+
+ return null;
+ },
+ () -> tokens.trySkip(TokenType.SYMBOL_COMMA)
+ );
+
+ var paramsEnd = tokens.position();
+ var paramsSource = paramsStart.to(paramsEnd);
- return new UntypedParamsNode(List.of(), List.of(), source);
+ return new UntypedParamsNode(positional, named, paramsSource);
}
private static UntypedExpressionNode parsePrimaryExpression(TokenIterator<TokenType> tokens) {
diff --git a/src/main/java/org/shedlang/compiler/parser/PositionalParamAfterNamedParamError.java b/src/main/java/org/shedlang/compiler/parser/PositionalParamAfterNamedParamError.java
new file mode 100644
index 00000000..e32865f6
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/parser/PositionalParamAfterNamedParamError.java
@@ -0,0 +1,11 @@
+package org.shedlang.compiler.parser;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+
+public class PositionalParamAfterNamedParamError extends SourceError {
+ public PositionalParamAfterNamedParamError(Source source) {
+ super("Positional param cannot follow named param", source);
+ }
+}
+
diff --git a/src/main/java/org/shedlang/compiler/parser/TokenType.java b/src/main/java/org/shedlang/compiler/parser/TokenType.java
index 21e830f0..2972ce59 100644
--- a/src/main/java/org/shedlang/compiler/parser/TokenType.java
+++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java
@@ -16,6 +16,7 @@ public enum TokenType {
SYMBOL_BANG,
SYMBOL_BRACE_OPEN,
SYMBOL_BRACE_CLOSE,
+ SYMBOL_COLON,
SYMBOL_COMMA,
SYMBOL_DOT,
SYMBOL_EQUALS,
diff --git a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java
index 131462f7..4c06a20a 100644
--- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java
+++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java
@@ -27,6 +27,7 @@ public class Tokeniser {
RegexTokeniser.rule(TokenType.SYMBOL_BANG, "!"),
RegexTokeniser.rule(TokenType.SYMBOL_BRACE_OPEN, "\\{"),
RegexTokeniser.rule(TokenType.SYMBOL_BRACE_CLOSE, "\\}"),
+ RegexTokeniser.rule(TokenType.SYMBOL_COLON, ":"),
RegexTokeniser.rule(TokenType.SYMBOL_COMMA, ","),
RegexTokeniser.rule(TokenType.SYMBOL_DOT, "\\."),
RegexTokeniser.rule(TokenType.SYMBOL_EQUALS, "="),