aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-01-21 19:01:12 +0000
committerMichael Williamson <mike@zwobble.org>2024-01-21 19:01:12 +0000
commit8147341b40ea563e8bdabfab1a71dd9c39d72a7c (patch)
tree1cb80456f7e4987bd868534529aae7ad2a5a9656 /src
parentde25b93ec50da213047fe423f77583c92d692eca (diff)
Add Patio byte-size-of and byte-offset-of instructions
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java6
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java6
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioSerializer.java35
-rw-r--r--src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java22
-rw-r--r--src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java19
-rw-r--r--src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java2
-rw-r--r--src/test/java/org/shedlang/compiler/patio/PatioSerializerTests.java46
-rw-r--r--src/test/java/org/shedlang/compiler/patio/instructions/Patio.java24
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,