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); }
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); }
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)); }
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++); } }
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); }
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); }
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); }
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()); }
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]); }
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); }
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); }
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]); }
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); }
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); }
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()); }
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)); }
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); }
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); }
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); }
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 }
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)); }
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()); }
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); }
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)); }
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()); }
public void RemoveUnusedVariables_DeclaredButNotUsed_Removes() { var ast = new ASTNode(); ast.AddChild(new VariableDeclarationNode("byte", "a")); RemoveUnusedVariables(ast); Assert.AreEqual(0, ast.GetChildren().Count()); }
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)); }
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]); }
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)); }
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); }