aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-28 15:13:55 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-28 15:13:55 +0100
commit37623ba6964acf573e100903fbdd1453d69d2e26 (patch)
treed7dd087153dc64cdf3f386b4897a3255d64db453 /src/main/java
parenta637fcc83f642d5320608ea7fc20a93f3ec5ab86 (diff)
Add Patio code gen for struct field accesses
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java9
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java51
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java7
-rw-r--r--src/main/java/org/shedlang/compiler/types/StructTypeInfo.java17
-rw-r--r--src/main/java/org/shedlang/compiler/util/POrderedMap.java13
5 files changed, 81 insertions, 16 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
index 0c6f94f2..9382eab7 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -281,7 +281,14 @@ public class PatioCodeGen {
}
case FieldLoadInstruction.Receiver.Struct receiverStruct -> {
- throw new UnsupportedOperationException("TODO");
+ context = PatioCodeGenStructs.fieldLoad(
+ target,
+ receiver,
+ receiverStruct.type(),
+ fieldLoad.fieldName(),
+ fieldLoad.source(),
+ context
+ );
}
}
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java
index d99f3ce6..4d6ece42 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java
@@ -1,10 +1,7 @@
package org.shedlang.compiler.patio;
import org.shedlang.compiler.ast.typed.FreeVariables;
-import org.shedlang.compiler.patio.ast.instructions.PatioAllocHeap;
-import org.shedlang.compiler.patio.ast.instructions.PatioDataPtrToInt;
-import org.shedlang.compiler.patio.ast.instructions.PatioMemoryStore;
-import org.shedlang.compiler.patio.ast.instructions.PatioReturn;
+import org.shedlang.compiler.patio.ast.instructions.*;
import org.shedlang.compiler.patio.ast.operands.PatioLocalRef;
import org.shedlang.compiler.patio.ast.types.PatioDataLayout;
import org.shedlang.compiler.patio.ast.types.PatioDataLayouts;
@@ -44,7 +41,7 @@ public class PatioCodeGenStructs {
var valuePointer = valuePointerResult.value();
bodyContext = valuePointerResult.context();
- var structDataLayout = structDataLayout(fields);
+ var structDataLayout = structDataLayout(type, context);
bodyContext = bodyContext.addInstruction(new PatioAllocHeap(
valuePointer,
@@ -87,12 +84,52 @@ public class PatioCodeGenStructs {
);
}
+ public static PatioCodeGenContext fieldLoad(
+ PatioLocalRef target,
+ PatioLocalRef receiver,
+ StructType type,
+ String fieldName,
+ Source source,
+ PatioCodeGenContext context
+ ) {
+ var valuePointerResult = context.allocateVal(
+ PatioCodeGenLocalSpace.STRUCT_VALUE_POINTER,
+ PatioTypes.DATA_POINTER
+ );
+ var valuePointer = valuePointerResult.value();
+ context = valuePointerResult.context();
+
+ context = context.addInstruction(new PatioIntToDataPtr(
+ valuePointer,
+ receiver,
+ source
+ ));
+
+ var structDataLayout = structDataLayout(type, context);
+
+ var structTypeInfo = context.structTypeInfo(type);
+ var fieldIndex = structTypeInfo.fieldIndex(fieldName);
+
+ context = context.addInstruction(new PatioMemoryLoad(
+ target,
+ valuePointer,
+ structDataLayout,
+ List.of(fieldIndex),
+ source
+ ));
+
+ return context;
+ }
+
private static PatioDataLayout structDataLayout(
- List<DefineStructInstruction.Field> fields
+ StructType type,
+ PatioCodeGenContext context
) {
+ var structTypeInfo = context.structTypeInfo(type);
+
return PatioDataLayouts.struct(Lists.repeat(
PatioDataLayouts.INT,
- fields.size()
+ structTypeInfo.fields().size()
));
}
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index dc25bfc3..81917dfb 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -1,11 +1,10 @@
package org.shedlang.compiler.typechecker;
-import org.pcollections.OrderedPMap;
import org.shedlang.compiler.ast.typed.*;
import org.shedlang.compiler.ast.untyped.*;
import org.shedlang.compiler.sources.Source;
-import org.shedlang.compiler.typechecker.errors.*;
import org.shedlang.compiler.typechecker.errors.NoSuchFieldError;
+import org.shedlang.compiler.typechecker.errors.*;
import org.shedlang.compiler.typechecker.typesets.TypeSetTypeLevelValue;
import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.*;
@@ -323,7 +322,7 @@ public class TypeChecker {
) {
var structTypeInfo = context.structTypeInfo(structType, typedReceiver.source());
- var namedParams = structTypeInfo.fields().entrySet().stream()
+ var namedParams = structTypeInfo.fields().entryStream()
.map(field -> {
var name = field.getKey();
var type = field.getValue();
@@ -859,7 +858,7 @@ public class TypeChecker {
@Override
public TypeCheckerContext defineTypes(TypeCheckerContext context) {
var typedFieldNodes = new ArrayList<TypedStructFieldDefinitionNode>();
- var fieldTypes = OrderedPMap.<String, Type>empty();
+ var fieldTypes = P.<String, Type>orderedMap();
for (var untypedField : untyped.fields()) {
var typedFieldNode = new TypedStructFieldDefinitionNode(
diff --git a/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java b/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java
index f0c3eff7..7a95a234 100644
--- a/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java
+++ b/src/main/java/org/shedlang/compiler/types/StructTypeInfo.java
@@ -1,11 +1,22 @@
package org.shedlang.compiler.types;
-import org.pcollections.OrderedPMap;
+import org.shedlang.compiler.util.POrderedMap;
import java.util.Optional;
-public record StructTypeInfo(OrderedPMap<String, Type> fields) {
+public record StructTypeInfo(POrderedMap<String, Type> fields) {
public Optional<Type> fieldType(String fieldName) {
- return Optional.ofNullable(this.fields.get(fieldName));
+ return this.fields.get(fieldName);
+ }
+
+ public int fieldIndex(String fieldName) {
+ // TODO: extract common field set from namespace type info
+ var fieldIndex = fields.keys().indexOf(fieldName);
+
+ if (fieldIndex == -1) {
+ throw new NoSuchFieldInternalError(fieldName);
+ } else {
+ return fieldIndex;
+ }
}
}
diff --git a/src/main/java/org/shedlang/compiler/util/POrderedMap.java b/src/main/java/org/shedlang/compiler/util/POrderedMap.java
index 3ab74270..4a8780ad 100644
--- a/src/main/java/org/shedlang/compiler/util/POrderedMap.java
+++ b/src/main/java/org/shedlang/compiler/util/POrderedMap.java
@@ -4,7 +4,9 @@ import org.pcollections.Empty;
import org.pcollections.PMap;
import org.pcollections.PVector;
-import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
public class POrderedMap<K, V> {
public static <K, V> POrderedMap<K, V> empty() {
@@ -42,6 +44,10 @@ public class POrderedMap<K, V> {
return keys;
}
+ public Optional<V> get(K key) {
+ return Optional.ofNullable(map.get(key));
+ }
+
public PVector<V> toValues() {
return keys.stream()
.map(key -> map.get(key))
@@ -52,6 +58,11 @@ public class POrderedMap<K, V> {
return keys.size();
}
+ public Stream<Map.Entry<K, V>> entryStream() {
+ return keys.stream()
+ .map(key -> Map.entry(key, map.get(key)));
+ }
+
@Override
public boolean equals(Object other) {
if (this == other) {