From dd30830b4c24e046d1e35968bbe101748894f897 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 28 Sep 2023 12:35:20 +0100 Subject: Support calling struct types --- .../compiler/ast/untyped/UntypedArgsNode.java | 7 +++++ .../compiler/ast/untyped/UntypedCallNode.java | 8 +++++ .../shedlang/compiler/typechecker/TypeChecker.java | 35 ++++++++++++++++++---- .../compiler/typechecker/TypeCheckerContext.java | 7 +++-- 4 files changed, 48 insertions(+), 9 deletions(-) (limited to 'src/main/java') 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(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 structTypeInfo() { return structTypeInfo; } -- cgit v1.2.3