public RuleApplication(RewriteRule rule, Expression before, Expression after, double time) { Rule = rule; Before = before; After = after; Time = time; }
public static Expression RecApplyRules(Expression expr, IEnumerable <RewriteRule> rules, Func <Expression, bool> exclude) { var rewriter = new RewriteVisitor(rules, exclude); var ret = rewriter.Visit(expr); //Quitar los atoms: var r2 = new RewriteVisitor(new[] { RewriteRule.Create( "quitarAtoms", (RewriteTypes.C1 x) => RewriteSpecial.Atom(x), x => x) }, x => false); var sinAtoms = r2.Visit(ret); return(sinAtoms); }
/// <summary> /// Devuelve el resultado de aplicar una regla al niver superior de la expresión o la expresión original si la regla no se pudo aplicar a la expresión /// </summary> public static Expression GlobalApplyRule(Expression expr, RewriteRule rule, Func <Expression, Expression> visit) { if (rule.DebugName == "convertFromParam" || rule.DebugName == "fromParam") { ; } var parameters = rule.Find.Parameters; var pattBody = rule.Find.Body; PartialMatch partialMatch; try { partialMatch = GlobalMatch(expr, parameters, pattBody); } catch (Exception ex) { throw new ApplyRuleException("Error al obtener el match", rule.DebugName, expr, ex); } var match = PartialMatch.ToFullMatch(partialMatch, parameters); if (match == null) { return(expr); } if (rule.Condition != null && !rule.Condition(match, expr)) { return(expr); } //Sustituir la expresión: var ret = expr; var replaceLambda = rule.Replace; if (replaceLambda != null) { var subDic = replaceLambda.Parameters .Select((x, i) => (par: x, value: match.Args[i])) .ToDictionary(x => (Expression)x.par, x => x.value) ; Expression repRet; try { repRet = ReplaceVisitor.Replace(replaceLambda.Body, subDic, match.Types, x => false); } catch (Exception ex) { throw new ApplyRuleException("Error al reemplazar", rule.DebugName, expr, ex); } ret = repRet; } //Aplicar los transforms: { Expression nextRet; try { nextRet = ReplaceVisitor.Replace(ret, ex => { if (ex is MethodCallExpression call && call.Method.DeclaringType == typeof(RewriteSpecial) && call.Method.Name == nameof(RewriteSpecial.Transform)) { //Aplica el transform a la expresión: var arg = call.Arguments[0]; var func = ExprEval.EvalExpr <Func <Expression, Expression> >(call.Arguments[1]); var tResult = func.Value(arg); return(tResult); } return(ex); }); }