private Expression HandleIterateArray(IterateNode node)
        {
            var index          = Expression.Variable(typeof(int));
            var length         = Expression.Variable(typeof(int));
            var currentElement = Expression.Variable(node.ItemType, "current");
            var exitLabel      = Expression.Label();

            PushScope(currentElement);
            var body = HandleNode(node.Body);

            PopScope();

            var array       = ParseExpression(node.Collection);
            var storedArray = Expression.Variable(array.Type);

            return(Expression.Block(
                       new[] { length, storedArray },
                       Expression.Assign(storedArray, array),
                       Expression.Assign(length, Expression.ArrayLength(storedArray)),
                       Expression.IfThenElse(Expression.Equal(length, Expression.Constant(0)),
                                             HandleNode(node.EmptyBody),
                                             Expression.Block(
                                                 new[] { index },
                                                 Expression.Assign(index, Expression.Constant(0)),
                                                 Expression.Loop(Expression.Block(
                                                                     new[] { currentElement },
                                                                     Expression.Assign(currentElement, Expression.ArrayIndex(storedArray, index)),
                                                                     body,
                                                                     Expression.Assign(index, Expression.Increment(index)),
                                                                     Expression.IfThen(Expression.Equal(index, length), Expression.Break(exitLabel))
                                                                     ), exitLabel)
                                                 )
                                             )
                       ));
        }
示例#2
0
文件: AvlApi.cs 项目: E01D/Base
        public void Iterate <TNode, TKey>(TNode node, Action <TNode> action)
            where TNode : class, AvlNode_I <TNode, TKey>
        {
            if (node == null)
            {
                return;
            }

            var stack = new IterateNode <TNode>()
            {
                Node = node,
            };

            while (stack != null)
            {
                TNode left;
                TNode right;

                if (stack.Status < 1 && (left = stack.Node.Left) != null)
                {
                    stack.Status = 1;

                    var newstack = new IterateNode <TNode>()
                    {
                        Node     = left,
                        Previous = stack,
                    };

                    stack = newstack;

                    continue;
                }

                if (stack.Status < 2)
                {
                    action(stack.Node);

                    stack.Status = 2;

                    continue;
                }

                if (stack.Status < 3 && (right = stack.Node.Right) != null)
                {
                    stack.Status = 3;

                    var newstack = new IterateNode <TNode>()
                    {
                        Node     = right,
                        Previous = stack,
                    };

                    stack = newstack;

                    continue;
                }

                stack = stack.Previous;
            }
        }
示例#3
0
        public void Iterate(TNode node, Action <TNode> action)
        {
            if (IsNull(node))
            {
                return;
            }

            var stack = new IterateNode <TNode>()
            {
                Node = node,
            };

            while (stack != null)
            {
                TNode left;
                TNode right;

                if (stack.Status < 1 && (left = GetLeft(stack.Node)) != null)
                {
                    stack.Status = 1;

                    var newstack = new IterateNode <TNode>()
                    {
                        Node     = left,
                        Previous = stack,
                    };

                    stack = newstack;

                    continue;
                }

                if (stack.Status < 2)
                {
                    action(stack.Node);

                    stack.Status = 2;

                    continue;
                }

                if (stack.Status < 3 && (right = GetRight(stack.Node)) != null)
                {
                    stack.Status = 3;

                    var newstack = new IterateNode <TNode>()
                    {
                        Node     = right,
                        Previous = stack,
                    };

                    stack = newstack;

                    continue;
                }

                stack = stack.Previous;
            }
        }
示例#4
0
        protected virtual TResult VisitIterateNode(IterateNode iterateNode)
        {
            var schema = this.VisitExpressionNode(iterateNode.Collection);

            this.VisitBlockNode(iterateNode.Body);
            this.VisitBlockNode(iterateNode.EmptyBody);

            return(schema);
        }
            protected override IClientModel VisitIterateNode(IterateNode iterateNode)
            {
                var result = this.VisitExpressionNode(iterateNode.Collection);

                _modelStack.Push(_clientContext.BeginIterate(result));
                this.Visit(iterateNode.Body);

                _modelStack.Pop();
                _clientContext.EndIterate();

                return(result);
            }
        private Expression HandleIterate(IterateNode node)
        {
            if (node.Collection.ResultType.IsArray)
            {
                return(HandleIterateArray(node));
            }

            var enumerableType      = typeof(IEnumerable <>).MakeGenericType(node.ItemType);
            var getEnumeratorMethod = enumerableType.GetMethod("GetEnumerator");
            var getCurrentMethod    = getEnumeratorMethod.ReturnType.GetProperty("Current").GetGetMethod();

            var currentElement = Expression.Variable(node.ItemType, "current");
            var hasElements    = Expression.Variable(typeof(bool), "hasElements");
            var enumerator     = Expression.Variable(getEnumeratorMethod.ReturnType, "enumerator");
            var exitLabel      = Expression.Label();

            var collection = ParseExpression(node.Collection);

            if (collection.Type == typeof(object))
            {
                collection = Expression.Convert(collection, enumerableType);
            }

            this.PushScope(currentElement);
            var loopBody = HandleNode(node.Body);

            this.PopScope();

            return(Expression.Block(
                       new[] { enumerator, hasElements },
                       Expression.Assign(hasElements, Expression.Constant(false)),
                       Expression.Assign(enumerator, Expression.Call(collection, getEnumeratorMethod)),
                       Expression.Loop(Expression.Block(
                                           Expression.IfThenElse(Expression.IsFalse(Expression.Call(enumerator, moveNextMethod)),
                                                                 Expression.Break(exitLabel),
                                                                 Expression.Block(
                                                                     new[] { currentElement },
                                                                     Expression.Assign(currentElement, Expression.Property(enumerator, getCurrentMethod)),
                                                                     Expression.Assign(hasElements, Expression.Constant(true)),
                                                                     loopBody
                                                                     )
                                                                 )
                                           ), exitLabel),
                       DisposeIfNeeded(enumerator),
                       Expression.IfThen(Expression.IsFalse(hasElements), HandleNode(node.EmptyBody))
                       ));
        }
