aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-28 12:35:20 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-28 12:37:36 +0100
commitdd30830b4c24e046d1e35968bbe101748894f897 (patch)
treeb8ad8d3dce6eebac2b4bd1ff094ac1c0830a8e49 /src/main/java
parentb964e7195924ce411471d680c0c4e521abbc690a (diff)
Support calling struct types
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedArgsNode.java7
-rw-r--r--src/main/java/org/shedlang/compiler/ast/untyped/UntypedCallNode.java8
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java35
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java7
4 files changed, 48 insertions, 9 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedArgsNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedArgsNode.java
index fb3df52e..202cb888 100644
--- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedArgsNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedArgsNode.java
@@ -26,5 +26,12 @@ public record UntypedArgsNode(
public UntypedArgsNode build() {
return new UntypedArgsNode(positional, named, Sources.NULL);
}
+
+ public Builder addNamedArg(UntypedNamedArgNode arg) {
+ return new Builder(
+ this.positional,
+ this.named.plus(arg)
+ );
+ }
}
}
diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedCallNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedCallNode.java
index f9fe01a4..c5b2c241 100644
--- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedCallNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedCallNode.java
@@ -34,6 +34,14 @@ public record UntypedCallNode(
);
}
+ public Builder addNamedArg(UntypedNamedArgNode arg) {
+ return new Builder(
+ this.receiver,
+ this.args.addNamedArg(arg),
+ this.hasEffects
+ );
+ }
+
public Builder withHasEffects(boolean hasEffects) {
return new Builder(
this.receiver,
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 9cd5e616..4644f695 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -276,7 +276,7 @@ public class TypeChecker {
var typedReceiver = receiverResult.value();
context = receiverResult.context();
- var receiverType = receiverTypeToFunctionType(typedReceiver);
+ var receiverType = receiverTypeToFunctionType(typedReceiver, context);
var argsResult = typeCheckArgs(untyped.args(), context, receiverType);
var typedArgs = argsResult.value();
@@ -309,11 +309,37 @@ public class TypeChecker {
));
}
- private static FunctionType receiverTypeToFunctionType(TypedExpressionNode typedReceiver) {
+ private static FunctionType receiverTypeToFunctionType(
+ TypedExpressionNode typedReceiver,
+ TypeCheckerContext context
+ ) {
if (typedReceiver.type() instanceof FunctionType receiverType) {
return receiverType;
}
+ if (
+ typedReceiver.type() instanceof TypeLevelValueType typeLevelValueType &&
+ typeLevelValueType.value() instanceof StructType structType
+ ) {
+ var structTypeInfo = context.structTypeInfo(structType, typedReceiver.source());
+
+ var namedParams = structTypeInfo.fields().entrySet().stream()
+ .map(field -> {
+ var name = field.getKey();
+ var type = field.getValue();
+
+ return new NamedParam(name, type);
+ })
+ .toList();
+
+ return new FunctionType(
+ List.of(),
+ namedParams,
+ Effects.NONE,
+ structType
+ );
+ }
+
throw new UnexpectedTypeError(
TypeSets.FUNCTION,
typedReceiver.type(),
@@ -408,10 +434,7 @@ public class TypeChecker {
throw new NoSuchFieldError(typedReceiver.type(), untyped.fieldName(), untyped.source());
}
- var structTypeInfo = context.structTypeInfo(
- receiverType,
- untyped.fieldName()
- ).orElseThrow(() -> new MissingStructTypeInfoError(receiverType, untyped.source()));
+ var structTypeInfo = context.structTypeInfo(receiverType, untyped.source());
var fieldType = structTypeInfo.fieldType(untyped.fieldName())
.orElseThrow(() -> new NoSuchFieldError(receiverType, untyped.fieldName(), untyped.source()));
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
index 18b030f8..5026dee6 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
@@ -6,6 +6,7 @@ import org.pcollections.PStack;
import org.shedlang.compiler.ast.typed.FreeVariables;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.typechecker.errors.CannotDefineVariableDeclaredInOuterScopeError;
+import org.shedlang.compiler.typechecker.errors.MissingStructTypeInfoError;
import org.shedlang.compiler.typechecker.errors.UnknownVariableError;
import org.shedlang.compiler.typechecker.errors.VariableIsAlreadyDefinedError;
import org.shedlang.compiler.types.*;
@@ -361,11 +362,11 @@ public class TypeCheckerContext {
);
}
- public Optional<StructTypeInfo> structTypeInfo(StructType type, String fieldName) {
- return Optional.ofNullable(this.structTypeInfo.get(type));
+ public StructTypeInfo structTypeInfo(StructType type, Source source) {
+ return Optional.ofNullable(this.structTypeInfo.get(type))
+ .orElseThrow(() -> new MissingStructTypeInfoError(type, source));
}
-
public PMap<StructType, StructTypeInfo> structTypeInfo() {
return structTypeInfo;
}