package org.shedlang.compiler.shid; import org.junit.jupiter.api.Test; import org.shedlang.compiler.ast.typed.BoundVariable; import org.shedlang.compiler.ast.typed.Typed; import org.shedlang.compiler.types.Types; import java.util.List; import static org.shedlang.compiler.shid.instructions.ShidMatchers.*; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.isSequence; public class ShidCodeGenValTests { @Test public void whenValIsFunctionStatementThenExpressionIsEvaluatedAndStoredAsLocal() { var node = Typed.val("x", Typed.stringLiteral("hello")); var context = ShidCodeGen.Context.EMPTY .addShedVal("x"); var result = ShidCodeGen.compileFunctionStatement(node, context); assertThat(result.instructions(), isSequence( isShidPushString("hello"), isShidLocalStore("x__0") )); } @Test public void whenValIsNamespaceStatementThenExpressionIsEvaluatedAndStoredAsLocal() { var node = Typed.val("x", Typed.stringLiteral("hello")); var context = ShidCodeGen.Context.EMPTY .addShedVal("x"); var result = ShidCodeGen.compileNamespaceStatement(node, context); assertThat(result.instructions(), isSequence( isShidPushString("hello"), isShidLocalStore("x__0") )); } @Test public void valsInDifferentBlocksAssignToDifferentLocals() { var nodes = List.of( Typed.val("x", Typed.intLiteral(10)), Typed.expressionStatement(Typed.reference("x")), Typed.expressionStatement(Typed.if_( List.of( Typed.conditionalBranch( Typed.boolLiteral(true), Typed.block( List.of( Typed.val("x", Typed.intLiteral(11)), Typed.expressionStatement(Typed.reference("x")) ), List.of(BoundVariable.val("x")) ) ) ), Typed.block( List.of( Typed.val("x", Typed.intLiteral(12)), Typed.expressionStatement(Typed.reference("x")) ), List.of(BoundVariable.val("x")) ), Types.INT )), Typed.expressionStatement(Typed.reference("x")) ); var context = ShidCodeGen.Context.EMPTY .addShedVal("x"); for (var node : nodes) { context = ShidCodeGen.compileFunctionStatement(node, context); } assertThat(context.instructions(), isSequence( isShidPushInt(10), isShidLocalStore("x__0"), isShidLocalLoad("x__0"), isShidDiscard(), isShidPushBool(true), isShidIf( isShidBlock(isSequence( isShidPushInt(11), isShidLocalStore("x__1"), isShidLocalLoad("x__1"), isShidDiscard(), isShidPushUnit() )), isShidBlock(isSequence( isShidBlock(isSequence( isShidPushInt(12), isShidLocalStore("x__2"), isShidLocalLoad("x__2"), isShidDiscard(), isShidPushUnit() )) )) ), isShidDiscard(), isShidLocalLoad("x__0"), isShidDiscard() )); } }