aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-10-28 23:59:56 +0100
committerMichael Williamson <mike@zwobble.org>2023-10-28 23:59:56 +0100
commit186407bd0ecf485f7197027afd04c8c12e5920ce (patch)
tree010a68a4ea8c7672643924d63c3a9fd1d6b83e3e /src/main/java
parentba87d647e68a52f92dc859008f0ed20fe72659a0 (diff)
Compile expressions to stack IR
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java9
-rw-r--r--src/main/java/org/shedlang/compiler/stackir/StackCompiler.java67
2 files changed, 49 insertions, 27 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java
index 0f8ad4bc..1bc46fdb 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedFunctionExpressionNode.java
@@ -44,15 +44,6 @@ public record TypedFunctionExpressionNode(
);
}
- public Builder withName(String name) {
- return new Builder(
- this.signature,
- this.freeVariables,
- this.boundVariableNames,
- this.body
- );
- }
-
public Builder addPositionalParam(String name, TypedTypeLevelExpressionNode<Type> type) {
return new Builder(
this.signature.addPositionalParam(name, type),
diff --git a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
index bb138c84..8d1468c8 100644
--- a/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
+++ b/src/main/java/org/shedlang/compiler/stackir/StackCompiler.java
@@ -3,6 +3,7 @@ package org.shedlang.compiler.stackir;
import org.pcollections.*;
import org.shedlang.compiler.ShedBuiltins;
import org.shedlang.compiler.ast.typed.*;
+import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.stackir.instructions.*;
import org.shedlang.compiler.types.*;
import org.shedlang.compiler.util.Iterables;
@@ -128,7 +129,7 @@ public class StackCompiler {
compileFieldAccess(typedFieldAccessNode, context);
case TypedFunctionExpressionNode typedFunctionExpressionNode ->
- throw new UnsupportedOperationException("TODO");
+ compileFunctionExpression(typedFunctionExpressionNode, context);
case TypedIfNode typedIfNode ->
compileIf(typedIfNode, context);
@@ -184,47 +185,50 @@ public class StackCompiler {
return context;
}
- private static Context compileFunctionDefinition(
- TypedFunctionDefinitionNode node,
+ private static Context compileFunction(
+ String name,
+ TypedFunctionSignatureNode signature,
+ TypedFunctionBodyNode body,
+ Source source,
Context context
) {
- context = context.enterBlock(node.body().boundVariableNames());
+ context = context.enterBlock(body.boundVariableNames());
var c = context;
- var positionalParams = node.signature().params().positional().stream()
+ var positionalParams = signature.params().positional().stream()
.map(param -> new DefineFunctionInstruction.Param(
c.shedVariableToLocal(param.name()),
param.source()
))
.toList();
- var namedParams = node.signature().params().named().stream()
+ var namedParams = signature.params().named().stream()
.map(param -> new DefineFunctionInstruction.Param(
c.shedVariableToLocal(param.name()),
param.source()
))
.toList();
- context = compileBlockWithYield(node.body().block(), context);
+ context = compileBlockWithYield(body.block(), context);
- switch (node.body().behaviour()) {
+ switch (body.behaviour()) {
case TypedFunctionStatementBehaviour.BlockReturn blockReturn -> {
- context = context.addInstruction(new ReturnInstruction(node.source()));
+ context = context.addInstruction(new ReturnInstruction(body.source()));
}
case TypedFunctionStatementBehaviour.Continue continue_ -> {
- context = context.addInstruction(new ReturnInstruction(node.source()));
+ context = context.addInstruction(new ReturnInstruction(body.source()));
}
case TypedFunctionStatementBehaviour.Terminate terminate -> {
}
}
- var body = context.instructions;
+ var bodyInstructions = context.instructions;
context = context.exitBlock();
var freeVariables = FreeVariables.builder();
- for (var shedFreeVariable : node.body().freeVariables()) {
+ for (var shedFreeVariable : body.freeVariables()) {
var freeVariableLocalName = context.shedVariableToLocal(shedFreeVariable.name());
for (var freeVariableSource : shedFreeVariable.referenceSources()) {
freeVariables = freeVariables.plus(
@@ -235,20 +239,47 @@ public class StackCompiler {
}
var defineFunctionInstruction = new DefineFunctionInstruction(
- node.name(),
+ name,
positionalParams,
namedParams,
freeVariables.build(),
- body,
- node.source()
+ bodyInstructions,
+ source
+ );
+
+ return context.addInstruction(defineFunctionInstruction);
+ }
+
+ private static Context compileFunctionDefinition(
+ TypedFunctionDefinitionNode node,
+ Context context
+ ) {
+ context = compileFunction(
+ node.name(),
+ node.signature(),
+ node.body(),
+ node.source(),
+ context
);
var localName = context.shedVariableToLocal(node.name());
var storeInstruction = new LocalStoreInstruction(localName, node.source());
- return context
- .addInstruction(defineFunctionInstruction)
- .addInstruction(storeInstruction);
+ return context.addInstruction(storeInstruction);
+ }
+
+ private static Context compileFunctionExpression(
+ TypedFunctionExpressionNode node,
+ Context context
+ ) {
+ return compileFunction(
+ // TODO: include source location?
+ "anonymous",
+ node.signature(),
+ node.body(),
+ node.source(),
+ context
+ );
}
private static Context compileFunctionReturn(