From bd1515f9b219cef789cc31b2f8efbb217bfc2c3c Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 7 Feb 2025 20:53:02 +0000 Subject: Add basic type checking for native type declarations --- .../ast/typed/TypedNamespaceStatementNode.java | 2 +- .../ast/typed/TypedNativeTypeDeclarationNode.java | 50 ++++++++++++++++++++++ .../org/shedlang/compiler/shid/ShidCodeGen.java | 6 +++ .../shedlang/compiler/typechecker/TypeChecker.java | 44 ++++++++++++++++++- ...notDefineNativeTypeOutsideOfNamespaceError.java | 10 +++++ .../java/org/shedlang/compiler/types/Scope.java | 2 +- .../org/shedlang/compiler/types/TypeParam.java | 2 +- 7 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/ast/typed/TypedNativeTypeDeclarationNode.java create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineNativeTypeOutsideOfNamespaceError.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java index d38cff5e..c63b58d7 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.ast.typed; -public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedAssignNode, TypedEffectDefinitionNode, TypedFunctionDefinitionNode, TypedNativeFunctionDeclarationNode, TypedStructDefinitionNode, TypedSumTypeDefinitionNode { +public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedAssignNode, TypedEffectDefinitionNode, TypedFunctionDefinitionNode, TypedNativeFunctionDeclarationNode, TypedNativeTypeDeclarationNode, TypedStructDefinitionNode, TypedSumTypeDefinitionNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeTypeDeclarationNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeTypeDeclarationNode.java new file mode 100644 index 00000000..2c438577 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedNativeTypeDeclarationNode.java @@ -0,0 +1,50 @@ +package org.shedlang.compiler.ast.typed; + +import org.pcollections.PVector; +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; +import org.shedlang.compiler.types.*; +import org.shedlang.compiler.util.P; + +import java.util.List; + +public record TypedNativeTypeDeclarationNode( + TypeOrConstructor typeOrConstructor, + List methods, + Source source +) implements TypedNamespaceStatementNode { + public static Builder builder() { + var namespaceName = NamespaceName.of("Default", "Test", "Namespace"); + return new Builder( + TypeOrConstructor.type(Types.nativeType(namespaceName, "X")), + P.vector() + ); + } + + public record Builder( + TypeOrConstructor type, + PVector methods + ) { + public TypedNativeTypeDeclarationNode build() { + return new TypedNativeTypeDeclarationNode( + this.type, + this.methods, + Sources.NULL + ); + } + + public Builder withType(SimpleNativeType type) { + return new Builder( + TypeOrConstructor.type(type), + this.methods + ); + } + + public Builder addMethod(TypedNativeFunctionDeclarationNode method) { + return new Builder( + this.type, + this.methods.plus(method) + ); + } + } +} diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java index bf6d2072..11827861 100644 --- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java +++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java @@ -593,6 +593,9 @@ public class ShidCodeGen { case TypedNativeFunctionDeclarationNode nativeFunctionDeclaration -> 1; + case TypedNativeTypeDeclarationNode nativeTypeDeclaration -> + 0; + case TypedStructDefinitionNode structDefinition -> 0; @@ -642,6 +645,9 @@ public class ShidCodeGen { case TypedNativeFunctionDeclarationNode nativeFunctionDeclaration -> compileNativeFunctionDeclaration(nativeFunctionDeclaration, context); + case TypedNativeTypeDeclarationNode nativeTypeDeclarationNode -> + throw new UnsupportedOperationException("TODO"); + case TypedStructDefinitionNode structDefinition -> compileStructDefinition(structDefinition, context); diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index 98fe892e..a9d98ff2 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -1609,7 +1609,7 @@ public class TypeChecker { typeCheckStepsNativeFunctionDeclaration(nativeFunctionDeclaration); case UntypedNativeTypeDeclarationNode nativeTypeDeclaration -> - throw new UnsupportedOperationException("TODO"); + typeCheckStepsNativeTypeDeclaration(nativeTypeDeclaration); case UntypedStructDefinitionNode structDefinition -> typeCheckStepsStructDefinition(structDefinition); @@ -1658,6 +1658,48 @@ public class TypeChecker { }; } + private static TypeCheckSteps typeCheckStepsNativeTypeDeclaration( + UntypedNativeTypeDeclarationNode untyped + ) { + return new TypeCheckSteps<>() { + @Override + public TypeCheckerContext declareTypes(TypeCheckerContext context) { + var namespaceName = context.namespaceName() + .orElseThrow(() -> new CannotDefineNativeTypeOutsideOfNamespaceError(untyped.source())); + + var type = new SimpleNativeType(namespaceName, untyped.name()); + + var typeOrConstructor = createTypeOrConstructor( + untyped.typeLevelParams(), + type, + new Scope.NativeType(type) + ); + + context = context.addLexicalState(untyped.name(), typeOrConstructor); + + return context.declareVariableType( + untyped.name(), + typeOrConstructor.toMetaType(), + untyped.source() + ); + } + + @Override + public TypeCheckerResult finish(TypeCheckerContext context) { + var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( + TypeOrConstructor.class, + untyped.name() + ); + + return context.toResult(new TypedNativeTypeDeclarationNode( + typeOrConstructor, + List.of(), + untyped.source() + )); + } + }; + } + private static TypedParamNode typeCheckParam( UntypedParamNode untyped, TypeCheckerContext context diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineNativeTypeOutsideOfNamespaceError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineNativeTypeOutsideOfNamespaceError.java new file mode 100644 index 00000000..01e9dead --- /dev/null +++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineNativeTypeOutsideOfNamespaceError.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.typechecker.errors; + +import org.shedlang.compiler.errors.InternalCompilerError; +import org.shedlang.compiler.sources.Source; + +public class CannotDefineNativeTypeOutsideOfNamespaceError extends InternalCompilerError { + public CannotDefineNativeTypeOutsideOfNamespaceError(Source source) { + super("Cannot define native type outside of namespace", source); + } +} diff --git a/src/main/java/org/shedlang/compiler/types/Scope.java b/src/main/java/org/shedlang/compiler/types/Scope.java index b0141916..9a61e51e 100644 --- a/src/main/java/org/shedlang/compiler/types/Scope.java +++ b/src/main/java/org/shedlang/compiler/types/Scope.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.types; public sealed interface Scope { record Function(NamespaceName namespaceName, String name) implements Scope {} - record Native(NativeType type) implements Scope {} + record NativeType(org.shedlang.compiler.types.NativeType type) implements Scope {} record Struct(SimpleStructType type) implements Scope {} record Sum(SimpleSumType type) implements Scope {} } diff --git a/src/main/java/org/shedlang/compiler/types/TypeParam.java b/src/main/java/org/shedlang/compiler/types/TypeParam.java index 6d311940..c996dd97 100644 --- a/src/main/java/org/shedlang/compiler/types/TypeParam.java +++ b/src/main/java/org/shedlang/compiler/types/TypeParam.java @@ -10,7 +10,7 @@ public record TypeParam(Scope scope, String name) implements Type, TypeLevelPara } public static TypeParam forNativeType(SimpleNativeType nativeType, String name) { - return new TypeParam(new Scope.Native(nativeType), name); + return new TypeParam(new Scope.NativeType(nativeType), name); } public static TypeParam forStructType(SimpleStructType structType, String name) { -- cgit v1.2.3