diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-12-23 11:44:45 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-12-23 11:44:45 +0000 |
| commit | 1c60ecab9d6323b4d1fe6a2b2a510c6c5a5672e3 (patch) | |
| tree | 82d810b3fb2e6c6877133fb9c9eace8f02aa34e6 /src/main/java | |
| parent | ea47513fb5c1aef630be914295af7e8676d9fea9 (diff) | |
Parse struct type level params
Diffstat (limited to 'src/main/java')
5 files changed, 49 insertions, 2 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNode.java index 8767da19..148bd066 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedStructDefinitionNode.java @@ -7,26 +7,30 @@ import org.shedlang.compiler.types.Visibility; import org.shedlang.compiler.util.P; import java.util.List; +import java.util.Optional; public record UntypedStructDefinitionNode( String name, Visibility visibility, + Optional<List<UntypedTypeLevelParamNode>> typeLevelParams, List<UntypedStructFieldDefinitionNode> fields, Source source ) implements UntypedNamespaceStatementNode, UntypedVariableDeclarationNode { public static Builder builder() { - return new Builder("X", Visibility.PRIVATE, P.vector()); + return new Builder("X", Visibility.PRIVATE, Optional.empty(), P.vector()); } public record Builder( String name, Visibility visibility, + Optional<List<UntypedTypeLevelParamNode>> typeLevelParams, PVector<UntypedStructFieldDefinitionNode> fields ) { public UntypedStructDefinitionNode build() { return new UntypedStructDefinitionNode( this.name, this.visibility, + this.typeLevelParams, this.fields, Sources.NULL ); @@ -36,6 +40,7 @@ public record UntypedStructDefinitionNode( return new Builder( name, this.visibility, + this.typeLevelParams, this.fields ); } @@ -44,6 +49,7 @@ public record UntypedStructDefinitionNode( return new Builder( this.name, this.visibility, + this.typeLevelParams, this.fields.plus(field) ); } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedTypeLevelParamNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedTypeLevelParamNode.java new file mode 100644 index 00000000..73b31281 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedTypeLevelParamNode.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.ast.untyped; + +import org.shedlang.compiler.sources.Source; + +public record UntypedTypeLevelParamNode( + String name, + Source source +) implements UntypedNode { +} diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java index 1d56120b..d7ee611d 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -914,6 +914,17 @@ public class Parser { var name = tokens.nextValue(TokenType.IDENTIFIER); + var typeLevelParams = Optional.<List<UntypedTypeLevelParamNode>>empty(); + if (tokens.trySkip(TokenType.SYMBOL_SQUARE_OPEN)) { + typeLevelParams = Optional.of(parseMany( + () -> tokens.isNext(TokenType.SYMBOL_SQUARE_CLOSE), + () -> parseTypeLevelParam(tokens), + () -> tokens.trySkip(TokenType.SYMBOL_COMMA) + )); + + tokens.skip(TokenType.SYMBOL_SQUARE_CLOSE); + } + tokens.skip(TokenType.SYMBOL_PAREN_OPEN); var fields = parseMany( () -> tokens.isNext(TokenType.SYMBOL_PAREN_CLOSE), @@ -928,7 +939,13 @@ public class Parser { var end = tokens.position(); var source = start.to(end); - return new UntypedStructDefinitionNode(name, visibility, fields, source); + return new UntypedStructDefinitionNode( + name, + visibility, + typeLevelParams, + fields, + source + ); } private static UntypedStructFieldDefinitionNode parseStructFieldDefinition(TokenIterator<TokenType> tokens) { @@ -1196,6 +1213,17 @@ public class Parser { return new UntypedTupleTypeNode(elements, source); } + private static UntypedTypeLevelParamNode parseTypeLevelParam(TokenIterator<TokenType> tokens) { + var start = tokens.position(); + + var name = tokens.nextValue(TokenType.IDENTIFIER); + + var end = tokens.position(); + var source = start.to(end); + + return new UntypedTypeLevelParamNode(name, source); + } + private static UntypedTypeLevelReferenceNode parseTypeLevelReference(TokenIterator<TokenType> tokens) { var start = tokens.position(); diff --git a/src/main/java/org/shedlang/compiler/parser/TokenType.java b/src/main/java/org/shedlang/compiler/parser/TokenType.java index 9bbdbe83..f25986fe 100644 --- a/src/main/java/org/shedlang/compiler/parser/TokenType.java +++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java @@ -51,6 +51,8 @@ public enum TokenType { SYMBOL_PAREN_CLOSE, SYMBOL_PLUS, SYMBOL_SEMICOLON, + SYMBOL_SQUARE_OPEN, + SYMBOL_SQUARE_CLOSE, SYMBOL_THIN_ARROW, SYMBOL_UNDERSCORE, } diff --git a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java index 720b1a2f..22223ebf 100644 --- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java +++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java @@ -67,6 +67,8 @@ public class Tokeniser { RegexTokeniser.rule(TokenType.SYMBOL_PAREN_CLOSE, "\\)"), RegexTokeniser.rule(TokenType.SYMBOL_PLUS, "\\+"), RegexTokeniser.rule(TokenType.SYMBOL_SEMICOLON, ";"), + RegexTokeniser.rule(TokenType.SYMBOL_SQUARE_OPEN, "\\["), + RegexTokeniser.rule(TokenType.SYMBOL_SQUARE_CLOSE, "\\]"), RegexTokeniser.rule(TokenType.SYMBOL_UNDERSCORE, "_") ) ); |
