From 186407bd0ecf485f7197027afd04c8c12e5920ce Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 28 Oct 2023 23:59:56 +0100 Subject: Compile expressions to stack IR --- .../ast/typed/TypedFunctionExpressionNode.java | 9 --- .../shedlang/compiler/stackir/StackCompiler.java | 67 ++++++++++++++++------ 2 files changed, 49 insertions(+), 27 deletions(-) (limited to 'src/main/java') 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) { 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( -- cgit v1.2.3