diff options
| author | Michael Williamson <mike@zwobble.org> | 2024-01-21 19:01:12 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2024-01-21 19:01:12 +0000 |
| commit | 8147341b40ea563e8bdabfab1a71dd9c39d72a7c (patch) | |
| tree | 1cb80456f7e4987bd868534529aae7ad2a5a9656 /src | |
| parent | de25b93ec50da213047fe423f77583c92d692eca (diff) | |
Add Patio byte-size-of and byte-offset-of instructions
Diffstat (limited to 'src')
8 files changed, 148 insertions, 12 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java index 1a7c46a8..fbeaa039 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java @@ -370,6 +370,12 @@ public class PatioToLlvm { )); } + case PatioByteOffsetOf patioByteOffsetOf -> + throw new UnsupportedOperationException("TODO"); + + case PatioByteSizeOf patioByteSizeOf -> + throw new UnsupportedOperationException("TODO"); + case PatioCall patioCall -> { var destination = Optional.<LlvmVariable>empty(); if (patioCall.destination().isPresent()) { diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java index e9589935..c140bf92 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java @@ -214,6 +214,12 @@ public class PatioToWasm { yield context; } + case PatioByteOffsetOf patioByteOffsetOf -> + throw new UnsupportedOperationException("TODO"); + + case PatioByteSizeOf patioByteSizeOf -> + throw new UnsupportedOperationException("TODO"); + case PatioCall patioCall -> { for (var patioArg : patioCall.args()) { context = generateOperand(patioArg, context); diff --git a/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java b/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java index 7a0a0d06..2d65bf1b 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java @@ -164,6 +164,21 @@ public class PatioSerializer { operandToTree(boolToInt.value()) ); + case PatioByteOffsetOf byteOffsetOf -> + treeListIndented( + treeIdentifier("byte-offset-of"), + operandToTree(byteOffsetOf.destination()), + dataLayoutToTree(byteOffsetOf.layout()), + offsetToTree(byteOffsetOf.offset()) + ); + + case PatioByteSizeOf byteSizeOf -> + treeListIndented( + treeIdentifier("byte-size-of"), + operandToTree(byteSizeOf.destination()), + dataLayoutToTree(byteSizeOf.layout()) + ); + case PatioCall call -> treeList( treeIdentifier("call"), @@ -272,11 +287,7 @@ public class PatioSerializer { operandToTree(memoryLoad.destination()), treeNamed("pointer", operandToTree(memoryLoad.pointer())), treeNamed("layout", dataLayoutToTree(memoryLoad.layout())), - treeNamed("offset", treeList( - memoryLoad.offset().stream() - .map(offset -> treeInt(offset)) - .toList() - )) + treeNamed("offset", offsetToTree(memoryLoad.offset())) ); case PatioMemoryStore memoryStore -> @@ -284,11 +295,7 @@ public class PatioSerializer { treeIdentifier("memory-store"), treeNamed("pointer", operandToTree(memoryStore.pointer())), treeNamed("layout", dataLayoutToTree(memoryStore.layout())), - treeNamed("offset", treeList( - memoryStore.offset().stream() - .map(offset -> treeInt(offset)) - .toList() - )), + treeNamed("offset", offsetToTree(memoryStore.offset())), treeNamed("value", operandToTree(memoryStore.value())) ); @@ -548,6 +555,14 @@ public class PatioSerializer { }; } + private static Tree offsetToTree(List<Integer> memoryLoad) { + return treeList( + memoryLoad.stream() + .map(offset -> treeInt(offset)) + .toList() + ); + } + private static Tree visibilityToTree(PatioVisibility visibility) { return treeIdentifier(switch (visibility) { case PRIVATE -> "private"; diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java new file mode 100644 index 00000000..40cf3c67 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java @@ -0,0 +1,22 @@ +package org.shedlang.compiler.patio.instructions; + +import org.shedlang.compiler.patio.operands.PatioLocalRef; +import org.shedlang.compiler.patio.types.PatioDataLayout; +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +/** + * Get the offset, in bytes, of an offset in a data layout. + */ +public record PatioByteOffsetOf( + PatioLocalRef destination, + PatioDataLayout layout, + List<Integer> offset, + Source source +) implements PatioInstruction { + @Override + public boolean isBlockTerminator() { + return false; + } +} diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java new file mode 100644 index 00000000..e4f97309 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java @@ -0,0 +1,19 @@ +package org.shedlang.compiler.patio.instructions; + +import org.shedlang.compiler.patio.operands.PatioLocalRef; +import org.shedlang.compiler.patio.types.PatioDataLayout; +import org.shedlang.compiler.sources.Source; + +/** + * Get the size, in bytes, of a data layout. + */ +public record PatioByteSizeOf( + PatioLocalRef destination, + PatioDataLayout layout, + Source source +) implements PatioInstruction { + @Override + public boolean isBlockTerminator() { + return false; + } +} diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java index 8c5860a7..72d62c99 100644 --- a/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio.instructions; import org.shedlang.compiler.sources.Source; -public sealed interface PatioInstruction permits PatioAllocHeap, PatioAllocStack, PatioBlock, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn, PatioReturnVoid, PatioSwitch, PatioThrow, PatioTry, PatioUnreachable, PatioVarLoad, PatioVarStore { +public sealed interface PatioInstruction permits PatioAllocHeap, PatioAllocStack, PatioBlock, PatioBoolToInt, PatioByteOffsetOf, PatioByteSizeOf, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn, PatioReturnVoid, PatioSwitch, PatioThrow, PatioTry, PatioUnreachable, PatioVarLoad, PatioVarStore { boolean isBlockTerminator(); Source source(); } diff --git a/src/test/java/org/shedlang/compiler/patio/PatioSerializerTests.java b/src/test/java/org/shedlang/compiler/patio/PatioSerializerTests.java index 33dccf5a..404b072f 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioSerializerTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioSerializerTests.java @@ -1,10 +1,10 @@ package org.shedlang.compiler.patio; import org.junit.jupiter.api.Test; +import org.shedlang.compiler.patio.instructions.Patio; import org.shedlang.compiler.patio.types.PatioDataLayouts; import org.shedlang.compiler.patio.types.PatioDataValues; import org.shedlang.compiler.patio.types.PatioTypes; -import org.shedlang.compiler.patio.instructions.Patio; import java.util.List; import java.util.Optional; @@ -193,6 +193,50 @@ public class PatioSerializerTests { } @Test + public void canSerializeByteOffsetOf() { + var instruction = Patio.byteOffsetOf( + Patio.localRef("destination"), + PatioDataLayouts.struct(List.of( + PatioDataLayouts.INT, + PatioDataLayouts.BYTE + )), + List.of(1, 2) + ); + + var string = PatioTesting.serializeInstruction(instruction); + + assertThat(string, equalTo(""" + ( + byte-offset-of + (local "destination") + (struct (int byte)) + (1 2) + )""" + )); + } + + @Test + public void canSerializeByteSizeOf() { + var instruction = Patio.byteSizeOf( + Patio.localRef("destination"), + PatioDataLayouts.struct(List.of( + PatioDataLayouts.INT, + PatioDataLayouts.BYTE + )) + ); + + var string = PatioTesting.serializeInstruction(instruction); + + assertThat(string, equalTo(""" + ( + byte-size-of + (local "destination") + (struct (int byte)) + )""" + )); + } + + @Test public void canSerializeCallWithoutTarget() { var instruction = Patio.call( Optional.empty(), diff --git a/src/test/java/org/shedlang/compiler/patio/instructions/Patio.java b/src/test/java/org/shedlang/compiler/patio/instructions/Patio.java index e1610ada..a1dbd84e 100644 --- a/src/test/java/org/shedlang/compiler/patio/instructions/Patio.java +++ b/src/test/java/org/shedlang/compiler/patio/instructions/Patio.java @@ -36,6 +36,30 @@ public class Patio { return new PatioBoolToInt(destination, value, Sources.NULL); } + public static PatioInstruction byteOffsetOf( + PatioLocalRef destination, + PatioDataLayout layout, + List<Integer> offset + ) { + return new PatioByteOffsetOf( + destination, + layout, + offset, + Sources.NULL + ); + } + + public static PatioInstruction byteSizeOf( + PatioLocalRef destination, + PatioDataLayout layout + ) { + return new PatioByteSizeOf( + destination, + layout, + Sources.NULL + ); + } + public static PatioInstruction call( Optional<PatioLocalRef> destination, String name, |
