/// <summary> /// 对某个AST节点求值,并打印求值过程 /// </summary> /// <param name="node"></param> /// <param name="indent">打印输出时的缩进量,用tab控制</param> /// <returns></returns> private int Evaluate(ASTNode node, string indent) { int result = 0; Console.WriteLine(indent + "Calculating:" + node.GetType()); switch (node.GetType()) { case ASTNodeType.Program: foreach (ASTNode child in node.GetChildren()) { result = Evaluate(child, indent + "\t"); } break; case ASTNodeType.Additive: ASTNode child1 = node.GetChildren()[0]; int value1 = Evaluate(child1, indent + "\t"); ASTNode child2 = node.GetChildren()[1]; int value2 = Evaluate(child2, indent + "\t"); if (node.GetText().Equals("+")) { result = value1 + value2; } else { result = value1 - value2; } break; case ASTNodeType.Multiplicative: child1 = node.GetChildren()[0]; value1 = Evaluate(child1, indent + "\t"); child2 = node.GetChildren()[1]; value2 = Evaluate(child2, indent + "\t"); if (node.GetText().Equals("*")) { result = value1 * value2; } else { result = value1 / value2; } break; case ASTNodeType.IntLiteral: result = int.Parse(node.GetText()); break; default: break; } Console.WriteLine(indent + "Result:" + result); return(result); }
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 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)); }
void dumpAST(ASTNode node, string indent) { Console.WriteLine(indent + node.GetType() + " " + node.GetText()); foreach (var child in node.GetChildren()) { dumpAST(child, indent + "\t"); } }
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 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 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_RemovesDecrement_Multiple() { 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 DecrementNode("a")); ast.AddChild(new DecrementNode("a")); ast.AddChild(new DecrementNode("a")); PropagateConstants(ast); Assert.AreEqual(2, ast.GetChildren().Count()); }
public void TestCheckSyntax() { Token tmpToken; LineContext tmpContext; List <Token> tokens = new List <Token>(); tmpToken = new Token(Global.DataType.IDENTIFIER); tmpToken.value = "print"; tokens.Add(tmpToken); tmpToken = new Token(Global.DataType.OPEN_ROUND_BRACKET); tokens.Add(tmpToken); tmpToken = new Token(Global.DataType.STRING); tmpToken.value = "\"hoi\""; tokens.Add(tmpToken); tmpToken = new Token(Global.DataType.CLOSE_ROUND_BRACKET); tokens.Add(tmpToken); List <LineContext> context = new List <LineContext>(); tmpContext = new LineContext(1, 1); context.Add(tmpContext); tmpContext = new LineContext(1, 1); context.Add(tmpContext); tmpContext = new LineContext(1, 1); context.Add(tmpContext); tmpContext = new LineContext(1, 1); context.Add(tmpContext); SyntaxAnalyzer syntaxAnalyer = new SyntaxAnalyzer(); ASTNode result = syntaxAnalyer.CheckSyntax(tokens, context); Assert.AreEqual(Global.ASTType.BASE, result.GetType()); Assert.AreEqual(Global.ASTType.FUNCTION_CALL, result.GetChildren()[0].GetType()); Assert.AreEqual("print", result.GetChildren()[0].GetName()); Assert.AreEqual("\"hoi\"", result.GetChildren()[0].GetChildren()[0].GetName()); }
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_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 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 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 FlattenExpresison_Assignment_If_ConditionExtracts() { var ast = new ASTNode(); var ifnode = new IfNode( new AdditionNode( new ShortValueNode(0), new ShortValueNode(1) ), new BlockNode() ); ast.AddChild(ifnode); var changes = FlattenExpression(ast, 0); Assert.IsTrue(changes > 0); var children = ast.GetChildren().ToList(); Assert.AreEqual(3, children.Count); Assert.IsInstanceOfType(children[0], typeof(VariableDeclarationNode)); Assert.IsInstanceOfType(ifnode.Condition, typeof(VariableValueNode)); }
public void RemoveUnusedVariables_ReducesChain() { 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"))); var iterations = 0; while (RemoveUnusedVariables(ast)) { iterations++; } Assert.AreEqual(3, iterations); Assert.AreEqual(0, ast.GetChildren().Count()); }
public void PropagteConstants_If_ExtractsFalseBody() { var ast = new ASTNode(); ast.AddChild(new VariableDeclarationNode("byte", "x")); ast.AddChild(new VariableAssignmentNode("x", new ShortValueNode(0))); var iftrue = new BlockNode(); iftrue.AddChild(new VariableAssignmentNode("x", new ShortValueNode(1))); var iffalse = new BlockNode(); iffalse.AddChild(new AdditionAssignmentNode("x", new ShortValueNode(2))); ast.AddChild(new IfNode(new VariableValueNode("x"), iftrue, iffalse)); var changesmade = PropagateConstants(ast); Assert.IsTrue(changesmade); var children = ast.GetChildren().ToList(); Assert.AreEqual(3, children.Count); Assert.IsInstanceOfType(children[2], typeof(AdditionAssignmentNode)); }
private int Evaluate(ASTNode node, string indent) { int result = 0; if (verbose) { Console.WriteLine(indent + "Calculatings:" + node.GetType()); } switch (node.GetType()) { case ASTNodeType.Program: foreach (var child in node.GetChildren()) { result = Evaluate(child, indent); } break; case ASTNodeType.Additive: ASTNode child1 = node.GetChildren()[0]; int value1 = Evaluate(child1, indent + "\t"); ASTNode child2 = node.GetChildren()[1]; int value2 = Evaluate(child2, indent + "\t"); if (node.GetText().Equals("+")) { result = value1 + value2; } else { result = value1 - value2; } break; case ASTNodeType.Multiplicative: child1 = node.GetChildren()[0]; value1 = Evaluate(child1, indent + "\t"); child2 = node.GetChildren()[1]; value2 = Evaluate(child2, indent + "\t"); if (node.GetText().Equals("*")) { result = value1 * value2; } else { result = value1 / value2; } break; case ASTNodeType.IntLiteral: result = int.Parse(node.GetText()); break; case ASTNodeType.Identifier: string varName = node.GetText(); if (variables.ContainsKey(varName)) { int value; if (!variables.TryGetValue(varName, out value)) { throw new Exception("variables " + varName + "has not been set any value"); } } else { throw new Exception("unknow variable:" + varName); } break; case ASTNodeType.AssignmentStmt: varName = node.GetText(); if (!variables.ContainsKey(varName)) { } } }