aboutsummaryrefslogtreecommitdiff
path: root/src/main/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/main/java
parentfa21920d943f199609712461cb700418d6d4ead0 (diff)
Generate top level entity for minimal function
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java38
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java32
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTopLevelEntitySpace.java1
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmTopLevelEntity.java1
4 files changed, 67 insertions, 5 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 7fc14092..2ad82eef 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java
@@ -1,5 +1,9 @@
package org.shedlang.compiler.backends.llvm;
+import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock;
+import org.shedlang.compiler.backends.llvm.ir.ast.LlvmFunctionDefinition;
+import org.shedlang.compiler.backends.llvm.ir.ast.LlvmParam;
+import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmReturn;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperandInt;
import org.shedlang.compiler.stackir.instructions.*;
@@ -49,8 +53,38 @@ public class LlvmCompiler {
args
);
}
- case DefineFunctionInstruction defineFunctionInstruction -> {
- throw new UnsupportedOperationException("TODO");
+ case DefineFunctionInstruction defineFunction -> {
+ var topLevelEntityName = context.generateTopLevelEntityName(
+ LlvmCompilerTopLevelEntitySpace.FUNCTION,
+ defineFunction.name()
+ );
+
+ var functionContext = context.enterFunction();
+ for (var bodyInstruction : defineFunction.body()) {
+ functionContext = compileInstruction(bodyInstruction, functionContext);
+ }
+ // TODO: rejoin function context with context
+ // TODO: assert stack has exactly one element
+ var returnValue = functionContext.stack().get(0);
+
+ yield context.addTopLevelEntity(new LlvmFunctionDefinition(
+ topLevelEntityName,
+ LlvmCompilerTypes.VALUE_TYPE,
+ List.of(
+ new LlvmParam(
+ LlvmCompilerClosures.typeClosureEnvironmentPointer(),
+ // TODO: allocate name properly
+ "shed__env__0"
+ )
+ ),
+ List.of(
+ new LlvmBasicBlock(
+ Optional.empty(),
+ List.of(),
+ new LlvmReturn(LlvmCompilerTypes.VALUE_TYPE, returnValue)
+ )
+ )
+ ));
}
case DiscardInstruction discardInstruction ->
context.pop().context();
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java
index e1925e24..d558f483 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java
@@ -93,21 +93,36 @@ public record LlvmCompilerContext(
builder.unnamedAddr()
);
+ return addTopLevelEntity(globalDefinition).toResult(globalDefinition);
+ }
+
+ public LlvmCompilerContext addTopLevelEntity(LlvmTopLevelEntity topLevelEntity) {
return new LlvmCompilerContext(
typeInfo,
stack,
locals,
instructions,
- topLevelEntitiesByName.plus(globalDefinition.name(), globalDefinition),
+ topLevelEntitiesByName.plus(topLevelEntity.name(), topLevelEntity),
localVariableNames
- ).toResult(globalDefinition);
+ );
+ }
+
+ public String generateTopLevelEntityName(LlvmCompilerTopLevelEntitySpace space, String name) {
+ return generateTopLevelEntityName(space, Optional.of(name));
}
private String generateTopLevelEntityName(LlvmCompilerTopLevelEntitySpace space) {
+ return generateTopLevelEntityName(space, Optional.empty());
+ }
+
+ private String generateTopLevelEntityName(
+ LlvmCompilerTopLevelEntitySpace space,
+ Optional<String> name
+ ) {
return NameAllocator.generateName(
topLevelEntitiesByName::containsKey,
"shed__" + space,
- Optional.empty()
+ name
);
}
@@ -146,4 +161,15 @@ public record LlvmCompilerContext(
public <T> LlvmCompilerResult<T> toResult(T value) {
return new LlvmCompilerResult<>(value, this);
}
+
+ public LlvmCompilerContext enterFunction() {
+ return new LlvmCompilerContext(
+ typeInfo,
+ Empty.stack(),
+ Empty.map(),
+ Empty.vector(),
+ topLevelEntitiesByName,
+ NameAllocator.empty()
+ );
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTopLevelEntitySpace.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTopLevelEntitySpace.java
index 7ca7a06b..87b0a60b 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTopLevelEntitySpace.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerTopLevelEntitySpace.java
@@ -1,6 +1,7 @@
package org.shedlang.compiler.backends.llvm;
public enum LlvmCompilerTopLevelEntitySpace {
+ FUNCTION("fun"),
STRING("string");
private final String name;
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmTopLevelEntity.java b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmTopLevelEntity.java
index 86b3efc3..b1cabfa0 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmTopLevelEntity.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/ir/ast/LlvmTopLevelEntity.java
@@ -1,4 +1,5 @@
package org.shedlang.compiler.backends.llvm.ir.ast;
public sealed interface LlvmTopLevelEntity permits LlvmFunctionDefinition, LlvmGlobalDefinition {
+ String name();
}