From edff0de2d08ed5a4bab9c1f3f748d7478fc0de1d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 13 Jun 2023 23:10:45 +0100 Subject: Compile namespace-field-store to LLVM IR --- .../llvm/LlvmCompilerNamespaceFieldStoreTests.java | 67 ++++++++++++++++++++++ .../backends/llvm/ir/ast/LlvmIrMatchers.java | 7 +++ 2 files changed, 74 insertions(+) create mode 100644 src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaceFieldStoreTests.java (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaceFieldStoreTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaceFieldStoreTests.java new file mode 100644 index 00000000..7877ed87 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaceFieldStoreTests.java @@ -0,0 +1,67 @@ +package org.shedlang.compiler.backends.llvm; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.backends.llvm.ir.ast.LlvmIr; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmGetElementPtr; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmStore; +import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes; +import org.shedlang.compiler.stackir.instructions.Instructions; +import org.shedlang.compiler.typechecker.TypeCheckerContext; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.shedlang.compiler.backends.llvm.ir.ast.LlvmIrMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.*; + +public class LlvmCompilerNamespaceFieldStoreTests { + @Test + public void namespaceFieldStorePopsFromStackAndUpdatesFieldOnNamespace() { + var namespaceName = new NamespaceName(List.of("Example", "Project")); + var instruction = Instructions.namespaceFieldStore(namespaceName, "y"); + var typeInfo = TypeCheckerContext.EMPTY + .addNamespaceField(namespaceName, "x", Types.INT) + .addNamespaceField(namespaceName, "y", Types.INT) + .addNamespaceField(namespaceName, "z", Types.INT) + .toTypeInfo(); + var context = LlvmCompilerContext.fromTypeInfo(typeInfo) + .push(LlvmIr.operandInt(0)) + .push(LlvmIr.operandInt(1)); + + var result = LlvmCompiler.compileInstruction(instruction, context); + + assertThat(result.instructions(), isSequence( + instanceOf( + LlvmGetElementPtr.class, + has("target", x -> x.target(), isLlvmVariableLocal("fieldPointer__y")), + has( + "pointerType", + x -> x.pointerType(), + equalTo(LlvmTypes.pointer(LlvmTypes.structure(List.of( + LlvmTypes.INT_64, + LlvmTypes.INT_64, + LlvmTypes.INT_64 + )))) + ), + has( + "pointer", + x -> x.pointer(), + isLlvmVariableGlobal("shed__namespace__Example_Project") + ), + has("indexes", x -> x.indexes(), isSequence( + isLlvmTypedOperand(LlvmTypes.INT_64, isLlvmOperandInt(0)), + isLlvmTypedOperand(LlvmTypes.INT_32, isLlvmOperandInt(1)) + )) + ), + instanceOf( + LlvmStore.class, + has("type", x -> x.type(), equalTo(LlvmTypes.INT_64)), + has("value", x -> x.value(), isLlvmOperandInt(1)), + has("pointer", x -> x.pointer(), isLlvmVariableLocal("fieldPointer__y")) + ) + )); + assertThat(result.stack(), isSequence(isLlvmOperandInt(0))); + } +} diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmIrMatchers.java b/src/test/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmIrMatchers.java index 8582ce93..21755f6e 100644 --- a/src/test/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmIrMatchers.java +++ b/src/test/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmIrMatchers.java @@ -30,6 +30,13 @@ public class LlvmIrMatchers { ); } + public static Matcher isLlvmTypedOperand(LlvmType type, Matcher operand) { + return allOf( + has("type", x -> x.type(), equalTo(type)), + has("operand", x -> x.operand(), operand) + ); + } + public static Matcher isLlvmVariableGlobal(String name) { return instanceOf( LlvmVariableGlobal.class, -- cgit v1.2.3