예제 #1
1
        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" }));
        }
예제 #2
0
        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());
        }
예제 #3
0
        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());
        }
예제 #4
0
        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" }));
        }
예제 #5
0
        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" }));
        }
예제 #6
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" }));
        }
예제 #7
0
        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" }));
        }
예제 #8
0
        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" }));
        }
예제 #9
0
        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());
        }
예제 #10
0
        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" }));
        }
예제 #11
0
        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" }));
        }
예제 #12
0
        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());
        }
예제 #13
0
        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" }));
        }
예제 #14
0
        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());
        }
예제 #15
0
        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" }));
        }
예제 #16
0
        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" }));
        }