From 1c60ecab9d6323b4d1fe6a2b2a510c6c5a5672e3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 23 Dec 2023 11:44:45 +0000 Subject: Parse struct type level params --- .../ast/untyped/UntypedStructDefinitionNode.java | 8 +++++- .../ast/untyped/UntypedTypeLevelParamNode.java | 9 +++++++ .../java/org/shedlang/compiler/parser/Parser.java | 30 +++++++++++++++++++++- .../org/shedlang/compiler/parser/TokenType.java | 2 ++ .../org/shedlang/compiler/parser/Tokeniser.java | 2 ++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/ast/untyped/UntypedTypeLevelParamNode.java (limited to 'src/main/java') 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> typeLevelParams, List 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> typeLevelParams, PVector 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.>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 tokens) { @@ -1196,6 +1213,17 @@ public class Parser { return new UntypedTupleTypeNode(elements, source); } + private static UntypedTypeLevelParamNode parseTypeLevelParam(TokenIterator 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 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, "_") ) ); -- cgit v1.2.3