package org.shedlang.compiler.shid; import org.junit.jupiter.api.Test; import org.shedlang.compiler.ast.typed.Typed; import org.shedlang.compiler.ast.typed.TypedFunctionExpressionNode; import org.shedlang.compiler.shid.instructions.ShidDefineFunction; import org.shedlang.compiler.types.Types; import static org.shedlang.compiler.shid.instructions.ShidMatchers.*; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.*; public class ShidCodeGenFunctionExpressionTests { @Test public void functionIsCompiledToDefineFunctionInstruction() { var node = TypedFunctionExpressionNode.builder() .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) .addFreeVariable("z") .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) .build(); var context = ShidCodeGen.Context.EMPTY .addShedVal("f") .addShedVal("z"); var result = ShidCodeGen.compileExpression(node, context); assertThat(result.instructions(), isSequence( instanceOf( ShidDefineFunction.class, has("name", x -> x.name(), equalTo("anonymous")), has("positionalParams", x -> x.positionalParams(), isSequence( isShidDefineFunctionParam("x__0") )), has("namedParams", x -> x.namedParams(), isSequence( isShidDefineFunctionParam("y__0") )), has("freeVariables", x -> x.freeVariables(), containsExactly( has("name", x -> x.name(), equalTo("z__0")) )), has("body", x -> x.body(), isShidBlock(isSequence( isShidPushString("hello"), isShidDiscard(), isShidPushUnit(), isShidReturn() ))) ) )); } @Test public void whenLastStatementIsBlockReturnThenThatValueIsReturned() { var node = TypedFunctionExpressionNode.builder() .addStatement(Typed.blockReturn(Typed.stringLiteral("hello"))) .build(); var context = ShidCodeGen.Context.EMPTY .addShedVal("f"); var result = ShidCodeGen.compileExpression(node, context); assertThat(result.instructions(), isSequence( instanceOf( ShidDefineFunction.class, has("body", x -> x.body(), isShidBlock(isSequence( isShidPushString("hello"), isShidReturn() ))) ) )); } }