public void CodeGenerator_ShouldFillInAddressOfFunctionCallCorrectly_InObjectCode() { // Arrange var tacs = new Tacs { Tac.Init(0), Tac.BeginCall("main", 0, "t0"), Tac.Call("main", "t0"), Tac.BeginFunc("main", 0), Tac.EndFunc("main") }; // Act var output = new CodeGenerator().Generate(tacs); // Assert // jump to function is like this // 10: LDA 7, 18(0) ; jump to function // where the jump is too address 18 var jumpLineNumber = Regex.Match(output, @"LDA 7, (\d+)\(0\)").Groups[1].Value; // the beginning of the function looks like this: // * BeginFunc 'main' // 18: ST 2, -9(6) ; store result of function r2, in result postion in stack frame // so want to find the linenumber after the begin function comment var functionLineNumber = Regex.Match(output, @"\* BeginFunc 'main'\r\n(\d+):").Groups[1].Value; Assert.That(jumpLineNumber, Is.EqualTo(functionLineNumber)); }
public void TestStackFrameArguments2_ArgumentsToTheFunctionCallShouldBeStoredInTheStackFrame_AndBeAvailableWithinTheFunction() { // Arrange var tacs = new Tacs() { Tac.Init(0), Tac.Assign("13", "t0"), Tac.Assign("17", "t1"), Tac.Assign("23", "t2"), Tac.BeginCall("print", 3, "t4"), Tac.Param("t0"), Tac.Param("t1"), Tac.Param("t2"), Tac.Call("print", "t4"), Tac.Halt(), Tac.BeginFunc("print", 3), Tac.PrintVariable("arg0"), Tac.PrintVariable("arg1"), Tac.PrintVariable("arg2"), Tac.EndFunc("print") }; var output = new CodeGenerator().Generate(tacs); // Act var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // Assert Assert.That(tinyOut, Is.EqualTo(new[] { "13", "17", "23" }), tinyOut.ToString()); }
public void TestStackFrameRegisterState_WhenReturningFromAFunctionCall_TheRegistersShouldBeRestoredToTheirPreCallValues() { // Arrange var tacs = new Tacs { Tac.Init(0), Tac.SetRegisterValue(1, 11), Tac.SetRegisterValue(2, 11), Tac.SetRegisterValue(3, 11), Tac.SetRegisterValue(4, 11), Tac.SetRegisterValue(5, 11), Tac.SetRegisterValue(6, 11), Tac.BeginCall("main", 0, "t0"), Tac.Call("main", "t0"), Tac.PrintRegisters(), Tac.Halt(), Tac.BeginFunc("main", 0), Tac.SetRegisterValue(1, 22), Tac.SetRegisterValue(2, 22), Tac.SetRegisterValue(3, 22), Tac.SetRegisterValue(4, 22), Tac.SetRegisterValue(5, 22), // cant mess with r6 because this is the stack pointer Tac.EndFunc("main") }; var output = new CodeGenerator().Generate(tacs); // Act var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // Assert Assert.That(tinyOut, Is.EqualTo(new[] { "0", "11", "11", "11", "11", "11", "11" }), tinyOut.ToString()); }
public void CodeGenerator_ShouldFillInAddressOfLabelsCorrectly() { // Arrange var tacs = new Tacs() { Tac.Init(0), Tac.Goto("label0"), Tac.PrintValue(1), Tac.Label("label0", null), Tac.PrintValue(2), Tac.Halt() }; var output = new CodeGenerator().Generate(tacs); // Act var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // Assert Assert.That(tinyOut, Is.EqualTo(new[] { "2" }), tinyOut.ToString()); }
public void TestStackFrameCommandLineArguments_TheInitialStackFrameIsSetUp_SoThatCommandLineArguments_FallInTheArgumentSlotsOfTheInitalStackFrame() { // Arrange var tacs = new Tacs() { Tac.Init(3), Tac.BeginCall("main", 3, "t0"), Tac.Param("arg0"), Tac.Param("arg1"), Tac.Param("arg2"), Tac.Call("main", "t0"), Tac.BeginCall("print", 1, "t1"), Tac.Param("t0"), Tac.Call("print", "t1"), Tac.Halt(), Tac.BeginFunc("print", 1), Tac.PrintVariable("arg0"), Tac.EndFunc("print"), Tac.BeginFunc("main", 3), Tac.PrintVariable("arg0"), Tac.PrintVariable("arg1"), Tac.PrintVariable("arg2"), Tac.Assign("13", "t0"), Tac.Return("t0"), Tac.EndFunc("main") }; var output = new CodeGenerator().Generate(tacs); // Act var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output, "29 31 37"); // Assert Assert.That(tinyOut, Is.EqualTo(new[] { "29", "31", "37", "13" }), tinyOut.ToString()); }
public void TestStackFrameReturnAddress_WhenFunctionIsCalled_ExecutionShouldJumpToTheFunction_WhenFunctionFinishes_ExectionShouldReturn() { // Arrange var tacs = new Tacs { Tac.Init(0), Tac.PrintValue(1), Tac.BeginCall("main", 0, "t0"), Tac.Call("main", "t0"), Tac.PrintValue(2), Tac.Halt(), Tac.BeginFunc("main", 0), Tac.PrintValue(3), Tac.EndFunc("main") }; var output = new CodeGenerator().Generate(tacs); // Act var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // Assert Assert.That(tinyOut, Is.EqualTo(new[] { "1", "3", "2" })); }
public void TestStackFrameReturnValue_TheValueReturnedFromTheFunction_ShouldBeStoredInTheStackFrame_AnIsAutomaticallyAssignedToTheReturnVariable() { // Arrange var tacs = new Tacs() { Tac.Init(0), Tac.BeginCall("returnthirteen", 0, "t0"), Tac.Call("returnthirteen", "t0"), Tac.PrintVariable("t0"), Tac.Halt(), Tac.BeginFunc("returnthirteen", 0), Tac.Assign("13", "t0"), Tac.Return("t0"), Tac.EndFunc("returnthirteen") }; var output = new CodeGenerator().Generate(tacs); // Act var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // Assert Assert.That(tinyOut, Is.EqualTo(new[] { "13" }), tinyOut.ToString()); }