示例#1
0
        public void FlattenExpression_Assignment_MemoryValue_Both()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            var additionnode = new AdditionNode(new MemoryValueNode(100), new MemoryValueNode(100));
            var assignment   = new VariableAssignmentNode("x", additionnode);

            ast.AddChild(assignment);

            var changes = FlattenExpression(ast, 1);

            Assert.IsTrue(changes > 0);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(6, children.Count);
            Assert.IsInstanceOfType(additionnode.Left, typeof(VariableValueNode));
            Assert.IsInstanceOfType(additionnode.Right, typeof(VariableValueNode));
            Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[1], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[2], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[4], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[5], typeof(VariableAssignmentNode));
            Assert.AreSame(children[5], assignment);
            Assert.AreNotEqual(((VariableAssignmentNode)children[2]).VariableName, ((VariableAssignmentNode)children[4]).VariableName);
        }
示例#2
0
        public void EmitAssembly_Expression_MoreThen()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x",
                                                    new MoreThanComparisonNode(
                                                        new ShortValueNode(1),
                                                        new ShortValueNode(2)
                                                        )
                                                    ));

            var asm = EmitAssembly(ast).ToArray();

            ListEqual(new[] {
                "LD A 1",
                "CP 2",
                "JP C generatedLabel1",
                "JP NZ generatedLabel1",
                "LD C 1",
                "JP generatedLabel2",
                "generatedLabel1:",
                "LD C 0",
                "generatedLabel2:"
            }, asm);
        }
示例#3
0
        public void FlattenExpression_Assignment_SideSubexpressionExtracted()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new SubtractionNode(
                                                        new AdditionNode(
                                                            new ShortValueNode(1),
                                                            new ShortValueNode(2)
                                                            ),
                                                        new AdditionNode(
                                                            new ShortValueNode(3),
                                                            new ShortValueNode(4)
                                                            )
                                                        )));

            var changes = FlattenExpression(ast, 1);

            Assert.IsTrue(changes > 0);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(6, children.Count);
            Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[1], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[2], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[4], typeof(VariableAssignmentNode));
            Assert.IsInstanceOfType(children[5], typeof(VariableAssignmentNode));
        }
示例#4
0
        public void BasicRegisterAlloc()
        {
            var expectedvariables = new[] { "x", "y", "z" };
            var rootnode          = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("int", expectedvariables[0]));                                      // int x
            rootnode.AddChild(new VariableAssignmentNode(expectedvariables[0], new ShortValueNode(5)));                       // x = 5
            rootnode.AddChild(new VariableDeclarationNode("int", expectedvariables[1]));                                      // int y
            rootnode.AddChild(new VariableAssignmentNode(expectedvariables[1], new VariableValueNode(expectedvariables[0]))); // y = x
            rootnode.AddChild(new VariableDeclarationNode("int", expectedvariables[2]));                                      // int z

            var alloc = NaiveAllocate(rootnode);

            Assert.AreEqual(3, alloc.Keys.Count);

            var i = 0;

            foreach (var variable in alloc.Keys)
            {
                Assert.AreEqual(expectedvariables[i++], variable);
            }
            i = 0;
            foreach (var register in alloc.Values)
            {
                Assert.AreEqual(register, i++);
            }
        }
示例#5
0
        public void EmitAssembly_If_CreatesBlock_WithElse()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(1)));
            var iftrueblock = new BlockNode();

            iftrueblock.AddChild(new VariableAssignmentNode("x", new ShortValueNode(1)));
            var iffalseblock = new BlockNode();

            iffalseblock.AddChild(new VariableAssignmentNode("x", new ShortValueNode(2)));
            ast.AddChild(new IfNode(new VariableValueNode("x"), iftrueblock, iffalseblock));

            var asm = EmitAssembly(ast).ToArray();

            ListEqual(new[] {
                "LD C 1",
                "XOR A",
                "CP C",
                "JP NZ generatedLabel1",
                "LD C 1",
                "JP generatedLabel2",
                "generatedLabel1:",
                "LD C 2",
                "generatedLabel2:"
            }, asm);
        }
示例#6
0
        public void FlattenExpressions_Assignment_FlattensAll()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new SubtractionNode(
                                                        new AdditionNode(
                                                            new ShortValueNode(1),
                                                            new ShortValueNode(2)
                                                            ),
                                                        new ShortValueNode(3)
                                                        )));
            ast.AddChild(new VariableDeclarationNode("byte", "y"));
            ast.AddChild(new VariableAssignmentNode("y", new SubtractionNode(
                                                        new AdditionNode(
                                                            new ShortValueNode(1),
                                                            new ShortValueNode(2)
                                                            ),
                                                        new ShortValueNode(3)
                                                        )));

            var changed = FlattenExpressions(ast);

            Assert.IsTrue(changed);
        }
示例#7
0
        public void FlattenExpression_Assignment_FlatExpression_NotAffected()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new SubtractionAssignmentNode("x", new AdditionNode(new ShortValueNode(5), new ShortValueNode(1))));

            var changes = FlattenExpression(ast, 1);

            Assert.IsTrue(changes == 0);
        }
