aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-30 19:35:21 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-30 19:35:21 +0100
commit71c588ca231d275c5263b3e9ca5f7f57c4e048a1 (patch)
tree7e132e16697d881fd3472fc1b81f9731ecd7ae4e /src/main/java
parente8e3854cdda2c5aa2d47069e90698f5288f28b7c (diff)
Add field-load instruction
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java17
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenContext.java5
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java15
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java7
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java15
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java2
6 files changed, 60 insertions, 1 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
index cd302929..135e9552 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
@@ -136,6 +136,23 @@ public class LlvmCodeGen {
case DiscardInstruction discardInstruction ->
context.pop().context();
+ case FieldLoadInstruction fieldLoad -> {
+ var receiverResult = context.pop();
+ var receiver = receiverResult.value();
+ context = receiverResult.context();
+
+ var fieldLoadResult = LlvmCodeGenNamespaces.fieldLoad(
+ fieldLoad.namespaceName(),
+ receiver,
+ fieldLoad.fieldName(),
+ context
+ );
+ var fieldValue = fieldLoadResult.value();
+ context = fieldLoadResult.context();
+
+ yield context.push(fieldValue);
+ }
+
case LocalLoadInstruction localLoad ->
context.push(context.shedLocal(localLoad.name()));
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenContext.java
index e7dddf02..90541aca 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenContext.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenContext.java
@@ -163,6 +163,11 @@ public record LlvmCodeGenContext(
LlvmType returnType,
List<LlvmParam> params
) {
+ if (!instructions.isEmpty()) {
+ // TODO: better error
+ throw new RuntimeException("unterminated basic block");
+ }
+
return new LlvmFunctionDefinition(
name,
returnType,
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
index 71043f81..212c81ff 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
@@ -164,6 +164,21 @@ public class WasmCodeGen {
case DiscardInstruction discard ->
context.addInstruction(new WasmDrop());
+ case FieldLoadInstruction fieldLoad -> {
+ var receiverResult = context.generateLocal(WasmCodeGenLocalSpace.RECEIVER);
+ var receiver = receiverResult.value();
+ context = receiverResult.context();
+
+ context = context.addInstruction(new WasmLocalSet(receiver));
+
+ yield WasmCodeGenNamespaces.fieldLoad(
+ fieldLoad.namespaceName(),
+ receiver,
+ fieldLoad.fieldName(),
+ context
+ );
+ }
+
case LocalLoadInstruction localLoad ->
context.addInstruction(new WasmLocalGet(context.shedLocal(localLoad.name())));
diff --git a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
index 35789b18..ef832b90 100644
--- a/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
+++ b/src/main/java/org/shedlang/compiler/stackir/InstructionSerializer.java
@@ -74,6 +74,13 @@ public class InstructionSerializer {
treeList(
treeIdentifier("discard")
);
+
+ case FieldLoadInstruction fieldLoad ->
+ treeList(
+ treeIdentifier("field-load"),
+ treeString(fieldLoad.namespaceName().toString()),
+ treeString(fieldLoad.fieldName())
+ );
case LocalLoadInstruction localLoadInstruction ->
treeList(
diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java
new file mode 100644
index 00000000..98ea9952
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/stackir/instructions/FieldLoadInstruction.java
@@ -0,0 +1,15 @@
+package org.shedlang.compiler.stackir.instructions;
+
+import org.shedlang.compiler.sources.Source;
+import org.shedlang.compiler.types.NamespaceName;
+
+/**
+ * Pop a value from the stack, get the given field from the popped value, and
+ * push the field's value onto the stack.
+ */
+public record FieldLoadInstruction(
+ NamespaceName namespaceName,
+ String fieldName,
+ Source source
+) implements Instruction {
+}
diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java
index 1fb0bede..6a21404c 100644
--- a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java
+++ b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java
@@ -3,7 +3,7 @@ package org.shedlang.compiler.stackir.instructions;
import org.shedlang.compiler.sources.Source;
public sealed interface Instruction
- permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction {
+ permits CallInstruction, DefineFunctionInstruction, DiscardInstruction, FieldLoadInstruction, LocalLoadInstruction, LocalStoreInstruction, NamespaceFieldStoreInstruction, NamespaceImportInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction, PushUnitInstruction, ReturnInstruction {
Source source();
}