Beispiel #1
0
        private static Zen <TResult> Simplify(Zen <IList <T> > e, Zen <TResult> emptyCase, Func <Zen <T>, Zen <IList <T> >, Zen <TResult> > consCase)
        {
            if (e is ZenListEmptyExpr <T> l1)
            {
                return(emptyCase);
            }

            if (e is ZenListAddFrontExpr <T> l2)
            {
                return(consCase(l2.Element, l2.Expr));
            }

            if (Settings.SimplifyRecursive)
            {
                if (e is ZenIfExpr <IList <T> > l3)
                {
                    var tbranch = ZenListCaseExpr <T, TResult> .Create(l3.TrueExpr, emptyCase, consCase);

                    var fbranch = ZenListCaseExpr <T, TResult> .Create(l3.FalseExpr, emptyCase, consCase);

                    return(ZenIfExpr <TResult> .Create(l3.GuardExpr, tbranch, fbranch));
                }
            }

            return(new ZenListCaseExpr <T, TResult>(e, emptyCase, consCase));
        }
Beispiel #2
0
        private static Zen <T2> Simplify(Zen <T1> expr, string fieldName, bool unroll)
        {
            // get(with(o, name, f), name) == f
            // get(with(o, name', f), name) == get(o, name)
            if (expr is ZenWithFieldExpr <T1, T2> e1)
            {
                return((e1.FieldName == fieldName) ?
                       e1.FieldValue :
                       Create(e1.Expr, fieldName)); // recurse
            }

            // get(if e1 then e2 else e3, name) = if e1 then get(e2, name) else get(e3, name)
            if (unroll && expr is ZenIfExpr <T1> e2)
            {
                var trueBranch  = Create(e2.TrueExpr, fieldName);
                var falseBranch = Create(e2.FalseExpr, fieldName);
                return(ZenIfExpr <T2> .Create(e2.GuardExpr, trueBranch.Unroll(), falseBranch.Unroll()));
            }

            // get(createobject(p1, ..., pn), namei) == pi
            if (expr is ZenCreateObjectExpr <T1> coe)
            {
                return((Zen <T2>)coe.Fields[fieldName]);
            }

            return(new ZenGetFieldExpr <T1, T2>(expr, fieldName));
        }
Beispiel #3
0
        private static Zen <TTo> Simplify(Zen <TFrom> e, ImmutableList <Func <object, object> > converters, bool unroll)
        {
            // adapt(t1, t2, adapt(t2, t1, e)) == e
            if (e is ZenAdapterExpr <TFrom, TTo> inner1)
            {
                return(inner1.Expr);
            }

            if (unroll && e is ZenIfExpr <TFrom> inner2)
            {
                var trueBranch  = CreateMulti(inner2.TrueExpr, converters);
                var falseBranch = CreateMulti(inner2.FalseExpr, converters);
                return(ZenIfExpr <TTo> .Create(inner2.GuardExpr, trueBranch.Unroll(), falseBranch.Unroll()));
            }

            return(new ZenAdapterExpr <TTo, TFrom>(e, converters));
        }
Beispiel #4
0
        private static Zen <TTo> Simplify(Zen <TFrom> e, ImmutableList <Func <object, object> > converters)
        {
            // adapt(t1, t2, adapt(t2, t1, e)) == e
            if (e is ZenAdapterExpr <TFrom, TTo> inner1)
            {
                return(inner1.Expr);
            }

            // adapt(t1, t2, adapt(t2, t3, e)) == adapt(t1, t3, e)

            /* var type = e.GetType();
             * if (type.GetGenericTypeDefinition() == typeof(ZenAdapterExpr<,>))
             * {
             *  if (type.GetGenericArguments()[0] == typeof(T2))
             *  {
             *      var type1 = typeof(T1);
             *      var type3 = type.GetGenericArguments()[1];
             *      var astType = typeof(ZenAdapterExpr<,>).MakeGenericType(type1, type3);
             *      var paramType1 = typeof(Zen<>).MakeGenericType(type3);
             *      var paramType2 = typeof(ImmutableList<>).MakeGenericType(typeof(Func<object, object>));
             *      var method = astType.GetMethod("CreateMulti");
             *      var param1 = type.GetProperty("Expr").GetValue(e);
             *      var converters = (ImmutableList<Func<object, object>>)type.GetProperty("Converters").GetValue(e);
             *      var param2 = converters.AddRange(expression.Converters);
             *      return (Zen<T1>)method.Invoke(null, new object[] { param1, param2 });
             *  }
             * } */
            if (Settings.SimplifyRecursive)
            {
                if (e is ZenIfExpr <TFrom> inner2)
                {
                    var trueBranch = ZenAdapterExpr <TTo, TFrom> .CreateMulti(inner2.TrueExpr, converters);

                    var falseBranch = ZenAdapterExpr <TTo, TFrom> .CreateMulti(inner2.FalseExpr, converters);

                    return(ZenIfExpr <TTo> .Create(inner2.GuardExpr, trueBranch, falseBranch));
                }
            }

            return(new ZenAdapterExpr <TTo, TFrom>(e, converters));
        }
Beispiel #5
0
        private static Zen <TResult> Simplify(Zen <IList <T> > e, Zen <TResult> emptyCase, Func <Zen <T>, Zen <IList <T> >, Zen <TResult> > consCase, bool unroll)
        {
            if (e is ZenListEmptyExpr <T> l1)
            {
                return(emptyCase);
            }

            if (e is ZenListAddFrontExpr <T> l2)
            {
                return(consCase(l2.Element, l2.Expr));
            }

            if (unroll && e is ZenIfExpr <IList <T> > l3)
            {
                var tbranch = Create(l3.TrueExpr, emptyCase, consCase);
                var fbranch = Create(l3.FalseExpr, emptyCase, consCase);
                return(ZenIfExpr <TResult> .Create(l3.GuardExpr, tbranch.Unroll(), fbranch.Unroll()));
            }

            return(new ZenListCaseExpr <T, TResult>(e, emptyCase, consCase));
        }