diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-05 21:30:56 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-05 21:30:56 +0100 |
| commit | f497e7f884856ca91f3697886db559af070a92ba (patch) | |
| tree | 153550411103c5e17f51855957bedc25f74f8449 /src/main/java | |
| parent | 69c3b150b872e0e3bb75cafa21e5e2e2eea768cb (diff) | |
Parse function definition params
Diffstat (limited to 'src/main/java')
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, "="), |
