/// <summary>
        /// Called when the item is a while 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(WhileItem 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);

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

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

            // goto start;
            gen.Emit(OpCodes.Br, start);

            // end:
            gen.MarkLabel(end);

            return target;
        }
        /// <summary>
        /// Called when the item is a while 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(WhileItem target)
        {
            if (target == null)
                throw new ArgumentNullException("target");

            target.Exp.Accept(this);

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

            return target;
        }
示例#3
0
        /// <summary>
        /// Reads a while 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 ReadWhile(ITokenizer input, ref Token prev)
        {
            var debug = input.Read(); // read 'while'
            WhileItem w = new WhileItem();
            if (debug.Value != "while")
                throw new InvalidOperationException(string.Format(Resources.MustBeOn, "while", "ReadWhile"));
            
            // read the expression
            w.Exp = ReadExp(input, ref debug);

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

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

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

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