diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-06-16 20:20:18 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-06-16 20:20:18 +0100 |
| commit | 778488f6a51227d42e06df0c3188df98c6938f77 (patch) | |
| tree | 6a1d8734bd7b28b3044340e5a019165d9dab8d1b /src/main/java | |
| parent | 57446428f678ebc2bc5ad34d04e41feabe35d28f (diff) | |
Include args when compiling call to LLVM IR
Diffstat (limited to 'src/main/java')
3 files changed, 77 insertions, 4 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 89cf70b7..7fc14092 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java @@ -1,10 +1,13 @@ package org.shedlang.compiler.backends.llvm; +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.*; import org.shedlang.compiler.types.NamespaceName; -import java.util.List; +import java.util.*; + +import static org.shedlang.compiler.util.Lists.reversed; public class LlvmCompiler { public static void compileNamespace(NamespaceName namespaceName, List<Instruction> instructions) { @@ -14,13 +17,36 @@ public class LlvmCompiler { public static LlvmCompilerContext compileInstruction(Instruction instruction, LlvmCompilerContext context) { return switch (instruction) { case CallInstruction call -> { + var namedArgsByName = new HashMap<String, LlvmOperand>(); + for (var argName : reversed(call.namedArgNames())) { + var argResult = context.pop(); + var arg = argResult.value(); + context = argResult.context(); + namedArgsByName.put(argName, arg); + } + var namedArgs = namedArgsByName.entrySet() + .stream().sorted(Map.Entry.comparingByKey()) + .map(x -> x.getValue()) + .toList(); + + var args = new ArrayList<LlvmOperand>(); + for (var i = 0; i < call.positionalArgCount(); i++) { + var argResult = context.pop(); + var arg = argResult.value(); + context = argResult.context(); + args.add(arg); + } + Collections.reverse(args); + args.addAll(namedArgs); + var receiverResult = context.pop(); var receiver = receiverResult.value(); context = receiverResult.context(); yield LlvmCompilerClosures.call( receiver, - context + context, + args ); } case DefineFunctionInstruction defineFunctionInstruction -> { diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java index 68f66719..a579e6a7 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java @@ -9,6 +9,7 @@ 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.ArrayList; import java.util.List; public class LlvmCompilerClosures { @@ -47,7 +48,8 @@ public class LlvmCompilerClosures { public static LlvmCompilerContext call( LlvmOperand closure, - LlvmCompilerContext context + LlvmCompilerContext context, + List<LlvmOperand> args ) { var closurePointerResult = castValueToClosurePointer(closure, context); var closurePointer = closurePointerResult.value(); @@ -67,11 +69,17 @@ public class LlvmCompilerClosures { var callTarget = callTargetResult.value(); context = callTargetResult.context(); + var fullArgs = new ArrayList<LlvmTypedOperand>(); + fullArgs.add(new LlvmTypedOperand(typeClosureEnvironmentPointer(), environmentPointer)); + for (var arg : args) { + fullArgs.add(new LlvmTypedOperand(LlvmCompilerTypes.VALUE_TYPE, arg)); + } + return context.addInstruction(new LlvmCall( callTarget, LlvmCompilerTypes.VALUE_TYPE, functionPointer, - List.of(new LlvmTypedOperand(typeClosureEnvironmentPointer(), environmentPointer)) + fullArgs )).push(callTarget); } diff --git a/src/main/java/org/shedlang/compiler/util/Lists.java b/src/main/java/org/shedlang/compiler/util/Lists.java new file mode 100644 index 00000000..20d39455 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/util/Lists.java @@ -0,0 +1,39 @@ +package org.shedlang.compiler.util; + +import java.util.Iterator; +import java.util.List; + +public class Lists { + private Lists() { + } + + public static <T> Iterable<T> reversed(List<T> list) { + return new Iterable<T>() { + @Override + public Iterator<T> iterator() { + return new ReverseIterator<>(list); + } + }; + } + + private static class ReverseIterator<T> implements Iterator<T> { + private int index; + private final List<T> list; + + private ReverseIterator(List<T> list) { + this.list = list; + this.index = list.size(); + } + + @Override + public boolean hasNext() { + return index > 0; + } + + @Override + public T next() { + index--; + return list.get(index); + } + } +} |
