aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-17 19:42:49 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-17 19:42:49 +0100
commit136bc83f98c9eeda4cc18d90c6c29839622b5759 (patch)
tree2f0b5cbacef40673a28bd6f58149483575d0b715 /src/main/java
parentcb79027f3045b979b964d5dd4e6229a6d0212b0e (diff)
Support tuples in Patio code gen
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java103
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java3
2 files changed, 102 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 4922bf14..b92d7850 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java
@@ -6,12 +6,14 @@ import org.shedlang.compiler.patio.ast.instructions.*;
import org.shedlang.compiler.patio.ast.operands.PatioInt;
import org.shedlang.compiler.patio.ast.operands.PatioLocalRef;
import org.shedlang.compiler.patio.ast.operands.PatioOperand;
+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.sources.Sources;
import org.shedlang.compiler.stackir.StackIrNamespace;
import org.shedlang.compiler.stackir.instructions.*;
import org.shedlang.compiler.types.NamespaceName;
+import org.shedlang.compiler.util.Lists;
import java.util.ArrayList;
import java.util.Collections;
@@ -225,8 +227,13 @@ public class PatioCodeGen {
case DiscardInstruction discard ->
context.temporaryPop().context();
- case DuplicateInstruction duplicate ->
- throw new UnsupportedOperationException("TODO");
+ case DuplicateInstruction duplicate -> {
+ var valueResult = context.temporaryPop();
+ var value = valueResult.value();
+ context = valueResult.context();
+
+ yield context.temporaryPush(value).temporaryPush(value);
+ }
case FieldLoadInstruction fieldLoad -> {
var receiverResult = context.temporaryPop();
@@ -471,11 +478,99 @@ public class PatioCodeGen {
);
case TupleCreateInstruction tupleCreate -> {
- throw new UnsupportedOperationException("TODO");
+ var tuplePointerResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TUPLE_POINTER,
+ PatioTypes.DATA_POINTER
+ );
+ var tuplePointer = tuplePointerResult.value();
+ context = tuplePointerResult.context();
+
+ var tupleLayout = PatioDataLayouts.struct(Lists.repeat(
+ PatioDataLayouts.INT,
+ tupleCreate.elementCount()
+ ));
+
+ context = context.addInstruction(new PatioAllocHeap(
+ tuplePointer,
+ tupleLayout,
+ tupleCreate.source()
+ ));
+
+ for (var elementIndex = tupleCreate.elementCount(); elementIndex --> 0;) {
+ var tupleElementResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TUPLE_ELEMENT,
+ Integer.toString(elementIndex),
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var tupleElement = tupleElementResult.value();
+ context = tupleElementResult.context();
+
+ context = context.temporaryPopIntoLocal(tupleElement, tupleCreate.source());
+
+ context = context.addInstruction(new PatioMemoryStore(
+ tuplePointer,
+ tupleLayout,
+ List.of(elementIndex),
+ tupleElement,
+ tupleCreate.source()
+ ));
+ }
+
+ var tupleResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TUPLE,
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var tuple = tupleResult.value();
+ context = tupleResult.context();
+
+ context = context.addInstruction(new PatioDataPtrToInt(
+ tuple,
+ tuplePointer,
+ tupleCreate.source()
+ ));
+
+ yield context.temporaryPush(tuple);
}
case TupleGetInstruction tupleGet -> {
- throw new UnsupportedOperationException("TODO");
+ // TODO: store tuple type in case we want out-of-order fields?
+ var tupleResult = context.temporaryPop();
+ var tuple = tupleResult.value();
+ context = tupleResult.context();
+
+ var tuplePointerResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TUPLE,
+ PatioTypes.DATA_POINTER
+ );
+ var tuplePointer = tuplePointerResult.value();
+ context = tuplePointerResult.context();
+
+ context = context.addInstruction(new PatioIntToDataPtr(
+ tuplePointer,
+ tuple,
+ tupleGet.source()
+ ));
+
+ var targetResult = context.allocateVal(
+ PatioCodeGenLocalSpace.TUPLE_ELEMENT,
+ Integer.toString(tupleGet.elementIndex()),
+ PatioCodeGenTypes.VALUE_TYPE
+ );
+ var target = targetResult.value();
+ context = targetResult.context();
+
+ context = context.addInstruction(new PatioMemoryLoad(
+ target,
+ tuplePointer,
+ PatioDataLayouts.struct(Lists.repeat(
+ PatioDataLayouts.INT,
+ tupleGet.elementIndex() + 1
+ )),
+ List.of(tupleGet.elementIndex()),
+ tupleGet.source()
+ ));
+
+ yield context.temporaryPush(target);
}
case VarLoadInstruction varLoad -> {
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
index 74e394bb..63cb25e2 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
@@ -15,6 +15,9 @@ public enum PatioCodeGenLocalSpace {
RECEIVER("receiver"),
STRING("string"),
TEMPORARY("tmp"),
+ TUPLE("tuple"),
+ TUPLE_ELEMENT("tupleElement"),
+ TUPLE_POINTER("tuplePointer"),
VAR_VALUE("varValue");
private final String name;