diff options
| author | Michael Williamson <mike@zwobble.org> | 2025-02-02 13:09:06 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2025-02-02 13:10:52 +0000 |
| commit | 1c88d4563baea119c86f90ba2ba0c1f9f2e37b91 (patch) | |
| tree | 421e7ed25dede77fd7823a8b4a1c310378d347bf /src/main/java | |
| parent | fb439df085eb1f7095d987973475a7753d0a1103 (diff) | |
Parse native type declarations
Diffstat (limited to 'src/main/java')
7 files changed, 145 insertions, 3 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceStatementNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceStatementNode.java index c4981b68..a49a3c85 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceStatementNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNamespaceStatementNode.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.ast.untyped; -public sealed interface UntypedNamespaceStatementNode extends UntypedNode permits UntypedAssignNode, UntypedEffectDefinitionNode, UntypedFunctionDefinitionNode, UntypedNativeFunctionDeclarationNode, UntypedStructDefinitionNode, UntypedSumTypeDefinitionNode { +public sealed interface UntypedNamespaceStatementNode extends UntypedNode permits UntypedAssignNode, UntypedEffectDefinitionNode, UntypedFunctionDefinitionNode, UntypedNativeFunctionDeclarationNode, UntypedNativeTypeDeclarationNode, UntypedStructDefinitionNode, UntypedSumTypeDefinitionNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNativeTypeDeclarationNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNativeTypeDeclarationNode.java new file mode 100644 index 00000000..fcfda66d --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedNativeTypeDeclarationNode.java @@ -0,0 +1,71 @@ +package org.shedlang.compiler.ast.untyped; + +import org.pcollections.PVector; +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; +import org.shedlang.compiler.types.Visibility; +import org.shedlang.compiler.util.P; + +import java.util.List; +import java.util.Optional; + +public record UntypedNativeTypeDeclarationNode( + String name, + Visibility visibility, + Optional<List<UntypedTypeLevelParamNode>> typeLevelParams, + List<UntypedNativeFunctionDeclarationNode> methods, + Source source +) implements UntypedNamespaceStatementNode, UntypedVariableDeclarationNode { + public static Builder builder() { + return new Builder( + "X", + Visibility.PRIVATE, + Optional.empty(), + P.vector() + ); + } + + public record Builder( + String name, + Visibility visibility, + Optional<List<UntypedTypeLevelParamNode>> typeLevelParams, + PVector<UntypedNativeFunctionDeclarationNode> methods + ) { + public UntypedNativeTypeDeclarationNode build() { + return new UntypedNativeTypeDeclarationNode( + this.name, + this.visibility, + this.typeLevelParams, + this.methods, + Sources.NULL + ); + } + + public Builder withName(String name) { + return new Builder( + name, + this.visibility, + this.typeLevelParams, + this.methods + ); + } + + public Builder withTypeLevelParams(List<UntypedTypeLevelParamNode> typeLevelParams) { + return new Builder( + this.name, + this.visibility, + Optional.of(typeLevelParams), + this.methods + ); + } + + public Builder addMethod(UntypedNativeFunctionDeclarationNode method) { + return new Builder( + this.name, + this.visibility, + this.typeLevelParams, + this.methods.plus(method) + ); + } + } +} diff --git a/src/main/java/org/shedlang/compiler/parser/Parser.java b/src/main/java/org/shedlang/compiler/parser/Parser.java index 45533683..a6b2e1ff 100644 --- a/src/main/java/org/shedlang/compiler/parser/Parser.java +++ b/src/main/java/org/shedlang/compiler/parser/Parser.java @@ -777,7 +777,16 @@ public class Parser { parseFunctionDefinition(tokens); case KEYWORD_NATIVE -> - parseNativeFunctionDeclaration(tokens); + switch (tokens.peek(1).tokenType()) { + case KEYWORD_FUN -> + parseNativeFunctionDeclaration(tokens); + + case KEYWORD_TYPE -> + parseNativeTypeDeclaration(tokens); + + default -> + throw new UnexpectedTokenException("namespace statement", tokens.peek()); + }; case KEYWORD_PUB -> switch (tokens.peek(1).tokenType()) { @@ -788,7 +797,16 @@ public class Parser { parseFunctionDefinition(tokens); case KEYWORD_NATIVE -> - parseNativeFunctionDeclaration(tokens); + switch (tokens.peek(2).tokenType()) { + case KEYWORD_FUN -> + parseNativeFunctionDeclaration(tokens); + + case KEYWORD_TYPE -> + parseNativeTypeDeclaration(tokens); + + default -> + throw new UnexpectedTokenException("namespace statement", tokens.peek()); + }; case KEYWORD_STRUCT -> parseStructDefinition(tokens); @@ -843,6 +861,41 @@ public class Parser { ); } + private static UntypedNamespaceStatementNode parseNativeTypeDeclaration( + TokenIterator<TokenType> tokens + ) { + var start = tokens.startPosition(); + + var visibility = parseVisibility(tokens); + + tokens.skip(TokenType.KEYWORD_NATIVE); + tokens.skip(TokenType.KEYWORD_TYPE); + var name = tokens.nextValue(TokenType.IDENTIFIER); + + var typeLevelParams = parseTypeLevelParamsOptional(tokens); + + tokens.skip(TokenType.SYMBOL_BRACE_OPEN); + + var methods = parseMany( + () -> tokens.isNext(TokenType.SYMBOL_BRACE_CLOSE), + () -> parseNativeFunctionDeclaration(tokens), + () -> true + ); + + tokens.skip(TokenType.SYMBOL_BRACE_CLOSE); + + var end = tokens.endPosition(); + var source = new FileFragmentSource(start.to(end)); + + return new UntypedNativeTypeDeclarationNode( + name, + visibility, + typeLevelParams, + methods, + source + ); + } + private static UntypedParamsNode parseParams(TokenIterator<TokenType> tokens) { var paramsStart = tokens.startPosition(); diff --git a/src/main/java/org/shedlang/compiler/parser/TokenType.java b/src/main/java/org/shedlang/compiler/parser/TokenType.java index 5eee208c..77f566fb 100644 --- a/src/main/java/org/shedlang/compiler/parser/TokenType.java +++ b/src/main/java/org/shedlang/compiler/parser/TokenType.java @@ -29,6 +29,7 @@ public enum TokenType { KEYWORD_SUMTYPE, KEYWORD_TRUE, KEYWORD_TRY, + KEYWORD_TYPE, KEYWORD_UNIT, KEYWORD_VAL, KEYWORD_VAR, diff --git a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java index 6e5bed3f..c09d6974 100644 --- a/src/main/java/org/shedlang/compiler/parser/Tokeniser.java +++ b/src/main/java/org/shedlang/compiler/parser/Tokeniser.java @@ -33,6 +33,7 @@ public class Tokeniser { Map.entry("sumtype", TokenType.KEYWORD_SUMTYPE), Map.entry("true", TokenType.KEYWORD_TRUE), Map.entry("try", TokenType.KEYWORD_TRY), + Map.entry("type", TokenType.KEYWORD_TYPE), Map.entry("unit", TokenType.KEYWORD_UNIT), Map.entry("val", TokenType.KEYWORD_VAL), Map.entry("var", TokenType.KEYWORD_VAR), diff --git a/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariables.java b/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariables.java index a2a8b253..166489da 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariables.java +++ b/src/main/java/org/shedlang/compiler/typechecker/DeclaredVariables.java @@ -110,6 +110,12 @@ class DeclaredVariables { nativeFunctionDeclaration )); + case UntypedNativeTypeDeclarationNode nativeTypeDeclaration -> + variables.plus(DeclaredVariable.fromNode( + VariableType.CONSTANT, + nativeTypeDeclaration + )); + case UntypedStructDefinitionNode struct -> variables.plus(DeclaredVariable.fromNode( VariableType.CONSTANT, diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index 5feee88b..dd85cd98 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -1507,6 +1507,13 @@ public class TypeChecker { ); } + case UntypedNativeTypeDeclarationNode untypedNativeTypeDeclaration -> { + dependencyChecker = dependencyChecker.addDeferredDependencies( + untypedNativeTypeDeclaration.name(), + dependencies + ); + } + case UntypedStructDefinitionNode untypedStruct -> { dependencyChecker = dependencyChecker.addDeferredDependencies( untypedStruct.name(), @@ -1582,6 +1589,9 @@ public class TypeChecker { case UntypedNativeFunctionDeclarationNode nativeFunctionDeclaration -> typeCheckStepsNativeFunctionDeclaration(nativeFunctionDeclaration); + case UntypedNativeTypeDeclarationNode nativeTypeDeclaration -> + throw new UnsupportedOperationException("TODO"); + case UntypedStructDefinitionNode structDefinition -> typeCheckStepsStructDefinition(structDefinition); |
