From 136bc83f98c9eeda4cc18d90c6c29839622b5759 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 17 Sep 2023 19:42:49 +0100 Subject: Support tuples in Patio code gen --- .../org/shedlang/compiler/patio/PatioCodeGen.java | 103 ++++++++++++++++++++- .../compiler/patio/PatioCodeGenLocalSpace.java | 3 + 2 files changed, 102 insertions(+), 4 deletions(-) (limited to 'src/main/java') 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; -- cgit v1.2.3