protected override CrawlSyntaxNode VisitMultiChildExpression(MultiChildExpressionNode multiChildExpression) { var expr = (MultiChildExpressionNode)base.VisitMultiChildExpression(multiChildExpression); if (!(expr.ExpressionType == ExpressionType.Add || expr.ExpressionType == ExpressionType.Multiply || expr.ExpressionType == ExpressionType.ShortCircuitAnd || expr.ExpressionType == ExpressionType.ShortCircuitOr)) { return(expr); } List <ExpressionNode> literals = new List <ExpressionNode>(); List <ExpressionNode> restOfIt = new List <ExpressionNode>(); foreach (ExpressionNode expression in expr.Arguments) { var literal = expression as LiteralNode; if (literal != null) { literals.Add(literal); } else { restOfIt.Add(expression); } } List <ExpressionNode> newArguments = literals.Concat(restOfIt).ToList(); return(CrawlSyntaxNode.MultiChildExpression(expr.Interval, expr.ExpressionType, expr.ResultType, newArguments)); }
protected override CrawlSyntaxNode VisitMultiChildExpression(MultiChildExpressionNode multiChildExpression) { CrawlSyntaxNode expr = base.VisitMultiChildExpression(multiChildExpression); MultiChildExpressionNode multuExpr = expr as MultiChildExpressionNode; if (multuExpr == null) { return(expr); } if (multuExpr.Arguments.ChildCount == 1) { OptimizationsWereMade = true; return(multuExpr.Arguments.First()); } List <ExpressionNode> newArguments = new List <ExpressionNode>(); ListNode <ExpressionNode> arguments = multuExpr.Arguments; //Algorithm ahead. Strap in. //Go through the node's arguments, building list of new arguments, //where any pair of neighboring literals have been folded into one. int i = 0; while (i < arguments.Count()) { //If this is the last in the sequence, there is nothing left to fold. if (i == arguments.Count() - 1) { newArguments.Add(arguments[i]); break; } //Only literal nodes can be folded. LiteralNode current = arguments[i] as LiteralNode; if (current != null) { //If both the current node and the next node is a literal, then //fold them, add them to the new list, //and jump to the argument after them. LiteralNode next = arguments[i + 1] as LiteralNode; if (next != null) { newArguments.Add(FoldMultuPair(current, multuExpr.ExpressionType, next)); OptimizationsWereMade = true; i += 2; } //If the next argument is not a literal, it cannot be folded. //move on to the argument after that. else { newArguments.Add(arguments[i]); newArguments.Add(arguments[i + 1]); i += 2; } } //If the current node isn't a literal, //move on to consider the next else { newArguments.Add(arguments[i]); i += 1; } } return(CrawlSyntaxNode.MultiChildExpression(multuExpr.Interval, multuExpr.ExpressionType, multuExpr.ResultType, newArguments)); }