示例#7
0
            protected override JSchema VisitIterateNode(IterateNode iterateNode)
            {
                var schema = this.VisitExpressionNode(iterateNode.Collection);

                if (schema == null)
                {
                    return(null);
                }

                var arrayItemSchema = new JSchema();

                schema.Type = JSchemaType.Array;

                _schemas.Push(arrayItemSchema);
                this.VisitBlockNode(iterateNode.Body);
                this.VisitBlockNode(iterateNode.EmptyBody);
                arrayItemSchema = _schemas.Pop();

                schema.Items.Add(arrayItemSchema);

                return(schema);
            }
        private void EmitIterate(IterateNode node)
        {
            var allDone = emitter.DefineLabel();
            var empty   = emitter.DefineLabel();

            if (node.Collection.ResultType.IsArray)
            {
                var done = emitter.DefineLabel();
                var loop = emitter.DefineLabel();
                using (var index = emitter.DeclareLocal(typeof(int)))
                    using (var length = emitter.DeclareLocal(typeof(int)))
                        using (var item = emitter.DeclareLocal(node.ItemType))
                        {
                            EvaluateExpression(node.Collection);
                            emitter.LoadLength(node.ItemType);
                            emitter.StoreLocal(length);

                            emitter.LoadLocal(length);
                            emitter.BranchIfFalse(empty);

                            emitter.LoadConstant(0);
                            emitter.StoreLocal(index);

                            emitter.MarkLabel(loop);
                            emitter.LoadLocal(length);
                            emitter.LoadLocal(index);
                            emitter.CompareEqual();
                            emitter.BranchIfTrue(done);

                            EvaluateExpression(node.Collection);
                            emitter.LoadLocal(index);
                            emitter.LoadElement(node.ItemType);
                            emitter.StoreLocal(item);

                            AddModelScope(e => e.LoadLocal(item));
                            EmitNode(node.Body);
                            RemoveModelScope();

                            emitter.LoadLocal(index);
                            emitter.LoadConstant(1);
                            emitter.Add();
                            emitter.StoreLocal(index);
                            emitter.Branch(loop);

                            emitter.MarkLabel(done);
                            emitter.Branch(allDone);
                        }
            }
            else
            {
                var enumerable        = typeof(IEnumerable <>).MakeGenericType(node.ItemType);
                var getEnumerator     = enumerable.GetMethod("GetEnumerator");
                var getCurrent        = getEnumerator.ReturnType.GetProperty("Current").GetGetMethod();
                var disposeEnumerator = typeof(IDisposable).IsAssignableFrom(getEnumerator.ReturnType);
                var loop = emitter.DefineLabel();
                var done = emitter.DefineLabel();

                EvaluateExpression(node.Collection);

                if (node.Collection.ResultType == typeof(object))
                {
                    emitter.CastClass(enumerable);
                }

                using (var item = emitter.DeclareLocal(node.ItemType))
                    using (var hasItems = emitter.DeclareLocal(typeof(bool)))
                        using (var en = emitter.DeclareLocal(getEnumerator.ReturnType))
                        {
                            emitter.CallMethod(getEnumerator);
                            emitter.StoreLocal(en);

                            emitter.MarkLabel(loop);
                            emitter.LoadLocal(en);
                            emitter.CallMethod(moveNextMethod);
                            emitter.BranchIfFalse(done);

                            emitter.LoadConstant(1);
                            emitter.StoreLocal(hasItems);
                            emitter.LoadLocal(en);
                            emitter.CallMethod(getCurrent);
                            emitter.StoreLocal(item);

                            AddModelScope(e => e.LoadLocal(item));
                            EmitNode(node.Body);
                            RemoveModelScope();

                            emitter.Branch(loop);

                            emitter.MarkLabel(done);

                            if (disposeEnumerator)
                            {
                                emitter.LoadLocal(en);
                                emitter.CallMethod(disposeMethod);
                            }

                            emitter.LoadLocal(hasItems);
                            emitter.BranchIfTrue(allDone);
                        }
            }
            emitter.MarkLabel(empty);
            EmitNode(node.EmptyBody);
            emitter.MarkLabel(allDone);
        }