示例#8
0
        public void RemoveUnusedVariables_WriteButNoRead_Removes()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));

            RemoveUnusedVariables(ast);

            Assert.AreEqual(0, ast.GetChildren().Count());
        }
示例#9
0
        public void EmitAssembly_LoadValueToRegister()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("int", "x"));                // int x
            rootnode.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5))); // x = 5

            var asmlines = new List <string>(EmitAssembly(rootnode));

            Assert.AreEqual(1, asmlines.Count);
            Assert.AreEqual("LD C 5", asmlines[0]);
        }
示例#10
0
        public void CreateBasicBlocks_OneBlock()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableDeclarationNode("byte", "y"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));

            var blocks = CreateBasicBlocks(ast).ToArray();

            Assert.AreEqual(1, blocks.Length);
            Assert.AreEqual(3, blocks[0].Count);
        }
示例#11
0
        public void CreateBasicBlocks_NoEmpty()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));
            ast.AddChild(new GotoNode("label1"));
            ast.AddChild(new LabelNode("label1"));
            ast.AddChild(new VariableDeclarationNode("byte", "y"));

            var blocks = CreateBasicBlocks(ast).ToArray();

            Assert.AreEqual(2, blocks.Length);
        }
示例#12
0
        public void EmitAssembly_IncrementVariable()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("int", "x"));                // int x
            rootnode.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5))); // x = 5
            rootnode.AddChild(new IncrementNode("x"));                                 // x++

            var asmlines = new List <string>(EmitAssembly(rootnode));

            Assert.AreEqual(2, asmlines.Count);
            Assert.AreEqual("LD C 5", asmlines[0]);
            Assert.AreEqual("INC C", asmlines[1]);
        }
示例#13
0
        public void EmitAssembly_MemoryWrite_WithVariable()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(10)));
            ast.AddChild(new MemoryAssignmentNode(100, new VariableValueNode("x")));

            var asm = EmitAssembly(ast).ToArray();

            EndsWith(new[] {
                "LD (100) C"
            }, asm);
        }
示例#14
0
        public void EmitAssembly_AssignVariable_WithMemory()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new MemoryValueNode(31)));

            var asm = EmitAssembly(ast).ToList();

            ListEqual(new[] {
                "LD A (31)",
                "LD C A",
            }, asm);
        }
示例#15
0
        public void PropagateConstants_Chains()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            ast.AddChild(new VariableAssignmentNode("b", new VariableValueNode("a")));
            ast.AddChild(new VariableDeclarationNode("byte", "c"));
            ast.AddChild(new VariableAssignmentNode("c", new VariableValueNode("b")));
            ast.AddChild(new VariableDeclarationNode("byte", "c"));
            var assignment = new VariableAssignmentNode("c", new VariableValueNode("b"));

            ast.AddChild(assignment);

            var iterations = 0;

            while (PropagateConstants(ast))
            {
                iterations++;
            }

            Assert.AreEqual(1, iterations);
            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(5, ((ShortValueNode)assignment.Value).GetValue());
        }
示例#16
0
        public void PropagateConstants_ResolvesExpressions()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            var expression = new VariableAssignmentNode("a", new AdditionNode(new ShortValueNode(1), new ShortValueNode(5)));

            ast.AddChild(expression);

            var changed = PropagateConstants(ast);

            Assert.IsTrue(changed);
            Assert.IsInstanceOfType(expression.Value, typeof(ConstantNode));
        }
示例#17
0
        public void FindLastUsage_DoesntFind()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("int", "x"));                     // int x
            rootnode.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));      // x = 5
            rootnode.AddChild(new VariableDeclarationNode("int", "y"));                     // int y
            rootnode.AddChild(new VariableAssignmentNode("y", new VariableValueNode("x"))); // y = x
            rootnode.AddChild(new VariableDeclarationNode("int", "z"));                     // int z

            var lastusage = FindLastVariableUsage(rootnode.GetChildren().ToList(), "x", 10);

            Assert.AreEqual(10, lastusage);
        }
示例#18
0
        public void PropagateConstants_DetectsSubNodeChanges()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            var value = new AdditionNode(new VariableValueNode("y"), new VariableValueNode("x"));

            ast.AddChild(new VariableAssignmentNode("a", value));

            var changed = PropagateConstants(ast);

            Assert.IsTrue(changed);
        }
示例#19
0
        public void EmitAssembly_Expression_Negate()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new NegateNode(new ShortValueNode(1))));

            var asm = EmitAssembly(ast).ToArray();

            ListEqual(new[] {
                "LD A 1",
                "XOR 1",
                "LD C A"
            }, asm);
        }
示例#20
0
        public void EmitAssembly_LoadRegisterToRegister()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("int", "x"));                     // int x
            rootnode.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));      // x = 5
            rootnode.AddChild(new VariableDeclarationNode("int", "y"));                     // int y
            rootnode.AddChild(new VariableAssignmentNode("y", new VariableValueNode("x"))); // y = x

            var asmlines = new List <string>(EmitAssembly(rootnode));

            Assert.AreEqual(2, asmlines.Count);
            Assert.AreEqual("LD C 5", asmlines[0]);
            Assert.AreEqual("LD C C", asmlines[1]);             // x's last use is to create y so C gets reused
        }
