package org.shedlang.compiler.shid; import org.junit.jupiter.api.Test; import org.shedlang.compiler.ast.typed.Typed; import org.shedlang.compiler.types.FunctionType; import org.shedlang.compiler.types.NamespaceName; import org.shedlang.compiler.types.TypeParam; 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 ShidCodeGenCallTests { @Test public void callIsCompiledToInstructionsForOperandThenCall() { var node = Typed.call( Typed.reference("f"), List.of( Typed.stringLiteral("p1"), Typed.stringLiteral("p2") ), List.of( Typed.namedArg("x2", Typed.stringLiteral("n2")), Typed.namedArg("x1", Typed.stringLiteral("n1")) ) ); var context = ShidCodeGen.Context.EMPTY .addShedVal("f"); var result = ShidCodeGen.compileExpression(node, context); assertThat(result.instructions(), isSequence( isShidLocalLoad("f__0"), isShidPushString("p1"), isShidPushString("p2"), isShidPushString("n2"), isShidPushString("n1"), isShidCall(2, List.of("x2", "x1")) )); } @Test public void nativeTypeMethodCallIsCompiledToDirectCallWithoutMethodReference() { var namespaceName = NamespaceName.of("Example", "Project"); var nativeType = Types.nativeType(namespaceName, "Array"); var node = Typed.call( Typed.methodAccess( Typed.reference("x", nativeType), "f", FunctionType.builder().build() ), List.of( Typed.stringLiteral("p1"), Typed.stringLiteral("p2") ), List.of( Typed.namedArg("x2", Typed.stringLiteral("n2")), Typed.namedArg("x1", Typed.stringLiteral("n1")) ) ); var context = ShidCodeGen.Context.EMPTY .addShedVal("x"); var result = ShidCodeGen.compileExpression(node, context); assertThat(result.instructions(), isSequence( isShidMethodLoad(nativeType, "f"), isShidLocalLoad("x__0"), isShidPushString("p1"), isShidPushString("p2"), isShidPushString("n2"), isShidPushString("n1"), isShidCall(3, List.of("x2", "x1")) )); } @Test public void structMethodCallIsCompiledToDirectCallWithoutMethodReference() { var namespaceName = NamespaceName.of("Example", "Project"); var structType = Types.struct(namespaceName, "User"); var node = Typed.call( Typed.methodAccess( Typed.reference("x", structType), "f", FunctionType.builder().build() ), List.of( Typed.stringLiteral("p1"), Typed.stringLiteral("p2") ), List.of( Typed.namedArg("x2", Typed.stringLiteral("n2")), Typed.namedArg("x1", Typed.stringLiteral("n1")) ) ); var context = ShidCodeGen.Context.EMPTY .addShedVal("x"); var result = ShidCodeGen.compileExpression(node, context); assertThat(result.instructions(), isSequence( isShidMethodLoad(structType, "f"), isShidLocalLoad("x__0"), isShidPushString("p1"), isShidPushString("p2"), isShidPushString("n2"), isShidPushString("n1"), isShidCall(3, List.of("x2", "x1")) )); } @Test public void constructedTypeMethodCallIsCompiledToDirectCallWithoutMethodReference() { var namespaceName = NamespaceName.of("Example", "Project"); var simpleStructType = Types.struct(namespaceName, "User"); var structType = Types.constructedStructType( Types.typeConstructor( List.of( TypeParam.forStructType(simpleStructType, "T") ), simpleStructType ), List.of(Types.INT) ); var node = Typed.call( Typed.methodAccess( Typed.reference("x", structType), "f", FunctionType.builder().build() ), List.of( Typed.stringLiteral("p1"), Typed.stringLiteral("p2") ), List.of( Typed.namedArg("x2", Typed.stringLiteral("n2")), Typed.namedArg("x1", Typed.stringLiteral("n1")) ) ); var context = ShidCodeGen.Context.EMPTY .addShedVal("x"); var result = ShidCodeGen.compileExpression(node, context); assertThat(result.instructions(), isSequence( isShidMethodLoad(simpleStructType, "f"), isShidLocalLoad("x__0"), isShidPushString("p1"), isShidPushString("p2"), isShidPushString("n2"), isShidPushString("n1"), isShidCall(3, List.of("x2", "x1")) )); } }