From 0cf3c519c2b834c1d5709e1e98be54cd98b90eb9 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 10 Jun 2023 20:50:15 +0100 Subject: Add serialization for instructions --- .../stackir/InstructionSerializerTests.java | 123 +++++++++++++++++++++ .../stackir/instructions/InstructionMatchers.java | 9 +- .../stackir/instructions/Instructions.java | 47 ++++++++ 3 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java create mode 100644 src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java new file mode 100644 index 00000000..d3512869 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/InstructionSerializerTests.java @@ -0,0 +1,123 @@ +package org.shedlang.compiler.stackir; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.sources.Sources; +import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; +import org.shedlang.compiler.stackir.instructions.Instruction; +import org.shedlang.compiler.stackir.instructions.Instructions; + +import java.util.List; + +import static org.shedlang.compiler.util.Sets.orderedSetOf; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; + +public class InstructionSerializerTests { + @Test + public void canSerializeCall() { + var instruction = Instructions.call(1, List.of("x", "y")); + + var string = serialize(instruction); + + assertThat(string, equalTo("(call positionalArgCount=1 namedArgNames=(\"x\" \"y\"))")); + } + + @Test + public void canSerializeDefineFunction() { + // TODO: make a builder + var instruction = new DefineFunctionInstruction( + "f", + List.of(Instructions.param("p1"), Instructions.param("p2")), + List.of(Instructions.param("n1"), Instructions.param("n2")), + orderedSetOf("fv1", "fv2"), + List.of( + Instructions.pushBool(true), + Instructions.pushBool(false) + ), + Sources.NULL + ); + + var string = serialize(instruction); + + assertThat(string, equalTo(""" + ( + define-function + positionalParams=("p1" "p2") + namedParams=("n1" "n2") + freeVariables=("fv1" "fv2") + body=( + (push-bool true) + (push-bool false) + ) + )""")); + } + + @Test + public void canSerializeDiscard() { + var instruction = Instructions.discard(); + + var string = serialize(instruction); + + assertThat(string, equalTo("(discard)")); + } + + @Test + public void canSerializeLocalLoad() { + var instruction = Instructions.localLoad("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(local-load \"x\")")); + } + + @Test + public void canSerializeLocalStore() { + var instruction = Instructions.localStore("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(local-store \"x\")")); + } + + @Test + public void canSerializeModuleExport() { + var instruction = Instructions.moduleExport("x"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(module-export \"x\")")); + } + + @Test + public void canSerializePushBool() { + var instruction = Instructions.pushBool(true); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-bool true)")); + } + + @Test + public void canSerializePushInt() { + var instruction = Instructions.pushInt(42); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-int 42)")); + } + + @Test + public void canSerializePushString() { + var instruction = Instructions.pushString("hello"); + + var string = serialize(instruction); + + assertThat(string, equalTo("(push-string \"hello\")")); + } + + private String serialize(Instruction instruction) { + var builder = new StringBuilder(); + InstructionSerializer.serialize(instruction, builder); + return builder.toString(); + } +} 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 99fc7d5b..bfac50ce 100644 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java +++ b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java @@ -11,11 +11,14 @@ public class InstructionMatchers { private InstructionMatchers() { } - public static Matcher isCallInstruction(int argCount, List namedArgs) { + public static Matcher isCallInstruction( + int positionalArgCount, + List namedArgNames + ) { return instanceOf( CallInstruction.class, - has("argCount", x -> x.argCount(), equalTo(argCount)), - has("namedArgs", x -> x.namedArgs(), equalTo(namedArgs)) + has("positionalArgCount", x -> x.positionalArgCount(), equalTo(positionalArgCount)), + has("namedArgNames", x -> x.namedArgNames(), equalTo(namedArgNames)) ); } diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java new file mode 100644 index 00000000..ba55e28a --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/instructions/Instructions.java @@ -0,0 +1,47 @@ +package org.shedlang.compiler.stackir.instructions; + +import org.shedlang.compiler.sources.Sources; + +import java.math.BigInteger; +import java.util.List; + +public class Instructions { + private Instructions() { + } + + public static Instruction call(int positionalArgCount, List namedArgNames) { + return new CallInstruction(positionalArgCount, namedArgNames, Sources.NULL); + } + + public static Instruction discard() { + return new DiscardInstruction(Sources.NULL); + } + + public static Instruction localLoad(String name) { + return new LocalLoadInstruction(name, Sources.NULL); + } + + public static Instruction localStore(String name) { + return new LocalStoreInstruction(name, Sources.NULL); + } + + public static Instruction moduleExport(String name) { + return new ModuleExportInstruction(name, Sources.NULL); + } + + public static DefineFunctionInstruction.Param param(String name) { + return new DefineFunctionInstruction.Param(name, Sources.NULL); + } + + public static Instruction pushBool(boolean value) { + return new PushBoolInstruction(value, Sources.NULL); + } + + public static Instruction pushInt(int value) { + return new PushIntInstruction(BigInteger.valueOf(value), Sources.NULL); + } + + public static Instruction pushString(String value) { + return new PushStringInstruction(value, Sources.NULL); + } +} -- cgit v1.2.3