aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-16 22:50:45 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-16 22:50:45 +0100
commitdbb847a2e9524e1a6479c13ea2379dfa453bb32b (patch)
tree1d589b67275a9a4948dc6c1bfb0e455b93972056 /src/test/java
parentfa21920d943f199609712461cb700418d6d4ead0 (diff)
Generate top level entity for minimal function
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerDefineFunctionTests.java63
-rw-r--r--src/test/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmIrMatchers.java32
2 files changed, 95 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerDefineFunctionTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerDefineFunctionTests.java
new file mode 100644
index 00000000..1575c2ad
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmCompilerDefineFunctionTests.java
@@ -0,0 +1,63 @@
+package org.shedlang.compiler.backends.llvm;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.backends.llvm.ir.ast.LlvmFunctionDefinition;
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand;
+import org.shedlang.compiler.sources.Sources;
+import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction;
+import org.shedlang.compiler.stackir.instructions.Instructions;
+import org.zwobble.precisely.Matcher;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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 LlvmCompilerDefineFunctionTests {
+ @Test
+ public void canDefineMinimalFunction() {
+ var instruction = new DefineFunctionInstruction(
+ "f",
+ List.of(),
+ List.of(),
+ Set.of(),
+ List.of(
+ Instructions.pushUnit()
+ ),
+ Sources.NULL
+ );
+ var context = LlvmCompilerContext.EMPTY;
+
+ var result = LlvmCompiler.compileInstruction(instruction, context);
+
+ assertThat(result.topLevelEntities(), isSequence(
+ instanceOf(
+ LlvmFunctionDefinition.class,
+ has("name", x -> x.name(), equalTo("shed__fun__f__0")),
+ has("returnType", x -> x.returnType(), equalTo(LlvmCompilerTypes.VALUE_TYPE)),
+ has("params", x -> x.params(), isSequence(
+ isLlvmParam(LlvmCompilerClosures.typeClosureEnvironmentPointer(), "shed__env__0")
+ )),
+ has("body", x -> x.body(), isSequence(
+ isLlvmBasicBlock(
+ isSequence(),
+ isLlvmReturn(LlvmCompilerTypes.VALUE_TYPE, isLlvmOperandInt(0))
+ )
+ ))
+ )
+ ));
+ assertThat(result.instructions(), isSequence());
+ assertThat(result.stack(), isSequence());
+ assertThat(result.locals().entrySet(), isSequence());
+ }
+
+ private static Matcher<Map.Entry<String, LlvmOperand>> isLocal(String name, Matcher<LlvmOperand> operand) {
+ return allOf(
+ has("name", x -> x.getKey(), equalTo(name)),
+ has("operand", x -> x.getValue(), operand)
+ );
+ }
+}
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 21755f6e..f80746e1 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
@@ -1,5 +1,8 @@
package org.shedlang.compiler.backends.llvm.ir.ast;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmInstruction;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmReturn;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmTerminatorInstruction;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.*;
import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType;
import org.zwobble.precisely.Matcher;
@@ -10,6 +13,17 @@ public class LlvmIrMatchers {
private LlvmIrMatchers() {
}
+ public static Matcher<LlvmBasicBlock> isLlvmBasicBlock(
+ Matcher<Iterable<? extends LlvmInstruction>> instructions,
+ Matcher<LlvmTerminatorInstruction> terminator
+ ) {
+ return allOf(
+ has("label", x -> x.label(), isOptionalEmpty()),
+ has("instructions", x -> x.instructions(), instructions),
+ has("terminator", x -> x.terminator(), terminator)
+ );
+ }
+
public static Matcher<LlvmOperand> isLlvmOperandInt(long value) {
return instanceOf(
LlvmOperandInt.class,
@@ -30,6 +44,24 @@ public class LlvmIrMatchers {
);
}
+ public static Matcher<LlvmParam> isLlvmParam(LlvmType type, String name) {
+ return allOf(
+ has("type", x -> x.type(), equalTo(type)),
+ has("name", x -> x.name(), equalTo(name))
+ );
+ }
+
+ public static Matcher<LlvmTerminatorInstruction> isLlvmReturn(
+ LlvmType type,
+ Matcher<LlvmOperand> value
+ ) {
+ return instanceOf(
+ LlvmReturn.class,
+ has("type", x -> x.type(), equalTo(type)),
+ has("value", x -> x.value(), value)
+ );
+ }
+
public static Matcher<LlvmTypedOperand> isLlvmTypedOperand(LlvmType type, Matcher<LlvmOperand> operand) {
return allOf(
has("type", x -> x.type(), equalTo(type)),