From 6d9a2f0b07204debf78f70e3d1ed5078ee4e54c0 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 28 Sep 2023 11:38:44 +0100 Subject: Basic type checking for field access --- .../shedlang/compiler/typechecker/TypeChecker.java | 27 ++++++++++++++++++++-- .../compiler/typechecker/TypeCheckerContext.java | 5 ++++ .../shedlang/compiler/types/StructTypeInfo.java | 5 ++++ src/main/java/org/shedlang/compiler/util/P.java | 9 ++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index 042fb614..f11b0e1e 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -361,8 +361,8 @@ public class TypeChecker { case UntypedCallNode untypedCall -> typeCheckCall(untypedCall, context); - case UntypedFieldAccessNode untypedFieldAccessNode -> - throw new UnsupportedOperationException("TODO"); + case UntypedFieldAccessNode untypedFieldAccess -> + typeCheckFieldAccess(untypedFieldAccess, context); case UntypedIfNode untypedIf -> typeCheckIf(untypedIf, context); @@ -393,6 +393,29 @@ public class TypeChecker { }); } + private static TypeCheckerResult typeCheckFieldAccess( + UntypedFieldAccessNode untyped, + TypeCheckerContext context + ) { + var typedReceiverResult = typeCheckExpression(untyped.receiver(), context); + var typedReceiver = typedReceiverResult.value(); + context = typedReceiverResult.context(); + + var structTypeInfo = context.structTypeInfo( + (StructType) typedReceiver.type(), + untyped.fieldName() + ); + + var fieldType = structTypeInfo.orElseThrow().fieldType(untyped.fieldName()).orElseThrow(); + + return context.toResult(new TypedFieldAccessNode( + typedReceiver, + untyped.fieldName(), + fieldType, + untyped.source() + )); + } + private static TypeCheckSteps typeCheckStepsFunctionDefinition( UntypedFunctionDefinitionNode untyped ) { diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java index 06b237e1..18b030f8 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java @@ -361,6 +361,11 @@ public class TypeCheckerContext { ); } + public Optional structTypeInfo(StructType type, String fieldName) { + return Optional.ofNullable(this.structTypeInfo.get(type)); + } + + public PMap structTypeInfo() { return structTypeInfo; } diff --git a/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java b/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java index fb776091..f0c3eff7 100644 --- a/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java +++ b/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java @@ -2,5 +2,10 @@ package org.shedlang.compiler.types; import org.pcollections.OrderedPMap; +import java.util.Optional; + public record StructTypeInfo(OrderedPMap fields) { + public Optional fieldType(String fieldName) { + return Optional.ofNullable(this.fields.get(fieldName)); + } } diff --git a/src/main/java/org/shedlang/compiler/util/P.java b/src/main/java/org/shedlang/compiler/util/P.java index fc822614..5d40d596 100644 --- a/src/main/java/org/shedlang/compiler/util/P.java +++ b/src/main/java/org/shedlang/compiler/util/P.java @@ -28,6 +28,15 @@ public class P { return map; } + @SafeVarargs + public static OrderedPMap orderedPMap(Map.Entry... entries) { + var map = OrderedPMap.empty(); + for (var entry : entries) { + map = map.plus(entry.getKey(), entry.getValue()); + } + return map; + } + @SafeVarargs public static OrderedPSet orderedSet(T... values) { return OrderedPSet.from(Arrays.asList(values)); -- cgit v1.2.3