aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-28 14:58:12 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-28 14:58:12 +0100
commita637fcc83f642d5320608ea7fc20a93f3ec5ab86 (patch)
tree7d32340746ba7e053250c5ae8fd24f4f6c990f9e /src/main/java
parent81a8685983e718f087319de8f1b27c059bbcf283 (diff)
Generate Patio code for defining structs
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java20
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java10
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java3
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java98
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java1
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java2
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java19
7 files changed, 149 insertions, 4 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
index e4a72194..0c6f94f2 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -223,7 +223,25 @@ public class PatioCodeGen {
}
case DefineStructInstruction defineStruct -> {
- throw new UnsupportedOperationException("TODO");
+ var targetResult = context.allocateVal(
+ PatioCodeGenLocalSpace.STRUCT_TYPE,
+ defineStruct.type().name(),
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var target = targetResult.value();
+ context = targetResult.context();
+
+ context = PatioCodeGenStructs.createType(
+ target,
+ defineStruct.type(),
+ defineStruct.fields(),
+ defineStruct.source(),
+ context
+ );
+
+ context = context.temporaryPush(target);
+
+ yield context;
}
case DiscardInstruction discard ->
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java
index fb176c1e..a0822d7e 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java
@@ -15,6 +15,8 @@ import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.typechecker.TypeInfos;
import org.shedlang.compiler.types.NamespaceName;
import org.shedlang.compiler.types.NamespaceTypeInfo;
+import org.shedlang.compiler.types.StructType;
+import org.shedlang.compiler.types.StructTypeInfo;
import org.shedlang.compiler.util.P;
import java.util.ArrayList;
@@ -36,6 +38,10 @@ public record PatioCodeGenContext(
return typeInfos.namespaceTypeInfo(namespaceName);
}
+ public StructTypeInfo structTypeInfo(StructType type) {
+ return typeInfos.structTypeInfo(type);
+ }
+
public static final CompilationUnitContext EMPTY = forTypeInfos(TypeInfos.EMPTY);
public static CompilationUnitContext forTypeInfos(TypeInfos typeInfos) {
@@ -240,6 +246,10 @@ public record PatioCodeGenContext(
return this.compilationUnitContext.namespaceTypeInfo(namespaceName);
}
+ public StructTypeInfo structTypeInfo(StructType type) {
+ return this.compilationUnitContext.structTypeInfo(type);
+ }
+
public PatioCodeGenResult<String> allocateCompilationUnitElementName(
PatioCodeGenCompilationUnitElementSpace space,
String name
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
index 63cb25e2..6a5f40e1 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
@@ -14,6 +14,9 @@ public enum PatioCodeGenLocalSpace {
LOCAL("local"),
RECEIVER("receiver"),
STRING("string"),
+ STRUCT_TYPE("structType"),
+ STRUCT_VALUE("structValue"),
+ STRUCT_VALUE_POINTER("structValuePointer"),
TEMPORARY("tmp"),
TUPLE("tuple"),
TUPLE_ELEMENT("tupleElement"),
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java
new file mode 100644
index 00000000..d99f3ce6
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStructs.java
@@ -0,0 +1,98 @@
+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.operands.PatioLocalRef;
+import org.shedlang.compiler.patio.ast.types.PatioDataLayout;
+import org.shedlang.compiler.patio.ast.types.PatioDataLayouts;
+import org.shedlang.compiler.patio.ast.types.PatioTypes;
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction;
+import org.shedlang.compiler.stackir.instructions.DefineStructInstruction;
+import org.shedlang.compiler.types.StructType;
+import org.shedlang.compiler.util.Lists;
+
+import java.util.List;
+
+public class PatioCodeGenStructs {
+ private PatioCodeGenStructs() {
+ }
+
+ public static PatioCodeGenContext createType(
+ PatioLocalRef target,
+ StructType type,
+ List<DefineStructInstruction.Field> fields,
+ Source source,
+ PatioCodeGenContext context
+ ) {
+ return PatioCodeGenClosures.create(
+ target,
+ type.name(),
+ List.of(),
+ fields.stream()
+ .map(field -> new DefineFunctionInstruction.Param(field.name(), field.source()))
+ .toList(),
+ FreeVariables.empty(),
+ bodyContext -> {
+ var valuePointerResult = bodyContext.allocateVal(
+ PatioCodeGenLocalSpace.STRUCT_VALUE_POINTER,
+ PatioTypes.DATA_POINTER
+ );
+ var valuePointer = valuePointerResult.value();
+ bodyContext = valuePointerResult.context();
+
+ var structDataLayout = structDataLayout(fields);
+
+ bodyContext = bodyContext.addInstruction(new PatioAllocHeap(
+ valuePointer,
+ structDataLayout,
+ source
+ ));
+
+ for (var fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) {
+ var field = fields.get(fieldIndex);
+
+ bodyContext = bodyContext
+ .addInstruction(new PatioMemoryStore(
+ valuePointer,
+ structDataLayout,
+ List.of(fieldIndex),
+ bodyContext.stackIrLocalNameToLocal(field.name()),
+ source
+ ));
+ }
+
+ var valueResult = bodyContext.allocateVal(
+ PatioCodeGenLocalSpace.STRUCT_VALUE,
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var value = valueResult.value();
+ bodyContext = valueResult.context();
+
+ bodyContext = bodyContext.addInstruction(new PatioDataPtrToInt(
+ value,
+ valuePointer,
+ source
+ ));
+
+ bodyContext = bodyContext.addInstruction(new PatioReturn(value, source));
+
+ return bodyContext;
+ },
+ source,
+ context
+ );
+ }
+
+ private static PatioDataLayout structDataLayout(
+ List<DefineStructInstruction.Field> fields
+ ) {
+ return PatioDataLayouts.struct(Lists.repeat(
+ PatioDataLayouts.INT,
+ fields.size()
+ ));
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java
index bafa51bf..1d91a1a5 100644
--- a/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java
+++ b/src/main/java/org/shedlang/compiler/stackir/instructions/DefineStructInstruction.java
@@ -10,6 +10,7 @@ import java.util.List;
*/
public record DefineStructInstruction(
StructType type,
+ // TODO: remove fields? We should have fields from the type info.
List<Field> fields,
Source source
) implements Instruction {
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
index c62b4e48..2223309d 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
@@ -392,6 +392,6 @@ public class TypeCheckerContext {
}
public TypeInfos toTypeInfos() {
- return new TypeInfos(namespaceTypeInfos);
+ return new TypeInfos(namespaceTypeInfos, structTypeInfos);
}
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java b/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java
index 7331ee07..7cd03cb4 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java
@@ -4,16 +4,21 @@ import org.pcollections.Empty;
import org.pcollections.PMap;
import org.shedlang.compiler.types.NamespaceName;
import org.shedlang.compiler.types.NamespaceTypeInfo;
+import org.shedlang.compiler.types.StructType;
+import org.shedlang.compiler.types.StructTypeInfo;
public class TypeInfos {
- public static final TypeInfos EMPTY = new TypeInfos(Empty.map());
+ public static final TypeInfos EMPTY = new TypeInfos(Empty.map(), Empty.map());
private final PMap<NamespaceName, NamespaceTypeInfo> namespaceTypeInfos;
+ private final PMap<StructType, StructTypeInfo> structTypeInfos;
public TypeInfos(
- PMap<NamespaceName, NamespaceTypeInfo> namespaceTypeInfos
+ PMap<NamespaceName, NamespaceTypeInfo> namespaceTypeInfos,
+ PMap<StructType, StructTypeInfo> structTypeInfos
) {
this.namespaceTypeInfos = namespaceTypeInfos;
+ this.structTypeInfos = structTypeInfos;
}
public NamespaceTypeInfo namespaceTypeInfo(NamespaceName namespaceName) {
@@ -25,4 +30,14 @@ public class TypeInfos {
return typeInfo;
}
}
+
+ public StructTypeInfo structTypeInfo(StructType type) {
+ // TODO: throw better error
+ var typeInfo = structTypeInfos.get(type);
+ if (typeInfo == null) {
+ throw new RuntimeException("No type info for: " + type);
+ } else {
+ return typeInfo;
+ }
+ }
}