diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-09-17 19:42:49 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-09-17 19:42:49 +0100 |
| commit | 136bc83f98c9eeda4cc18d90c6c29839622b5759 (patch) | |
| tree | 2f0b5cbacef40673a28bd6f58149483575d0b715 /src/main/java | |
| parent | cb79027f3045b979b964d5dd4e6229a6d0212b0e (diff) | |
Support tuples in Patio code gen
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java | 103 | ||||
| -rw-r--r-- | src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java | 3 |
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; |
