diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-09-28 11:38:44 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-09-28 11:39:24 +0100 |
| commit | 6d9a2f0b07204debf78f70e3d1ed5078ee4e54c0 (patch) | |
| tree | 529563c9b13c39ef4e40b2e05e7495005ecd1c33 /src/main/java | |
| parent | 97daf07ea93e36b5be1db2a270dcdd5d8e25cec7 (diff) | |
Basic type checking for field access
Diffstat (limited to 'src/main/java')
4 files changed, 44 insertions, 2 deletions
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<TypedFieldAccessNode> 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<TypedFunctionDefinitionNode> 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> structTypeInfo(StructType type, String fieldName) { + return Optional.ofNullable(this.structTypeInfo.get(type)); + } + + public PMap<StructType, StructTypeInfo> 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<String, Type> fields) { + public Optional<Type> 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 @@ -29,6 +29,15 @@ public class P { } @SafeVarargs + public static <K, V> OrderedPMap<K, V> orderedPMap(Map.Entry<K, V>... entries) { + var map = OrderedPMap.<K, V>empty(); + for (var entry : entries) { + map = map.plus(entry.getKey(), entry.getValue()); + } + return map; + } + + @SafeVarargs public static <T> OrderedPSet<T> orderedSet(T... values) { return OrderedPSet.from(Arrays.asList(values)); } |
