Ejemplo n.º 1
0
        private Expression CreateListSet(Expression source, Expression destination, CompileArgument arg)
        {
            //### IList<T>
            //for (var i = 0, len = src.Count; i < len; i++) {
            //  var item = src[i];
            //  dest.Add(convert(item));
            //}

            //### IEnumerable<T>
            //foreach (var item in src)
            //  dest.Add(convert(item));

            var sourceElementType      = source.Type.ExtractCollectionType();
            var destinationElementType = destination.Type.ExtractCollectionType();
            var item   = Expression.Variable(sourceElementType, "item");
            var getter = CreateAdaptExpression(item, destinationElementType, arg);

            var addMethod = destination.Type.GetMethod("Add", new[] { destinationElementType });
            var set       = Expression.Call(
                destination,
                addMethod,
                getter);
            var loop = ExpressionEx.ForLoop(source, item, set);

            return(loop);
        }
Ejemplo n.º 2
0
        private Expression CreateArraySet(Expression source, Expression destination, CompileArgument arg)
        {
            //### IList<T>
            //var v = 0
            //for (var i = 0, len = src.Count; i < len; i++) {
            //  var item = src[i];
            //  dest[v++] = convert(item);
            //}

            //### IEnumerable<T>
            //var v = 0;
            //foreach (var item in src)
            //  dest[v++] = convert(item);

            var sourceElementType      = source.Type.ExtractCollectionType();
            var destinationElementType = destination.Type.ExtractCollectionType();
            var item   = Expression.Variable(sourceElementType, "item");
            var v      = Expression.Variable(typeof(int), "v");
            var start  = Expression.Assign(v, Expression.Constant(0));
            var getter = CreateAdaptExpression(item, destinationElementType, arg);
            var set    = Expression.Assign(
                Expression.ArrayAccess(destination, Expression.PostIncrementAssign(v)),
                getter);
            var loop = ExpressionEx.ForLoop(source, item, set);

            return(Expression.Block(new[] { v }, start, loop));
        }
        private Expression CreateArraySet(Expression source, Expression destination, CompileArgument arg)
        {
            //var v0 = 0, v1 = 0;
            //var vlen0 = dest.GetLength(0), vlen1 = dest.GetLength(1);
            //for (var i = 0, len = src.Count; i < len; i++) {
            //  var item = src[i];
            //  dest[v0, v1] = convert(item);
            //  v1++;
            //  if (v1 >= vlen1) {
            //      v1 = 0;
            //      v0++;
            //  }
            //}

            var sourceElementType      = source.Type.ExtractCollectionType();
            var destinationElementType = destination.Type.ExtractCollectionType();
            var item = Expression.Variable(sourceElementType, "item");
            var vx   = Enumerable.Range(0, destination.Type.GetArrayRank())
                       .Select(i => Expression.Variable(typeof(int), "v" + i))
                       .ToList();
            var vlenx = Enumerable.Range(0, destination.Type.GetArrayRank())
                        .Select(i => Expression.Variable(typeof(int), "vlen" + i))
                        .ToList();
            var block = new List <Expression>();

            block.AddRange(vx.Select(v => Expression.Assign(v, Expression.Constant(0))));

            var method = typeof(Array).GetMethod("GetLength", new[] { typeof(int) });

            block.AddRange(
                vlenx.Select((vlen, i) =>
                             Expression.Assign(
                                 vlen,
                                 Expression.Call(destination, method, Expression.Constant(i)))));
            var getter = CreateAdaptExpression(item, destinationElementType, arg);
            var set    = ExpressionEx.Assign(
                Expression.ArrayAccess(destination, vx),
                getter);

            Expression ifExpr = Expression.Block(
                Expression.Assign(vx[1], Expression.Constant(0)),
                Expression.PostIncrementAssign(vx[0]));

            for (var i = 1; i < vx.Count; i++)
            {
                var list = new List <Expression>();
                if (i + 1 < vx.Count)
                {
                    list.Add(Expression.Assign(vx[i + 1], Expression.Constant(0)));
                }
                list.Add(Expression.PostIncrementAssign(vx[i]));
                list.Add(Expression.IfThen(
                             Expression.GreaterThanOrEqual(vx[i], vlenx[i]),
                             ifExpr));
                ifExpr = Expression.Block(list);
            }

            var loop = ExpressionEx.ForLoop(source, item, set, ifExpr);

            block.Add(loop);
            return(Expression.Block(vx.Concat(vlenx), block));
        }