From 2cefa82d059dfd16d224b16f92fd69104beb24a2 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 10 Jun 2023 11:52:04 +0100 Subject: Compile calls to stack instructions --- .../shedlang/compiler/stackir/StackCompiler.java | 48 ++++++++++++++++------ .../stackir/instructions/CallInstruction.java | 12 ++++++ .../compiler/stackir/instructions/Instruction.java | 3 +- src/main/java/org/shedlang/compiler/util/P.java | 8 ++++ 4 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java index 1d6b0a88..c16674e0 100644 --- a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java +++ b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java @@ -1,25 +1,49 @@ package org.shedlang.compiler.stackir; +import org.pcollections.PVector; import org.shedlang.compiler.ast.typed.*; import org.shedlang.compiler.stackir.instructions.*; - -import java.util.List; +import org.shedlang.compiler.util.P; public class StackCompiler { private StackCompiler() { } - private static List compileBoolLiteral(TypedBoolLiteralNode node) { - return List.of(new PushBoolInstruction(node.value(), node.source())); + private static PVector compileBoolLiteral(TypedBoolLiteralNode node) { + return P.vector(new PushBoolInstruction(node.value(), node.source())); + } + + private static PVector compileCall(TypedCallNode node) { + var instructions = compileExpression(node.receiver()); + + instructions = node.args().positional().stream() + .map(arg -> compileExpression(arg)) + .reduce(instructions, PVector::plusAll); + + instructions = node.args().named().stream() + .map(arg -> compileExpression(arg.expression())) + .reduce(instructions, PVector::plusAll); + + var callInstruction = new CallInstruction( + node.args().positional().size(), + node.args().named().stream() + .map(arg -> arg.name()) + .toList(), + node.source() + ); + + instructions = instructions.plus(callInstruction); + + return instructions; } - public static List compileExpression(TypedExpressionNode node) { + public static PVector compileExpression(TypedExpressionNode node) { return switch (node) { case TypedBoolLiteralNode typedBoolLiteralNode -> compileBoolLiteral(typedBoolLiteralNode); case TypedCallNode typedCallNode -> - throw new UnsupportedOperationException("TODO"); + compileCall(typedCallNode); case TypedIntLiteralNode typedIntLiteralNode -> compileIntLiteral(typedIntLiteralNode); @@ -32,15 +56,15 @@ public class StackCompiler { }; } - private static List compileIntLiteral(TypedIntLiteralNode node) { - return List.of(new PushIntInstruction(node.value(), node.source())); + private static PVector compileIntLiteral(TypedIntLiteralNode node) { + return P.vector(new PushIntInstruction(node.value(), node.source())); } - private static List compileReference(TypedReferenceNode node) { - return List.of(new LocalLoadInstruction(node.name(), node.source())); + private static PVector compileReference(TypedReferenceNode node) { + return P.vector(new LocalLoadInstruction(node.name(), node.source())); } - private static List compileStringLiteral(TypedStringLiteralNode node) { - return List.of(new PushStringInstruction(node.value(), node.source())); + private static PVector compileStringLiteral(TypedStringLiteralNode node) { + return P.vector(new PushStringInstruction(node.value(), node.source())); } } diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java new file mode 100644 index 00000000..1cdfa9d5 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java @@ -0,0 +1,12 @@ +package org.shedlang.compiler.stackir.instructions; + +import org.shedlang.compiler.sources.Source; + +import java.util.List; + +public record CallInstruction( + int argCount, + List namedArgs, + Source source +) implements Instruction { +} diff --git a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java index 59af2b9b..33007bf2 100644 --- a/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java +++ b/src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java @@ -1,4 +1,5 @@ package org.shedlang.compiler.stackir.instructions; -public sealed interface Instruction permits LocalLoadInstruction, LocalStoreInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction { +public sealed interface Instruction + permits CallInstruction, LocalLoadInstruction, LocalStoreInstruction, PushBoolInstruction, PushIntInstruction, PushStringInstruction { } diff --git a/src/main/java/org/shedlang/compiler/util/P.java b/src/main/java/org/shedlang/compiler/util/P.java index 7ce8232c..a09d7940 100644 --- a/src/main/java/org/shedlang/compiler/util/P.java +++ b/src/main/java/org/shedlang/compiler/util/P.java @@ -2,7 +2,10 @@ package org.shedlang.compiler.util; import org.pcollections.HashTreePMap; import org.pcollections.PMap; +import org.pcollections.PVector; +import org.pcollections.TreePVector; +import java.util.Arrays; import java.util.Map; public class P { @@ -17,4 +20,9 @@ public class P { } return map; } + + @SafeVarargs + public static PVector vector(T... values) { + return TreePVector.from(Arrays.asList(values)); + } } -- cgit v1.2.3