/// <summary>
        /// Called when the item is a repeat item.
        /// </summary>
        /// <param name="target">The object that was passed to IParseItem.Visit.</param>
        /// <returns>The passed target or a modification of it.</returns>
        /// <exception cref="System.ArgumentNullException">If target is null.</exception>
        public IParseItem Visit(RepeatItem target)
        {
            if (target == null)
                throw new ArgumentNullException("target");

            ILGenerator gen = compiler.CurrentGenerator;
            target.Break.UserData = target.Break.UserData ?? gen.DefineLabel();
            Label start = gen.DefineLabel();
            Label end = (Label)target.Break.UserData;

            // start:
            gen.MarkLabel(start);

            // {Block}
            target.Block.Accept(this);

            // if (!{Exp}.IsTrue) goto start;
            target.Expression.Accept(this);
            gen.Emit(OpCodes.Callvirt, typeof(ILuaValue).GetMethod("get_IsTrue"));
            gen.Emit(OpCodes.Brfalse, start);

            // end:
            gen.MarkLabel(end);

            return target;
        }
        /// <summary>
        /// Called when the item is a repeat item.
        /// </summary>
        /// <param name="target">The object that was passed to IParseItem.Visit.</param>
        /// <returns>The passed target or a modification of it.</returns>
        /// <exception cref="System.ArgumentNullException">If target is null.</exception>
        public IParseItem Visit(RepeatItem target)
        {
            if (target == null)
                throw new ArgumentNullException("target");

            target.Expression.Accept(this);

            using (tree.Block(true))
            {
                tree.DefineLabel(target.Break);
                target.Block.Accept(this);
            }

            return target;
        }
        /// <summary>
        /// Reads a repeat statement from the input.
        /// </summary>
        /// <param name="input">Where to read input from.</param>
        /// <param name="prev">The token to append what is read into.</param>
        /// <returns>The object that was read.</returns>
        protected virtual IParseStatement ReadRepeat(ITokenizer input, ref Token prev)
        {
            var debug = input.Read(); // read 'repeat'
            RepeatItem repeat = new RepeatItem();
            if (debug.Value != "repeat")
                throw new InvalidOperationException(string.Format(Resources.MustBeOn, "repeat", "ReadRepeat"));

            // read the block
            repeat.Block = ReadBlock(input, ref debug);

            // read 'until'
            var name = Read(input, ref debug);
            if (name.Value != "until")
                throw new SyntaxException(
                    string.Format(Resources.TokenInvalidExpecting, name.Value, "repeat", "until"),
                    input.Name, name);

            // read the expression
            repeat.Expression = ReadExp(input, ref debug);

            prev.Append(debug);
            repeat.Debug = debug;
            return repeat;
        }