public void Optimize_AdditionMultiplicationConstants() { // 1 + 2 * 3 => 7 var ast = new SqlInfixOperationNode { Left = new SqlNumberNode(1), Operator = new SqlOperatorNode("+"), Right = new SqlInfixOperationNode { Left = new SqlNumberNode(2), Operator = new SqlOperatorNode("*"), Right = new SqlNumberNode(3) } }; var target = new ExpressionOptimizeVisitor(); var result = target.Visit(ast); result.Should().MatchAst(new SqlNumberNode(7)); }
private ISqlNode ParseBooleanExpression5(ITokenizer t) { // <BooleanExpression3> ("AND" | "OR") <BooleanExpression3> var left = ParseBooleanExpression4(t); while (t.Peek().IsKeyword("AND", "OR")) { var op = new SqlOperatorNode(t.GetNext()); var right = ParseBooleanExpression4(t); left = new SqlInfixOperationNode { Location = op.Location, Left = left, Operator = op, Right = right }; } return(left); }
private ISqlNode ParseScalarExpression3(ITokenizer t) { // Operators with + - precidence // <Expression2> (<op> <Expression2>)+ var left = ParseScalarExpression2(t); while (t.Peek().IsSymbol("+", "-", "&", "^", "|")) { var op = new SqlOperatorNode(t.GetNext()); var right = ParseScalarExpression2(t); left = new SqlInfixOperationNode { Location = op.Location, Left = left, Operator = op, Right = right }; } return(left); }
public ISqlNode VisitInfixOperation(SqlInfixOperationNode n) { void ToStringChild(ISqlNode node) { if (node is SqlInfixOperationNode) { Append("(", node, ")"); return; } Visit(node); } if (n.IsUnionOperation()) { Visit(n.Left); AppendLineAndIndent(); Visit(n.Operator); AppendLineAndIndent(); Visit(n.Right); } else if (n.IsBooleanOperation()) { ToStringChild(n.Left); AppendLineAndIndent(); Visit(n.Operator); Append(" "); ToStringChild(n.Right); } else { ToStringChild(n.Left); Append(" "); Visit(n.Operator); Append(" "); ToStringChild(n.Right); } return(n); }
public override ISqlNode VisitInfixOperation(SqlInfixOperationNode n) { n = base.VisitInfixOperation(n) as SqlInfixOperationNode; if (n.IsArithmeticOperation()) { if (n.Left is SqlNumberNode nl && n.Right is SqlNumberNode nr) { var newNode = n.Operator.Apply(nl, nr); newNode.Location = n.Location; return(newNode); } if (n.Left is SqlStringNode sl && n.Right is SqlStringNode a) { var newNode = n.Operator.Apply(sl, a); newNode.Location = n.Location; return(newNode); } } // TODO: If the operation is AND or OR and both sides can reduce to one of (TRUE, FALSE), we can reduce the whole thing return(n); }