void SimplifyActionBlocks() { int index = 0; while (index < _blocks.Count) { ActionBlock block = _blocks [index]; switch (block.ActionType) { case ActionType.ConditionalBranch: // if condition goto label // return expression // label: return true // | // V // return (condition || expression) // // label: return false // | // V // return (!condition || expression) ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)block; if (IsReturnTrueOrFalse(cbr.Then) && IsReturn(cbr.Else) && 1 == cbr.Then.Predecessors.Count && 1 == cbr.Else.Predecessors.Count) { BinaryOperator op = BinaryOperator.LogicalOr; Expression lhs = cbr.Condition; Expression rhs = ((ReturnActionBlock)cbr.Else).Expression; if (((LiteralExpression)((ReturnActionBlock)cbr.Then).Expression).Value.Equals(0)) { op = BinaryOperator.LogicalAnd; _expressionDecompiler.Negate(lhs); lhs = _expressionDecompiler.Pop(); } ActionBlock newBlock = new ReturnActionBlock( block.SourceInstruction, new BinaryExpression(op, lhs, rhs)); _graph.ReplaceAt(index, newBlock); index = 0; continue; } break; } ++index; } }
private ActionBlock OnReturn(ReturnActionBlock block) { Expression expression = block.Expression; VariableReferenceExpression variable = expression as VariableReferenceExpression; _queryExpression = variable != null ? _variables[GetVariableIndex(variable)] : expression; return null; }
void WriteReturn (ReturnActionBlock block) { _writer.Write ("return"); if (null != block.Expression) { _writer.Write (" "); WriteExpression (block.Expression); } }
static bool IsReturnTrueOrFalse(ActionBlock block) { ReturnActionBlock ret = block as ReturnActionBlock; return(ret != null && IsTrueOrFalse(ret.Expression)); }
void SimplifyActionBlocks () { int index = 0; while (index < _blocks.Count) { ActionBlock block = _blocks [index]; switch (block.ActionType) { case ActionType.ConditionalBranch: /// if condition goto label /// return expression /// label: return true /// | /// V /// return (condition || expression) /// /// label: return false /// | /// V /// return (!condition || expression) ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)block; if (IsReturnTrueOrFalse (cbr.Then) && IsReturn (cbr.Else) && 1 == cbr.Then.Predecessors.Count && 1 == cbr.Else.Predecessors.Count) { BinaryOperator op = BinaryOperator.LogicalOr; Expression lhs = cbr.Condition; Expression rhs = ((ReturnActionBlock) cbr.Else).Expression; if (((LiteralExpression) ((ReturnActionBlock) cbr.Then).Expression).Value.Equals (0)) { op = BinaryOperator.LogicalAnd; _expressionDecompiler.Negate (lhs); lhs = _expressionDecompiler.Pop (); } ActionBlock newBlock = new ReturnActionBlock ( block.SourceInstruction, new BinaryExpression (op, lhs, rhs)); _graph.ReplaceAt (index, newBlock); index = 0; continue; } break; } ++index; } }