From 98f33d0f843c88c404b525134986393a1b1569cb Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 3 Jan 2024 22:07:36 +0000 Subject: Introduce base types for struct types and sum types respectively --- .../ast/typed/TypedStructDefinitionNode.java | 8 +-- .../ast/typed/TypedSumTypeDefinitionNode.java | 4 +- .../compiler/ast/typed/TypedWhenCaseNode.java | 4 +- .../org/shedlang/compiler/shid/ShidCodeGen.java | 2 +- .../org/shedlang/compiler/shid/ShidSerializer.java | 4 +- .../shid/instructions/ShidDefineStruct.java | 4 +- .../compiler/shid/instructions/ShidFieldLoad.java | 4 +- .../compiler/shid/instructions/ShidSwitch.java | 4 +- .../compiler/shidtopatio/ShidToPatioContext.java | 14 +++--- .../compiler/shidtopatio/ShidToPatioStructs.java | 8 +-- .../shedlang/compiler/typechecker/TypeChecker.java | 51 +++++++------------ .../compiler/typechecker/TypeCheckerContext.java | 14 +----- .../compiler/typechecker/TypeCheckerSubTyping.java | 9 +--- .../shedlang/compiler/typechecker/TypeInfos.java | 57 +++++++++++++--------- .../typechecker/errors/UnhandledVariantError.java | 8 +-- .../typesets/TypeSetStructMetaType.java | 8 +-- .../compiler/types/ConstructedStructType.java | 8 ++- .../compiler/types/ConstructedSumType.java | 4 +- .../shedlang/compiler/types/ConstructibleType.java | 2 +- .../java/org/shedlang/compiler/types/Scope.java | 4 +- .../shedlang/compiler/types/SimpleStructType.java | 16 ++++++ .../org/shedlang/compiler/types/SimpleSumType.java | 11 +++++ .../org/shedlang/compiler/types/StructType.java | 10 +--- .../java/org/shedlang/compiler/types/SumType.java | 9 +--- .../org/shedlang/compiler/types/SumTypeInfo.java | 2 +- .../org/shedlang/compiler/types/SumVariant.java | 40 --------------- .../java/org/shedlang/compiler/types/Type.java | 2 +- .../org/shedlang/compiler/types/TypeParam.java | 4 +- .../shedlang/compiler/types/TypeSubstitution.java | 23 +++++++-- .../java/org/shedlang/compiler/types/Types.java | 20 ++++---- 30 files changed, 163 insertions(+), 195 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/types/SimpleStructType.java create mode 100644 src/main/java/org/shedlang/compiler/types/SimpleSumType.java delete mode 100644 src/main/java/org/shedlang/compiler/types/SumVariant.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java index bec48751..d87348a8 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedStructDefinitionNode.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.ast.typed; import org.pcollections.PVector; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.types.TypeOrConstructor; import org.shedlang.compiler.types.Types; @@ -12,7 +12,7 @@ import org.shedlang.compiler.util.P; import java.util.List; public record TypedStructDefinitionNode( - TypeOrConstructor typeOrConstructor, + TypeOrConstructor typeOrConstructor, List fields, Source source ) implements TypedNamespaceStatementNode { @@ -25,7 +25,7 @@ public record TypedStructDefinitionNode( } public record Builder( - TypeOrConstructor type, + TypeOrConstructor type, PVector fields ) { public TypedStructDefinitionNode build() { @@ -36,7 +36,7 @@ public record TypedStructDefinitionNode( ); } - public Builder withType(StructType type) { + public Builder withType(SimpleStructType type) { return new Builder( TypeOrConstructor.type(type), this.fields diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java index 109a7ace..b0a0e5d3 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java @@ -1,11 +1,11 @@ package org.shedlang.compiler.ast.typed; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.SumType; +import org.shedlang.compiler.types.SimpleSumType; import org.shedlang.compiler.types.TypeOrConstructor; public record TypedSumTypeDefinitionNode( - TypeOrConstructor typeOrConstructor, + TypeOrConstructor typeOrConstructor, Source source ) implements TypedNamespaceStatementNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedWhenCaseNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedWhenCaseNode.java index c9bb30f9..33506b30 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedWhenCaseNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedWhenCaseNode.java @@ -1,10 +1,10 @@ package org.shedlang.compiler.ast.typed; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.SumVariant; +import org.shedlang.compiler.types.StructType; public record TypedWhenCaseNode( - SumVariant caseType, + StructType caseType, TypedBlockNode body, Source source ) implements TypedNode { diff --git a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java index 1ab14ddd..16c1c3de 100644 --- a/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java +++ b/src/main/java/org/shedlang/compiler/shid/ShidCodeGen.java @@ -209,7 +209,7 @@ public class ShidCodeGen { case NamespaceType namespaceType -> new ShidFieldLoad.Receiver.Namespace(namespaceType.namespaceName()); - case StructType structType -> + case SimpleStructType structType -> new ShidFieldLoad.Receiver.Struct(structType); case TypeLevelValueType typeLevelValueType -> { diff --git a/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java b/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java index 09501abe..1e36885e 100644 --- a/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java +++ b/src/main/java/org/shedlang/compiler/shid/ShidSerializer.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.shid; import org.shedlang.compiler.shid.instructions.*; import org.shedlang.compiler.treetext.Tree; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; import org.shedlang.compiler.types.UserDefinedEffect; import java.util.List; @@ -312,7 +312,7 @@ public class ShidSerializer { return treeString(effect.describe()); } - private static Tree structTypeToTree(StructType type) { + private static Tree structTypeToTree(SimpleStructType type) { return treeString(type.describe()); } } diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java index 4400eb92..b52c9e74 100644 --- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidDefineStruct.java @@ -1,7 +1,7 @@ package org.shedlang.compiler.shid.instructions; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; import java.util.List; @@ -10,7 +10,7 @@ import java.util.List; * definition. */ public record ShidDefineStruct( - StructType type, + SimpleStructType type, // TODO: remove fields? We should have fields from the type info. List fields, Source source diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java index 4337dee1..9de2a4be 100644 --- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidFieldLoad.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.shid.instructions; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.types.NamespaceName; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; import org.shedlang.compiler.types.UserDefinedEffect; /** @@ -17,7 +17,7 @@ public record ShidFieldLoad( public sealed interface Receiver { record Effect(UserDefinedEffect effect) implements Receiver {} record Namespace(NamespaceName name) implements Receiver {} - record Struct(StructType type) implements Receiver {} + record Struct(SimpleStructType type) implements Receiver {} } @Override diff --git a/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java b/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java index 1f69dfea..2f4a0b24 100644 --- a/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java +++ b/src/main/java/org/shedlang/compiler/shid/instructions/ShidSwitch.java @@ -1,7 +1,7 @@ package org.shedlang.compiler.shid.instructions; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; import java.util.List; @@ -16,7 +16,7 @@ public record ShidSwitch( List cases, Source source ) implements ShidInstruction { - public record Case(StructType caseType, ShidBlock body, Source source) { + public record Case(SimpleStructType caseType, ShidBlock body, Source source) { } @Override diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java index dc338c83..8ca486ae 100644 --- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java +++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioContext.java @@ -32,7 +32,7 @@ public record ShidToPatioContext( ) { public record GlobalContext( TypeInfos typeInfos, - PMap structTags, + PMap structTags, PMap effectTags ) { public static final GlobalContext EMPTY = forTypeInfos(TypeInfos.EMPTY); @@ -50,8 +50,8 @@ public record ShidToPatioContext( } @CheckReturnValue - private static PMap generateStructTags(TypeInfos typeInfos) { - var tags = P.map(); + private static PMap generateStructTags(TypeInfos typeInfos) { + var tags = P.map(); var nextTag = 0; for (var structType : typeInfos.structTypes()) { tags = tags.plus(structType, nextTag); @@ -79,14 +79,14 @@ public record ShidToPatioContext( } @CheckReturnValue - public StructTypeInfo structTypeInfo(StructType type) { + public StructTypeInfo structTypeInfo(SimpleStructType type) { return typeInfos.structTypeInfo(type) // TODO: throw better error .orElseThrow(() -> new RuntimeException("No type info for: " + type)); } @CheckReturnValue - public int structTag(StructType type) { + public int structTag(SimpleStructType type) { var tag = this.structTags.get(type); if (tag == null) { // TODO: throw better error @@ -487,12 +487,12 @@ public record ShidToPatioContext( } @CheckReturnValue - public StructTypeInfo structTypeInfo(StructType type) { + public StructTypeInfo structTypeInfo(SimpleStructType type) { return this.globalContext.structTypeInfo(type); } @CheckReturnValue - public int structTag(StructType type) { + public int structTag(SimpleStructType type) { return globalContext.structTag(type); } diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioStructs.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioStructs.java index 0f18b9e9..f7e8bdfe 100644 --- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioStructs.java +++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioStructs.java @@ -11,7 +11,7 @@ import org.shedlang.compiler.patio.types.PatioTypes; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.shid.instructions.ShidDefineFunction; import org.shedlang.compiler.shid.instructions.ShidDefineStruct; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; import org.shedlang.compiler.util.Lists; import java.util.List; @@ -22,7 +22,7 @@ public class ShidToPatioStructs { public static ShidToPatioContext createType( PatioLocalRef target, - StructType type, + SimpleStructType type, List fields, Source source, ShidToPatioContext context @@ -101,7 +101,7 @@ public class ShidToPatioStructs { public static ShidToPatioContext fieldLoad( PatioLocalRef target, PatioOperand receiver, - StructType type, + SimpleStructType type, String fieldName, Source source, ShidToPatioContext context @@ -174,7 +174,7 @@ public class ShidToPatioStructs { } private static PatioDataLayout structDataLayout( - StructType type, + SimpleStructType type, ShidToPatioContext context ) { var structTypeInfo = context.structTypeInfo(type); diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index 37fd18b3..1aefd526 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -433,24 +433,13 @@ public class TypeChecker { ); } - if ( - receiverType instanceof TypeLevelValueType typeLevelValueType && - typeLevelValueType.value() instanceof ConstructedStructType constructedType - ) { - var structTypeInfo = context.structTypeInfo(constructedType, receiverSource); - return receiverStructTypeInfoToFunctionType( - constructedType, - structTypeInfo - ); - } - if ( receiverType instanceof TypeLevelValueType typeLevelValueType && typeLevelValueType.value() instanceof TypeConstructor typeConstructor && - typeConstructor.genericType() instanceof StructType structType + typeConstructor.genericType() instanceof SimpleStructType structType ) { var structTypeInfo = context.structTypeInfo( - (StructType) typeConstructor.genericType(), + structType, receiverSource ); var constructedType = Types.constructedType( @@ -692,7 +681,7 @@ public class TypeChecker { )); } - case StructType receiverTypeStruct -> { + case SimpleStructType receiverTypeStruct -> { var structTypeInfo = context.structTypeInfo(receiverTypeStruct, source); return structTypeInfo.fieldType(fieldName); } @@ -1536,7 +1525,7 @@ public class TypeChecker { var namespaceName = context.namespaceName() .orElseThrow(() -> new CannotDefineStructOutsideOfNamespaceError(untyped.source())); - var type = new StructType(namespaceName, untyped.name()); + var type = new SimpleStructType(namespaceName, untyped.name()); var typeOrConstructor = createTypeOrConstructor( untyped.typeLevelParams(), @@ -1555,7 +1544,7 @@ public class TypeChecker { @Override public TypeCheckerContext defineTypes(TypeCheckerContext context) { - var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( + var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( TypeOrConstructor.class, untyped.name() ); @@ -1613,7 +1602,7 @@ public class TypeChecker { var namespaceName = context.namespaceName() .orElseThrow(() -> new CannotDefineSumTypeOutsideOfNamespaceError(untyped.source())); - var type = new SumType(namespaceName, untyped.name()); + var type = new SimpleSumType(namespaceName, untyped.name()); var typeOrConstructor = createTypeOrConstructor( untyped.typeLevelParams(), @@ -1632,7 +1621,7 @@ public class TypeChecker { @Override public TypeCheckerContext defineTypes(TypeCheckerContext context) { - var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( + var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( TypeOrConstructor.class, untyped.name() ); @@ -1648,8 +1637,7 @@ public class TypeChecker { return context.addSumTypeInfo(typeOrConstructor.toType(), new SumTypeInfo(variants)); } - private OrderedPSet typeCheckVariants(TypeCheckerContext context) { - // TODO: restrict variants to structs. Do we allow other sum types? + private OrderedPSet typeCheckVariants(TypeCheckerContext context) { // TODO: prevent constructed types with same underlying type from appearing multiple times // (e.g. Option[String], Option[Int]) @@ -1661,9 +1649,7 @@ public class TypeChecker { ).value(); if (variantType instanceof StructType variantStructType) { - return SumVariant.struct(variantStructType); - } else if (variantType instanceof ConstructedStructType variantConstructedType) { - return SumVariant.constructedStruct(variantConstructedType); + return variantStructType; } else { throw new VariantTypeIsNotStructError( variantType, @@ -1676,7 +1662,7 @@ public class TypeChecker { @Override public TypeCheckerResult finish(TypeCheckerContext context) { - var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( + var typeOrConstructor = (TypeOrConstructor) context.getLexicalState( TypeOrConstructor.class, untyped.name() ); @@ -2098,7 +2084,7 @@ public class TypeChecker { case ConstructedSumType constructedType -> context.sumTypeInfo(constructedType, untyped.source()); - case SumType expressionType -> + case SimpleSumType expressionType -> context.sumTypeInfo(expressionType, untyped.source()); default -> @@ -2129,16 +2115,16 @@ public class TypeChecker { for (var typedCase : typedCases) { var caseType = typedCase.caseType(); if (!variantTypes.contains(caseType)) { - throw new UnreachableWhenCaseError(caseType.type(), typedCase.source()); + throw new UnreachableWhenCaseError(caseType, typedCase.source()); } - if (handledVariantTypes.contains(caseType.type())) { - throw new DuplicateWhenCaseError(caseType.type(), typedCase.source()); + if (handledVariantTypes.contains(caseType)) { + throw new DuplicateWhenCaseError(caseType, typedCase.source()); } - handledVariantTypes.add(caseType.type()); + handledVariantTypes.add(caseType); } for (var variantType : variantTypes) { - if (!handledVariantTypes.contains(variantType.type())) { + if (!handledVariantTypes.contains(variantType)) { throw new UnhandledVariantError(variantType, untyped.source()); } } @@ -2169,11 +2155,8 @@ public class TypeChecker { ); var variant = switch (typedCaseType.value()) { - case ConstructedStructType constructedStructType -> - SumVariant.constructedStruct(constructedStructType); - case StructType structType -> - SumVariant.struct(structType); + structType; default -> throw new UnexpectedTypeError( diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java index 78bf4638..557b05d7 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java @@ -434,7 +434,7 @@ public class TypeCheckerContext { } public TypeCheckerContext addStructTypeInfo( - StructType structType, + SimpleStructType structType, StructTypeInfo structTypeInfo ) { return new TypeCheckerContext( @@ -443,18 +443,13 @@ public class TypeCheckerContext { ); } - public StructTypeInfo structTypeInfo(ConstructedType type, Source source) { - return this.typeInfos.structTypeInfo(type) - .orElseThrow(() -> new MissingStructTypeInfoError(type.genericType(), source)); - } - public StructTypeInfo structTypeInfo(StructType type, Source source) { return this.typeInfos.structTypeInfo(type) .orElseThrow(() -> new MissingStructTypeInfoError(type, source)); } public TypeCheckerContext addSumTypeInfo( - SumType sumType, + SimpleSumType sumType, SumTypeInfo sumTypeInfo ) { return new TypeCheckerContext( @@ -468,11 +463,6 @@ public class TypeCheckerContext { .orElseThrow(() -> new MissingSumTypeInfoError(type, source)); } - public SumTypeInfo sumTypeInfo(ConstructedType type, Source source) { - return this.typeInfos.sumTypeInfo(type) - .orElseThrow(() -> new MissingSumTypeInfoError(type.genericType(), source)); - } - public TypeCheckerContext addUserDefinedEffectInfo( UserDefinedEffect effect, UserDefinedEffectInfo effectInfo diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java index 1ffd9ee2..4ee16c4d 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java @@ -125,13 +125,6 @@ public class TypeCheckerSubTyping { return tryAddVariantSubtypeConstraint(subtype, superTypeInfo, constraints); } - if (supertype instanceof ConstructedSumType supertypeConstructedType) { - var superTypeInfo = constraints.typeInfos - .sumTypeInfo(supertypeConstructedType) - .orElseThrow(); - return tryAddVariantSubtypeConstraint(subtype, superTypeInfo, constraints); - } - if ( supertype instanceof FunctionType supertypeFunction && subtype instanceof FunctionType subtypeFunction @@ -206,7 +199,7 @@ public class TypeCheckerSubTyping { Constraints constraints ) { for (var supertypeVariant : superTypeInfo.variants()) { - var result = tryAddSubtypeConstraint(subtype, supertypeVariant.type(), constraints); + var result = tryAddSubtypeConstraint(subtype, supertypeVariant, constraints); // TODO: is it possible for multiple variants to match? If so, do we need to handle that? if (result.isPresent()) { return result; diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java b/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java index 1e00a354..7812614f 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java @@ -14,14 +14,14 @@ public class TypeInfos { public static final TypeInfos EMPTY = new TypeInfos(Empty.map(), P.orderedPMap(), Empty.map(), Empty.map()); private final PMap namespaceTypeInfos; - private final OrderedPMap structTypeInfos; - private final PMap sumTypeInfos; + private final OrderedPMap structTypeInfos; + private final PMap sumTypeInfos; private final PMap userDefinedEffectInfos; public TypeInfos( PMap namespaceTypeInfos, - OrderedPMap structTypeInfos, - PMap sumTypeInfos, + OrderedPMap structTypeInfos, + PMap sumTypeInfos, PMap userDefinedEffectInfos ) { this.namespaceTypeInfos = namespaceTypeInfos; @@ -47,7 +47,7 @@ public class TypeInfos { } public TypeInfos addStructTypeInfo( - StructType type, + SimpleStructType type, StructTypeInfo structTypeInfo ) { return new TypeInfos( @@ -59,10 +59,20 @@ public class TypeInfos { } public Optional structTypeInfo(StructType type) { + return switch (type) { + case ConstructedStructType constructedStructType -> + constructedStructTypeInfo(constructedStructType); + + case SimpleStructType simpleStructType -> + simpleStructTypeInfo(simpleStructType); + }; + } + + private Optional simpleStructTypeInfo(SimpleStructType type) { return Optional.ofNullable(structTypeInfos.get(type)); } - public Optional structTypeInfo(ConstructedType type) { + private Optional constructedStructTypeInfo(ConstructedType type) { return structTypeInfo(type.genericType()).map(typeInfo -> { var typeSubstitutionMap = type.typeSubstitutionMap(); @@ -79,11 +89,11 @@ public class TypeInfos { }); } - public Set structTypes() { + public Set structTypes() { return structTypeInfos.keySet(); } - public TypeInfos addSumTypeInfo(SumType sumType, SumTypeInfo sumTypeInfo) { + public TypeInfos addSumTypeInfo(SimpleSumType sumType, SumTypeInfo sumTypeInfo) { return new TypeInfos( this.namespaceTypeInfos, this.structTypeInfos, @@ -93,27 +103,28 @@ public class TypeInfos { } public Optional sumTypeInfo(SumType type) { + return switch (type) { + case ConstructedSumType constructedSumType -> + constructedSumTypeInfo(constructedSumType); + + case SimpleSumType simpleSumType -> + simpleSumTypeInfo(simpleSumType); + }; + } + + private Optional simpleSumTypeInfo(SimpleSumType type) { return Optional.ofNullable(sumTypeInfos.get(type)); } - public Optional sumTypeInfo(ConstructedType type) { - return sumTypeInfo(type.genericType()).map(typeInfo -> { + private Optional constructedSumTypeInfo(ConstructedType type) { + return simpleSumTypeInfo(type.genericType()).map(typeInfo -> { var typeSubstitutionMap = type.typeSubstitutionMap(); var variants = typeInfo.variants().stream() - .map(variant -> switch (variant) { - case SumVariant.ConstructedStruct constructedStruct -> - SumVariant.constructedStruct(TypeSubstitution.substituteConstructedStructType( - constructedStruct.type(), - typeSubstitutionMap - )); - - case SumVariant.Struct struct -> - SumVariant.struct(TypeSubstitution.substituteStructType( - struct.type(), - typeSubstitutionMap - )); - }) + .map(variant -> TypeSubstitution.substituteStructType( + variant, + typeSubstitutionMap + )) .collect(PCollectors.toOrderedSet()); return new SumTypeInfo(variants); diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/UnhandledVariantError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/UnhandledVariantError.java index 377573b6..7a7ff1e3 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/errors/UnhandledVariantError.java +++ b/src/main/java/org/shedlang/compiler/typechecker/errors/UnhandledVariantError.java @@ -2,17 +2,17 @@ package org.shedlang.compiler.typechecker.errors; import org.shedlang.compiler.errors.SourceError; import org.shedlang.compiler.sources.Source; -import org.shedlang.compiler.types.SumVariant; +import org.shedlang.compiler.types.StructType; public class UnhandledVariantError extends SourceError { - private final SumVariant unhandledVariant; + private final StructType unhandledVariant; - public UnhandledVariantError(SumVariant unhandledVariant, Source source) { + public UnhandledVariantError(StructType unhandledVariant, Source source) { super("The variant " + unhandledVariant.describe() + " is unhandled", source); this.unhandledVariant = unhandledVariant; } - public SumVariant unhandledVariant() { + public StructType unhandledVariant() { return unhandledVariant; } } diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetStructMetaType.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetStructMetaType.java index b6db14cc..c5641dcf 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetStructMetaType.java +++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetStructMetaType.java @@ -1,8 +1,8 @@ package org.shedlang.compiler.typechecker.typesets; -import org.shedlang.compiler.types.StructType; +import org.shedlang.compiler.types.SimpleStructType; -public final class TypeSetStructMetaType implements TypeSetTypeLevelValue { +public final class TypeSetStructMetaType implements TypeSetTypeLevelValue { private TypeSetStructMetaType() { } @@ -14,7 +14,7 @@ public final class TypeSetStructMetaType implements TypeSetTypeLevelValue valueClass() { - return StructType.class; + public Class valueClass() { + return SimpleStructType.class; } } diff --git a/src/main/java/org/shedlang/compiler/types/ConstructedStructType.java b/src/main/java/org/shedlang/compiler/types/ConstructedStructType.java index df454e5d..d0906f94 100644 --- a/src/main/java/org/shedlang/compiler/types/ConstructedStructType.java +++ b/src/main/java/org/shedlang/compiler/types/ConstructedStructType.java @@ -3,7 +3,11 @@ package org.shedlang.compiler.types; import java.util.List; public record ConstructedStructType( - TypeConstructor constructor, + TypeConstructor constructor, List args -) implements ConstructedType { +) implements ConstructedType, StructType { + @Override + public SimpleStructType rawType() { + return genericType(); + } } diff --git a/src/main/java/org/shedlang/compiler/types/ConstructedSumType.java b/src/main/java/org/shedlang/compiler/types/ConstructedSumType.java index ee3c6f80..b001e43b 100644 --- a/src/main/java/org/shedlang/compiler/types/ConstructedSumType.java +++ b/src/main/java/org/shedlang/compiler/types/ConstructedSumType.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.types; import java.util.List; public record ConstructedSumType( - TypeConstructor constructor, + TypeConstructor constructor, List args -) implements ConstructedType { +) implements ConstructedType, SumType { } diff --git a/src/main/java/org/shedlang/compiler/types/ConstructibleType.java b/src/main/java/org/shedlang/compiler/types/ConstructibleType.java index 28cc62a0..164b2b8d 100644 --- a/src/main/java/org/shedlang/compiler/types/ConstructibleType.java +++ b/src/main/java/org/shedlang/compiler/types/ConstructibleType.java @@ -1,5 +1,5 @@ package org.shedlang.compiler.types; -public sealed interface ConstructibleType extends Type permits StructType, SumType { +public sealed interface ConstructibleType extends Type permits SimpleStructType, SimpleSumType { String name(); } diff --git a/src/main/java/org/shedlang/compiler/types/Scope.java b/src/main/java/org/shedlang/compiler/types/Scope.java index ed8e8c5a..170a47f2 100644 --- a/src/main/java/org/shedlang/compiler/types/Scope.java +++ b/src/main/java/org/shedlang/compiler/types/Scope.java @@ -1,6 +1,6 @@ package org.shedlang.compiler.types; public sealed interface Scope { - record Struct(StructType type) implements Scope {} - record Sum(SumType 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/SimpleStructType.java b/src/main/java/org/shedlang/compiler/types/SimpleStructType.java new file mode 100644 index 00000000..a43afb80 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/types/SimpleStructType.java @@ -0,0 +1,16 @@ +package org.shedlang.compiler.types; + +/** + * A set of named fields. + */ +public record SimpleStructType(NamespaceName namespaceName, String name) implements ConstructibleType, StructType { + @Override + public String describe() { + return namespaceName.toString() + "." + name; + } + + @Override + public SimpleStructType rawType() { + return this; + } +} diff --git a/src/main/java/org/shedlang/compiler/types/SimpleSumType.java b/src/main/java/org/shedlang/compiler/types/SimpleSumType.java new file mode 100644 index 00000000..7a978d40 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/types/SimpleSumType.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.types; + +/** + * A discriminated union of several different types. + */ +public record SimpleSumType(NamespaceName namespaceName, String name) implements ConstructibleType, SumType { + @Override + public String describe() { + return namespaceName.toString() + "." + name; + } +} diff --git a/src/main/java/org/shedlang/compiler/types/StructType.java b/src/main/java/org/shedlang/compiler/types/StructType.java index fbde821f..d18ced3f 100644 --- a/src/main/java/org/shedlang/compiler/types/StructType.java +++ b/src/main/java/org/shedlang/compiler/types/StructType.java @@ -1,11 +1,5 @@ package org.shedlang.compiler.types; -/** - * A set of named fields. - */ -public record StructType(NamespaceName namespaceName, String name) implements ConstructibleType { - @Override - public String describe() { - return namespaceName.toString() + "." + name; - } +public sealed interface StructType extends Type permits ConstructedStructType, SimpleStructType { + SimpleStructType rawType(); } diff --git a/src/main/java/org/shedlang/compiler/types/SumType.java b/src/main/java/org/shedlang/compiler/types/SumType.java index 675135c8..81f37b8c 100644 --- a/src/main/java/org/shedlang/compiler/types/SumType.java +++ b/src/main/java/org/shedlang/compiler/types/SumType.java @@ -1,11 +1,4 @@ package org.shedlang.compiler.types; -/** - * A discriminated union of several different types. - */ -public record SumType(NamespaceName namespaceName, String name) implements ConstructibleType { - @Override - public String describe() { - return namespaceName.toString() + "." + name; - } +public sealed interface SumType extends Type permits ConstructedSumType, SimpleSumType { } diff --git a/src/main/java/org/shedlang/compiler/types/SumTypeInfo.java b/src/main/java/org/shedlang/compiler/types/SumTypeInfo.java index 7dd359e3..a9027512 100644 --- a/src/main/java/org/shedlang/compiler/types/SumTypeInfo.java +++ b/src/main/java/org/shedlang/compiler/types/SumTypeInfo.java @@ -2,5 +2,5 @@ package org.shedlang.compiler.types; import org.pcollections.OrderedPSet; -public record SumTypeInfo(OrderedPSet variants) { +public record SumTypeInfo(OrderedPSet variants) { } diff --git a/src/main/java/org/shedlang/compiler/types/SumVariant.java b/src/main/java/org/shedlang/compiler/types/SumVariant.java deleted file mode 100644 index 5c04d77b..00000000 --- a/src/main/java/org/shedlang/compiler/types/SumVariant.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.shedlang.compiler.types; - -public sealed interface SumVariant { - static SumVariant constructedStruct(ConstructedStructType type) { - return new ConstructedStruct(type); - } - - static SumVariant struct(StructType type) { - return new Struct(type); - } - - String describe(); - - Type type(); - StructType rawType(); - - record ConstructedStruct(ConstructedStructType type) implements SumVariant { - @Override - public String describe() { - return type.describe(); - } - - @Override - public StructType rawType() { - return type.genericType(); - } - } - - record Struct(StructType type) implements SumVariant { - @Override - public String describe() { - return type.describe(); - } - - @Override - public StructType rawType() { - return type; - } - } -} diff --git a/src/main/java/org/shedlang/compiler/types/Type.java b/src/main/java/org/shedlang/compiler/types/Type.java index cdb7ed0a..a2701446 100644 --- a/src/main/java/org/shedlang/compiler/types/Type.java +++ b/src/main/java/org/shedlang/compiler/types/Type.java @@ -6,5 +6,5 @@ package org.shedlang.compiler.types; * found through auxiliary data. */ public sealed interface Type extends TypeLevelValue - permits BoolType, BottomType, ConstructedType, ConstructibleType, FunctionType, IntType, NamespaceType, StringType, TopType, TupleType, TypeLevelValueType, TypeParam, UnitType { + permits BoolType, BottomType, ConstructedType, ConstructibleType, FunctionType, IntType, NamespaceType, StringType, StructType, SumType, TopType, TupleType, TypeLevelValueType, TypeParam, UnitType { } diff --git a/src/main/java/org/shedlang/compiler/types/TypeParam.java b/src/main/java/org/shedlang/compiler/types/TypeParam.java index 4788276a..4d0fd70d 100644 --- a/src/main/java/org/shedlang/compiler/types/TypeParam.java +++ b/src/main/java/org/shedlang/compiler/types/TypeParam.java @@ -1,11 +1,11 @@ package org.shedlang.compiler.types; public record TypeParam(Scope scope, String name) implements Type { - public static TypeParam forStructType(StructType structType, String name) { + public static TypeParam forStructType(SimpleStructType structType, String name) { return new TypeParam(new Scope.Struct(structType), name); } - public static TypeParam forSumType(SumType sumType, String name) { + public static TypeParam forSumType(SimpleSumType sumType, String name) { return new TypeParam(new Scope.Sum(sumType), name); } diff --git a/src/main/java/org/shedlang/compiler/types/TypeSubstitution.java b/src/main/java/org/shedlang/compiler/types/TypeSubstitution.java index 6a4bc45b..302fab7a 100644 --- a/src/main/java/org/shedlang/compiler/types/TypeSubstitution.java +++ b/src/main/java/org/shedlang/compiler/types/TypeSubstitution.java @@ -42,10 +42,10 @@ public class TypeSubstitution { case StringType stringType -> type; - case StructType structType -> - substituteStructType(structType, map); + case SimpleStructType structType -> + substituteSimpleStructType(structType, map); - case SumType sumType -> { + case SimpleSumType sumType -> { throw new UnsupportedOperationException("TODO"); } @@ -71,7 +71,7 @@ public class TypeSubstitution { }; } - public static ConstructedStructType substituteConstructedStructType( + private static ConstructedStructType substituteConstructedStructType( ConstructedStructType constructedType, TypeSubstitutionMap map ) { @@ -109,10 +109,23 @@ public class TypeSubstitution { ); } + private static SimpleStructType substituteSimpleStructType( + SimpleStructType type, + TypeSubstitutionMap map + ) { + return type; + } + public static StructType substituteStructType( StructType type, TypeSubstitutionMap map ) { - return type; + return switch (type) { + case ConstructedStructType constructedStructType -> + substituteConstructedStructType(constructedStructType, map); + + case SimpleStructType simpleStructType -> + substituteSimpleStructType(simpleStructType, map); + }; } } diff --git a/src/main/java/org/shedlang/compiler/types/Types.java b/src/main/java/org/shedlang/compiler/types/Types.java index 191f9481..9ab5c634 100644 --- a/src/main/java/org/shedlang/compiler/types/Types.java +++ b/src/main/java/org/shedlang/compiler/types/Types.java @@ -18,12 +18,12 @@ public class Types { return new NamespaceType(namespaceName); } - public static StructType struct(NamespaceName namespaceName, String name) { - return new StructType(namespaceName, name); + public static SimpleStructType struct(NamespaceName namespaceName, String name) { + return new SimpleStructType(namespaceName, name); } - public static SumType sum(NamespaceName namespaceName, String name) { - return new SumType(namespaceName, name); + public static SimpleSumType sum(NamespaceName namespaceName, String name) { + return new SimpleSumType(namespaceName, name); } public static TupleType tuple(List elements) { @@ -55,22 +55,22 @@ public class Types { List args ) { return switch (constructor.genericType()) { - case StructType structType -> - constructedStructType((TypeConstructor) constructor, args); - case SumType sumType -> - constructedSumType((TypeConstructor) constructor, args); + case SimpleStructType structType -> + constructedStructType((TypeConstructor) constructor, args); + case SimpleSumType sumType -> + constructedSumType((TypeConstructor) constructor, args); }; } public static ConstructedStructType constructedStructType( - TypeConstructor constructor, + TypeConstructor constructor, List args ) { return new ConstructedStructType(constructor, args); } public static ConstructedSumType constructedSumType( - TypeConstructor constructor, + TypeConstructor constructor, List args ) { return new ConstructedSumType(constructor, args); -- cgit v1.2.3