aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org/shedlang/compiler/shid/ShidCodeGenTryTests.java
blob: c155eb4d1b0110d78bab44a73bc0c12c8ac6d808 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package org.shedlang.compiler.shid;

import org.junit.jupiter.api.Test;
import org.shedlang.compiler.ast.typed.Typed;
import org.shedlang.compiler.ast.typed.TypedTryHandlerMethodNode;
import org.shedlang.compiler.ast.typed.TypedTryNode;
import org.shedlang.compiler.shid.instructions.ShidDefineFunction;
import org.shedlang.compiler.shid.instructions.ShidTry;
import org.shedlang.compiler.types.Effects;
import org.shedlang.compiler.types.NamespaceName;

import static org.shedlang.compiler.shid.instructions.ShidMatchers.isShidBlock;
import static org.shedlang.compiler.shid.instructions.ShidMatchers.isShidPushInt;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.*;

public class ShidCodeGenTryTests {
    @Test
    public void tryNodeIsCompiledToTryInstruction() {
        var effect = Effects.userDefined(NamespaceName.of("Example"), "State");
        var node = TypedTryNode.builder()
            .addBodyStatement(
                Typed.blockReturn(Typed.intLiteral(42))
            )
            .withHandledEffect(Typed.typeLevelReference("State", effect))
            .addHandlerMethod(
                TypedTryHandlerMethodNode.builder()
                    .withName("read")
                    .build()
            )
            .addHandlerMethod(
                TypedTryHandlerMethodNode.builder()
                    .withName("write")
                    .build()
            )
            .build();
        var context = ShidCodeGen.Context.EMPTY
            .addShedVal("c");

        var result = ShidCodeGen.compileExpression(node, context);

        assertThat(result.instructions(), isSequence(
            instanceOf(
                ShidDefineFunction.class,
                has("name", x -> x.name(), equalTo("read"))
            ),
            instanceOf(
                ShidDefineFunction.class,
                has("name", x -> x.name(), equalTo("write"))
            ),
            instanceOf(
                ShidTry.class,
                has("handledEffect", x -> x.handledEffect(), equalTo(effect)),
                has("handlerMethodNames", x -> x.handlerMethodNames(), isSequence(
                    equalTo("read"),
                    equalTo("write")
                )),
                has("body", x -> x.body(), isShidBlock(isSequence(
                    isShidPushInt(42)
                )))
            )
        ));
    }
}