aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-03-03 09:34:44 +0000
committerMichael Williamson <mike@zwobble.org>2024-03-03 09:34:44 +0000
commitec7c801a8dbad307b76b0a18f819da3ea06bb16e (patch)
treeac3643832d6622ccf430b97e2928d416d958c802 /src/main/java
parent925916777a52ffa2f0cf94c761b3a4616fe17019 (diff)
Support calling functions with explicit type-level args
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java56
-rw-r--r--src/main/java/org/shedlang/compiler/types/FunctionType.java2
2 files changed, 50 insertions, 8 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 223323d3..c51758bb 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -376,23 +376,39 @@ public class TypeChecker {
var contextForReceiver = context;
var receiverType = untyped.typeLevelArgs()
.map(untypedTypeLevelArgNodes -> {
- var typeLevelArgs = untypedTypeLevelArgNodes.stream()
- .map(argNode -> typeCheckTypeExpression(argNode, contextForReceiver).value())
- .toList();
+ Type specificReceiverType;
if (
typedReceiver.type() instanceof TypeLevelValueType initialReceiverType &&
initialReceiverType.value() instanceof TypeConstructor<?> typeConstructor
) {
- // TODO: check args
- return typeCheckCallReceiverType(
- Types.metaType(Types.constructedType(typeConstructor, typeLevelArgs)),
- typedReceiver.source(),
+ var typeLevelArgs = typeCheckTypeLevelArgs(
+ untypedTypeLevelArgNodes,
+ typeConstructor.params(),
+ contextForReceiver
+ );
+ specificReceiverType = Types.metaType(
+ Types.constructedType(typeConstructor, typeLevelArgs)
+ );
+ } else if (
+ typedReceiver.type() instanceof FunctionType initialReceiverType &&
+ initialReceiverType.typeLevelParams().isPresent()
+ ) {
+ var typeLevelArgs = typeCheckTypeLevelArgs(
+ untypedTypeLevelArgNodes,
+ initialReceiverType.typeLevelParams().get(),
contextForReceiver
);
+ specificReceiverType = initialReceiverType.applyTypeLevelArgs(typeLevelArgs);
} else {
throw new IllegalArgumentException("TODO");
}
+
+ return typeCheckCallReceiverType(
+ specificReceiverType,
+ typedReceiver.source(),
+ contextForReceiver
+ );
})
.orElseGet(() -> typeCheckCallReceiverType(typedReceiver, contextForReceiver));
@@ -1864,6 +1880,32 @@ public class TypeChecker {
return new TypedTupleTypeNode(tupleType, untyped.source());
}
+ private static ArrayList<TypeLevelValue> typeCheckTypeLevelArgs(
+ List<UntypedTypeLevelExpressionNode> untyped,
+ List<TypeLevelParam> typeLevelParams,
+ TypeCheckerContext context
+ ) {
+ var typeLevelArgs = new ArrayList<TypeLevelValue>();
+
+ // TODO: check length
+ // TODO: check arg is appropriate for param
+
+ for (var paramIndex = 0; paramIndex < typeLevelParams.size(); paramIndex++) {
+ var typeLevelParam = typeLevelParams.get(paramIndex);
+ var argNode = untyped.get(paramIndex);
+
+ var typeLevelArg = switch (typeLevelParam) {
+ case EffectParam effectParam ->
+ typeCheckEffect(argNode, context).value();
+ case TypeParam typeParam ->
+ typeCheckTypeExpression(argNode, context).value();
+ };
+ typeLevelArgs.add(typeLevelArg);
+ }
+
+ return typeLevelArgs;
+ }
+
private static TypedTypeLevelExpressionNode<TypeLevelValue> typeCheckTypeLevelReference(
UntypedTypeLevelReferenceNode untyped,
TypeCheckerContext context
diff --git a/src/main/java/org/shedlang/compiler/types/FunctionType.java b/src/main/java/org/shedlang/compiler/types/FunctionType.java
index 14a885f7..9c992e55 100644
--- a/src/main/java/org/shedlang/compiler/types/FunctionType.java
+++ b/src/main/java/org/shedlang/compiler/types/FunctionType.java
@@ -78,7 +78,7 @@ public record FunctionType(
);
}
- public FunctionType applyTypeLevelArgs(List<TypeLevelArg> typeArgs) {
+ public FunctionType applyTypeLevelArgs(List<? extends TypeLevelValue> typeArgs) {
var typeSubstitutionMap = TypeSubstitutionMap.from(
this.typeLevelParams.orElseThrow(),
typeArgs