aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-28 11:38:44 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-28 11:39:24 +0100
commit6d9a2f0b07204debf78f70e3d1ed5078ee4e54c0 (patch)
tree529563c9b13c39ef4e40b2e05e7495005ecd1c33 /src/main/java
parent97daf07ea93e36b5be1db2a270dcdd5d8e25cec7 (diff)
Basic type checking for field access
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java27
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java5
-rw-r--r--src/main/java/org/shedlang/compiler/types/StructTypeInfo.java5
-rw-r--r--src/main/java/org/shedlang/compiler/util/P.java9
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));
}