From 49aee72f35f1ffdfc90a89162a500193746ef467 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 28 Sep 2023 14:07:01 +0100 Subject: Generate stack IR for field accesses --- .../org/shedlang/compiler/ast/typed/Typed.java | 8 ++++++ .../stackir/StackCompilerFieldAccessTests.java | 32 ++++++++++++++++++++++ .../stackir/instructions/InstructionMatchers.java | 22 +++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java index 42a46859..110696a7 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java @@ -65,6 +65,14 @@ public class Typed { return new TypedExpressionStatementNode(expression, Sources.NULL); } + public static TypedFieldAccessNode fieldAccess( + TypedExpressionNode receiver, + String fieldName, + Type type + ) { + return new TypedFieldAccessNode(receiver, fieldName, type, Sources.NULL); + } + public static TypedFunctionReturnNode functionReturn(TypedExpressionNode expression) { return new TypedFunctionReturnNode(expression, Sources.NULL); } diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java new file mode 100644 index 00000000..a9d76db3 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFieldAccessTests.java @@ -0,0 +1,32 @@ +package org.shedlang.compiler.stackir; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isFieldLoadInstruction; +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isLocalLoadInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class StackCompilerFieldAccessTests { + @Test + public void structFieldAccessIsCompiledToFieldLoad() { + var structType = Types.struct(NamespaceName.of("Example", "Project"), "User"); + var node = Typed.fieldAccess( + Typed.reference("user", structType), + "name", + Types.STRING + ); + var context = StackCompiler.Context.EMPTY + .addShedVariable("user"); + + var result = StackCompiler.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("user__0"), + isFieldLoadInstruction(structType, "name") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java index b50e4903..3d1689e1 100644 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java +++ b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java @@ -1,6 +1,7 @@ package org.shedlang.compiler.stackir.instructions; import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.StructType; import org.zwobble.precisely.Matcher; import java.math.BigInteger; @@ -37,6 +38,27 @@ public class InstructionMatchers { return instanceOf(DuplicateInstruction.class); } + public static Matcher isFieldLoadInstruction( + FieldLoadInstruction.Receiver receiver, + String fieldName + ) { + return instanceOf( + FieldLoadInstruction.class, + has("receiver", x -> x.receiver(), equalTo(receiver)), + has("fieldName", x -> x.fieldName(), equalTo(fieldName)) + ); + } + + public static Matcher isFieldLoadInstruction( + StructType receiverType, + String fieldName + ) { + return isFieldLoadInstruction( + new FieldLoadInstruction.Receiver.Struct(receiverType), + fieldName + ); + } + public static Matcher isIfInstruction( Matcher> trueBody, Matcher> falseBody -- cgit v1.2.3