/// <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; }
/// <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; }