aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/StackCompiler.java48
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/CallInstruction.java12
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/instructions/Instruction.java3
-rw-r--r--src/main/java/org/shedlang/compiler/util/P.java8
4 files changed, 58 insertions, 13 deletions
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<Instruction> compileBoolLiteral(TypedBoolLiteralNode node) {
- return List.of(new PushBoolInstruction(node.value(), node.source()));
+ private static PVector<Instruction> compileBoolLiteral(TypedBoolLiteralNode node) {
+ return P.vector(new PushBoolInstruction(node.value(), node.source()));
+ }
+
+ private static PVector<Instruction> 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<Instruction> compileExpression(TypedExpressionNode node) {
+ public static PVector<Instruction> 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<Instruction> compileIntLiteral(TypedIntLiteralNode node) {
- return List.of(new PushIntInstruction(node.value(), node.source()));
+ private static PVector<Instruction> compileIntLiteral(TypedIntLiteralNode node) {
+ return P.vector(new PushIntInstruction(node.value(), node.source()));
}
- private static List<Instruction> compileReference(TypedReferenceNode node) {
- return List.of(new LocalLoadInstruction(node.name(), node.source()));
+ private static PVector<Instruction> compileReference(TypedReferenceNode node) {
+ return P.vector(new LocalLoadInstruction(node.name(), node.source()));
}
- private static List<Instruction> compileStringLiteral(TypedStringLiteralNode node) {
- return List.of(new PushStringInstruction(node.value(), node.source()));
+ private static PVector<Instruction> 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<String> 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 <T> PVector<T> vector(T... values) {
+ return TreePVector.from(Arrays.asList(values));
+ }
}