示例#21
0
        public void TransformToIncDec_Subtract_Right_Optimizes()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(0)));
            ast.AddChild(new VariableAssignmentNode("x", new SubtractionNode(new VariableValueNode("x"), new ShortValueNode(1))));

            var changesmade = TransformToIncDec(ast);

            Assert.IsTrue(changesmade);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(3, children.Count);
            Assert.IsInstanceOfType(children[2], typeof(DecrementNode));
        }
示例#22
0
        public void PropagateConstants_CopiesOver()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            var assignment = new VariableAssignmentNode("b", new VariableValueNode("a"));

            ast.AddChild(assignment);

            PropagateConstants(ast);

            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(5, ((ShortValueNode)assignment.Value).GetValue());
        }
示例#23
0
        public void EmitAssembly_Expression_Subtraction()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new VariableDeclarationNode("byte", "x"));
            rootnode.AddChild(new VariableAssignmentNode("x", new SubtractionNode(new ShortValueNode(5), new ShortValueNode(6))));

            var actualASM = new List <string>(EmitAssembly(rootnode));

            var expectedASM = new[] {
                "LD A 5",
                "SUB A 6",
                "LD C A"
            };

            ListEqual(expectedASM, actualASM);
        }
示例#24
0
        public void CreateBasicBlocks_JumpSeperates()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(5)));
            ast.AddChild(new GotoNode("label1"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(10)));

            var blocks = CreateBasicBlocks(ast).ToArray();

            Assert.AreEqual(2, blocks.Length);
            Assert.AreEqual(3, blocks[0].Count);
            Assert.AreEqual(1, blocks[1].Count);
            Assert.IsInstanceOfType(blocks[0][0], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(blocks[1][0], typeof(VariableAssignmentNode));
        }
示例#25
0
        public void PropagateConstants_RemovesDecrement()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));
            ast.AddChild(new VariableAssignmentNode("a", new ShortValueNode(5)));
            ast.AddChild(new DecrementNode("a"));
            ast.AddChild(new VariableDeclarationNode("byte", "b"));
            var assignment = new VariableAssignmentNode("b", new VariableValueNode("a"));

            ast.AddChild(assignment);

            PropagateConstants(ast);

            Assert.IsInstanceOfType(assignment.Value, typeof(ShortValueNode));
            Assert.AreEqual(4, ((ShortValueNode)assignment.Value).GetValue());
            Assert.AreEqual(4, ast.GetChildren().Count());
        }
示例#26
0
        public void RemoveUnusedVariables_DeclaredButNotUsed_Removes()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "a"));

            RemoveUnusedVariables(ast);

            Assert.AreEqual(0, ast.GetChildren().Count());
        }
示例#27
0
        public void Transform_SubtractionAssignmentToExpression()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new SubtractionAssignmentNode("x", new ShortValueNode(5)));

            var changed = TransformSubtractionAssignmentToExpression(ast);

            var children = ast.GetChildren().ToList();

            Assert.IsTrue(changed);
            Assert.AreEqual(2, children.Count);
            Assert.IsInstanceOfType(children[1], typeof(VariableAssignmentNode));
            var assignment = (VariableAssignmentNode)children[1];

            Assert.IsInstanceOfType(assignment.Value, typeof(SubtractionNode));
            Assert.IsInstanceOfType(((SubtractionNode)assignment.Value).Left, typeof(VariableValueNode));
            Assert.IsInstanceOfType(((SubtractionNode)assignment.Value).Right, typeof(ShortValueNode));
        }
示例#28
0
        public void EmitAssembly_Label()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new LabelNode("label"));             // label:

            var asmlines = new List <string>(EmitAssembly(rootnode));

            Assert.AreEqual(1, asmlines.Count);
            Assert.AreEqual("label:", asmlines[0]);
        }
示例#29
0
        public void PropagteConstants_If_ExtractsTrueBody()
        {
            var ast = new ASTNode();

            ast.AddChild(new VariableDeclarationNode("byte", "x"));
            ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(1)));
            var block = new BlockNode();

            block.AddChild(new VariableDeclarationNode("byte", "a"));
            block.AddChild(new VariableAssignmentNode("a", new ShortValueNode(1)));
            ast.AddChild(new IfNode(new VariableValueNode("x"), block));

            var changesmade = PropagateConstants(ast);

            Assert.IsTrue(changesmade);
            var children = ast.GetChildren().ToList();

            Assert.AreEqual(4, children.Count);
            Assert.IsInstanceOfType(children[2], typeof(VariableDeclarationNode));
            Assert.IsInstanceOfType(children[3], typeof(VariableAssignmentNode));
        }
示例#30
0
        public void EmitAssembly_Goto()
        {
            var rootnode = new ASTNode();

            rootnode.AddChild(new GotoNode("label"));             // goto label

            var asmlines = new List <string>(EmitAssembly(rootnode));

            ListEqual(new List <string> {
                "JP label"
            }, asmlines);
        }