aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/shedlang/compiler/stackir
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-09 12:20:13 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-09 12:20:13 +0100
commite87797aff31cd99a6a08e46cb52aff61e1c7d75d (patch)
treefd437278318272bbf0deeb027f457f9106b141d7 /src/main/java/org/shedlang/compiler/stackir
parent85be56d890f100b72dde8e011d7421e597888363 (diff)
Handle block returns properly
Diffstat (limited to 'src/main/java/org/shedlang/compiler/stackir')
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/StackCompiler.java28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
index d3b8801c..a8bc9d45 100644
--- a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
+++ b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
@@ -4,6 +4,7 @@ import org.pcollections.PVector;
import org.shedlang.compiler.ShedBuiltins;
import org.shedlang.compiler.ast.typed.*;
import org.shedlang.compiler.stackir.instructions.*;
+import org.shedlang.compiler.util.Lists;
import org.shedlang.compiler.util.P;
import java.util.stream.Collectors;
@@ -29,6 +30,10 @@ public class StackCompiler {
});
}
+ private static PVector<Instruction> compileBlockReturn(TypedBlockReturnNode blockReturn) {
+ return compileExpression(blockReturn.expression());
+ }
+
private static PVector<Instruction> compileBoolLiteral(TypedBoolLiteralNode node) {
return P.vector(new PushBoolInstruction(node.value(), node.source()));
}
@@ -96,8 +101,24 @@ public class StackCompiler {
.flatMap(statement -> compileFunctionStatement(statement).stream())
.collect(Collectors.toList());
- body.add(new PushUnitInstruction(node.source()));
- body.add(new ReturnInstruction(node.source()));
+ var lastStatement = Lists.last(node.body());
+ // TODO: remove duplication with type checker (default to none behaviour).
+ // Extract block node?
+ var lastStatementBehaviour = lastStatement
+ .map(statement -> statement.behaviour())
+ .orElse(TypedFunctionStatementBehaviour.NONE);
+
+ switch (lastStatementBehaviour) {
+ case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> {
+ body.add(new ReturnInstruction(node.source()));
+ }
+ case TypedFunctionStatementBehaviour.None none -> {
+ body.add(new PushUnitInstruction(node.source()));
+ body.add(new ReturnInstruction(node.source()));
+ }
+ case TypedFunctionStatementBehaviour.Terminate terminate -> {
+ }
+ }
var defineFunctionInstruction = new DefineFunctionInstruction(
node.name(),
@@ -120,6 +141,9 @@ public class StackCompiler {
public static PVector<Instruction> compileFunctionStatement(TypedFunctionStatementNode node) {
return switch (node) {
+ case TypedBlockReturnNode blockReturn ->
+ compileBlockReturn(blockReturn);
+
case TypedExpressionStatementNode expressionStatement ->
compileExpressionStatement(expressionStatement);