public void NestedFunctionCalls_ShouldWorkCorrectly() { // Test Visit Function Call // arrange var input = @"main() : integer secondary() secondary() : integer tertiary() tertiary() : integer 17"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "17" })); }
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 And_LeftAndRightAreTrue_AndReturn1() { // arrange var input = @"main() : boolean true and true"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "1" })); }
public void Or_IfBothAreFalse_ShouldReturn0() { // arrange var input = @"main() : boolean false or false"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "0" })); }
public void Equality_IfTheNumbersAreTheSame_1_ShouldBeReturned() { // arrange var input = @"main() : boolean 2 = 2"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "1" })); }
public void AllArithmaticTogether_ShouldNestAndAll_ThatAndMiraculouslyWork() { // arrange var input = @"main(n : integer, m : integer) : integer -(n-1)/2 * (m+1)"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output, "9 11"); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "-48" })); }
public void TheValueReturnedFromMain_ShouldBeSentToStdOut() { // Tests Visit Program, Definition, Body and IntegerLiteral // arrange var input = @"main() : integer 1"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); Console.WriteLine(tacs); // assert Assert.That(tacs.ToString(), Is.EqualTo(@" Init 0 BeginCall main 0 t0 t0 := Call main BeginCall print 1 t1 Param t0 t1 := Call print Halt BeginFunc print 1 PrintVariable arg0 EndFunc print BeginFunc main 0 t0 := 1 Return t0 EndFunc main ")); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); Assert.That(tinyOut, Is.EqualTo(new[] { "1" })); }
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 Negate_ShouldNegateTheVariable() { // Tests Visit Negate // arrange var input = @"main(n : integer) : integer -n"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output, "19"); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "-19" })); }
public void PrintExpressions_ProgramShouldSendTheirValueToStdOut() { // Tests Visit Print // arrange var input = @"main() : integer print(1) 1"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "1", "1" })); }
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()); }
public void IfThenElse_IfConditionFalse_ElseBranchShouldExecute() { // arrange var input = @"main() : integer if false then 17 else 19"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); Console.WriteLine(tacs); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "19" })); }
public void ArgumentsShouldBePassedThrouh_NestedFunctionCalls() { // Tests Visit FunctionCall and Identifier // arrange var input = @"main(n : integer) : integer secondary(n) secondary(n: integer) : integer tertiary(n) tertiary(n : integer) : integer n"; var frontEnd = new FrontEnd(); var program = frontEnd.Compile(input); Assert.That(program, Is.Not.Null, frontEnd.ErrorRecord.ToString()); // act var tacs = new ThreeAddressCodeFactory().Generate(program); var output = new CodeGenerator().Generate(tacs); var tinyOut = new TinyMachine(ExePath, TestFilePath).Execute(output, "19"); // assert Assert.That(tinyOut, Is.EqualTo(new[] { "19" })); }