aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-14 20:13:09 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-14 20:14:04 +0100
commit57446428f678ebc2bc5ad34d04e41feabe35d28f (patch)
tree9e619123ab79b69ed15b77f4b56a54c9ccb921aa /src/main/java
parentd4a8c7d7cba85e107b8532036b6e6838c57f4e2a (diff)
Compile zero-args to LLVM IR
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java15
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java158
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java4
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTypes.java4
4 files changed, 167 insertions, 14 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
index 0cd282cf..89cf70b7 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
@@ -1,6 +1,5 @@
package org.shedlang.compiler.backends.llvm;
-import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmCall;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperandInt;
import org.shedlang.compiler.stackir.instructions.*;
import org.shedlang.compiler.types.NamespaceName;
@@ -19,18 +18,10 @@ public class LlvmCompiler {
var receiver = receiverResult.value();
context = receiverResult.context();
- var temporaryResult = context.generateVariableLocal(
- LlvmCompilerLocalVariableSpace.TEMPORARY
- );
- var temporary = temporaryResult.value();
- context = temporaryResult.context();
-
- yield context.addInstruction(new LlvmCall(
- temporary,
- LlvmCompilerTypes.VALUE_TYPE,
+ yield LlvmCompilerClosures.call(
receiver,
- List.of()
- )).push(temporary);
+ context
+ );
}
case DefineFunctionInstruction defineFunctionInstruction -> {
throw new UnsupportedOperationException("TODO");
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java
new file mode 100644
index 00000000..68f66719
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java
@@ -0,0 +1,158 @@
+package org.shedlang.compiler.backends.llvm;
+
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmCall;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmGetElementPtr;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmIntToPtr;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmLoad;
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand;
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmTypedOperand;
+import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal;
+import org.shedlang.compiler.backends.llvm.ir.ast.types.*;
+
+import java.util.List;
+
+public class LlvmCompilerClosures {
+ private LlvmCompilerClosures() {
+ }
+
+ public static LlvmTypePointer typeClosurePointer() {
+ return LlvmTypes.pointer(typeClosureStruct());
+ }
+
+ public static LlvmTypeStructure typeClosureStruct() {
+ return LlvmTypes.structure(List.of(
+ typeClosureFunctionPointer(),
+ typeClosureEnvironment()
+ ));
+ }
+
+ public static LlvmTypePointer typeClosureFunctionPointer() {
+ return LlvmTypes.pointer(typeClosureFunction());
+ }
+
+ public static LlvmTypeFunction typeClosureFunction() {
+ return LlvmTypes.function(
+ LlvmCompilerTypes.VALUE_TYPE,
+ List.of(typeClosureEnvironmentPointer())
+ );
+ }
+
+ public static LlvmTypePointer typeClosureEnvironmentPointer() {
+ return LlvmTypes.pointer(typeClosureEnvironment());
+ }
+
+ public static LlvmTypeArray typeClosureEnvironment() {
+ return LlvmTypes.array(0, LlvmCompilerTypes.VALUE_TYPE);
+ }
+
+ public static LlvmCompilerContext call(
+ LlvmOperand closure,
+ LlvmCompilerContext context
+ ) {
+ var closurePointerResult = castValueToClosurePointer(closure, context);
+ var closurePointer = closurePointerResult.value();
+ context = closurePointerResult.context();
+
+ var functionPointerResult = loadClosureFunctionPointer(closurePointer, context);
+ var functionPointer = functionPointerResult.value();
+ context = functionPointerResult.context();
+
+ var environmentPointerResult = getClosureEnvironmentPointer(closurePointer, context);
+ var environmentPointer = environmentPointerResult.value();
+ context = environmentPointerResult.context();
+
+ var callTargetResult = context.generateVariableLocal(
+ LlvmCompilerLocalVariableSpace.TEMPORARY
+ );
+ var callTarget = callTargetResult.value();
+ context = callTargetResult.context();
+
+ return context.addInstruction(new LlvmCall(
+ callTarget,
+ LlvmCompilerTypes.VALUE_TYPE,
+ functionPointer,
+ List.of(new LlvmTypedOperand(typeClosureEnvironmentPointer(), environmentPointer))
+ )).push(callTarget);
+ }
+
+ private static LlvmCompilerResult<LlvmVariableLocal> castValueToClosurePointer(
+ LlvmOperand value,
+ LlvmCompilerContext context
+ ) {
+ var closurePointerResult = context.generateVariableLocal(
+ LlvmCompilerLocalVariableSpace.CLOSURE_POINTER
+ );
+ var closurePointer = closurePointerResult.value();
+ context = closurePointerResult.context();
+
+ context = context.addInstruction(new LlvmIntToPtr(
+ closurePointer,
+ LlvmCompilerTypes.VALUE_TYPE,
+ value,
+ typeClosurePointer()
+ ));
+
+ return context.toResult(closurePointer);
+ }
+
+ private static LlvmCompilerResult<LlvmVariableLocal> loadClosureFunctionPointer(
+ LlvmOperand closurePointer,
+ LlvmCompilerContext context
+ ) {
+ var functionPointerPointerResult = getClosureFunctionPointerPointer(closurePointer, context);
+ var functionPointerPointer = functionPointerPointerResult.value();
+ context = functionPointerPointerResult.context();
+
+ var functionPointerResult = context.generateVariableLocal(
+ LlvmCompilerLocalVariableSpace.CLOSURE_FUNCTION_POINTER
+ );
+ var functionPointer = functionPointerResult.value();
+ context = functionPointerResult.context();
+
+ return context.addInstruction(new LlvmLoad(
+ functionPointer,
+ typeClosureFunctionPointer(),
+ functionPointerPointer
+ )).toResult(functionPointer);
+ }
+
+ private static LlvmCompilerResult<LlvmVariableLocal> getClosureFunctionPointerPointer(
+ LlvmOperand closurePointer,
+ LlvmCompilerContext context
+ ) {
+ var functionPointerPointerResult = context.generateVariableLocal(
+ LlvmCompilerLocalVariableSpace.CLOSURE_FUNCTION_POINTER_POINTER
+ );
+ var functionPointerPointer = functionPointerPointerResult.value();
+ context = functionPointerPointerResult.context();
+
+ context = context.addInstruction(new LlvmGetElementPtr(
+ functionPointerPointer,
+ typeClosurePointer(),
+ closurePointer,
+ List.of(LlvmTypedOperand.arrayIndex(0), LlvmTypedOperand.structureIndex(0))
+ ));
+
+ return context.toResult(functionPointerPointer);
+ }
+
+ private static LlvmCompilerResult<LlvmVariableLocal> getClosureEnvironmentPointer(
+ LlvmOperand closurePointer,
+ LlvmCompilerContext context
+ ) {
+ var environmentPointerResult = context.generateVariableLocal(
+ LlvmCompilerLocalVariableSpace.CLOSURE_ENVIRONMENT_POINTER
+ );
+ var environmentPointer = environmentPointerResult.value();
+ context = environmentPointerResult.context();
+
+ context = context.addInstruction(new LlvmGetElementPtr(
+ environmentPointer,
+ typeClosurePointer(),
+ closurePointer,
+ List.of(LlvmTypedOperand.arrayIndex(0), LlvmTypedOperand.structureIndex(1))
+ ));
+
+ return context.toResult(environmentPointer);
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java
index 756e139b..457fa7c5 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java
@@ -1,6 +1,10 @@
package org.shedlang.compiler.backends.llvm;
public enum LlvmCompilerLocalVariableSpace {
+ CLOSURE_POINTER("closurePointer"),
+ CLOSURE_FUNCTION_POINTER("closureFunctionPointer"),
+ CLOSURE_FUNCTION_POINTER_POINTER("closureFunctionPointerPointer"),
+ CLOSURE_ENVIRONMENT_POINTER("closureEnvironmentPointer"),
FIELD_POINTER("fieldPointer"),
TEMPORARY("tmp");
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTypes.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTypes.java
index 773cbccd..3623d829 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTypes.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTypes.java
@@ -1,11 +1,11 @@
package org.shedlang.compiler.backends.llvm;
-import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType;
+import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypeScalar;
import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypes;
public class LlvmCompilerTypes {
private LlvmCompilerTypes() {
}
- public static final LlvmType VALUE_TYPE = LlvmTypes.INT_64;
+ public static final LlvmTypeScalar VALUE_TYPE = LlvmTypes.INT_64;
}