private static void ParseWhileLoop(Scope scope, LuaLexer code) { // while expr do block end; LoopScope loopScope = new LoopScope(scope); // get the expression FetchToken(LuaToken.KwWhile, code); loopScope.AddExpression(Expression.Label(loopScope.ContinueLabel)); loopScope.AddExpression( Expression.IfThenElse( ConvertExpression(scope.Runtime, code.Current, ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug), typeof(bool)), Expression.Empty(), Expression.Goto(loopScope.BreakLabel) ) ); // append the block FetchToken(LuaToken.KwDo, code); ParseBlock(loopScope, code); FetchToken(LuaToken.KwEnd, code); // goto continue loopScope.AddExpression(Expression.Goto(loopScope.ContinueLabel)); loopScope.AddExpression(Expression.Label(loopScope.BreakLabel)); scope.AddExpression(loopScope.ExpressionBlock); }
private static void ParseDoLoop(Scope scope, LuaLexer code) { // doloop ::= do '(' name { ',' name } = expr { ',' expr } ')' block end // create empty block, that can used as an loop Scope outerScope = new Scope(scope); Expression[] exprFinally = null; // fetch do FetchToken(LuaToken.KwDo, code); if (code.Current.Typ == LuaToken.BracketOpen) // look for disposable variables { code.Next(); ParseExpressionStatement(outerScope, code, true); // Build finally-Block for the declared variables exprFinally = ( from c in outerScope.Variables select Expression.IfThen( Expression.TypeIs(c, typeof(IDisposable)), Expression.Call(Expression.Convert(c, typeof(IDisposable)), Lua.DisposeDisposeMethodInfo) )).ToArray(); FetchToken(LuaToken.BracketClose, code); } LoopScope loopScope = new LoopScope(outerScope); // Add the Contine label after the declaration loopScope.AddExpression(Expression.Label(loopScope.ContinueLabel)); // parse the block ParseBlock(loopScope, code); // create the break label loopScope.AddExpression(Expression.Label(loopScope.BreakLabel)); FetchToken(LuaToken.KwEnd, code); if (exprFinally != null && exprFinally.Length > 0) { outerScope.AddExpression( Expression.TryFinally( loopScope.ExpressionBlock, Expression.Block(exprFinally) ) ); scope.AddExpression(outerScope.ExpressionBlock); } else scope.AddExpression(loopScope.ExpressionBlock); }
private static void ParseRepeatLoop(Scope scope, LuaLexer code) { LoopScope loopScope = new LoopScope(scope); // continue label loopScope.AddExpression(Expression.Label(loopScope.ContinueLabel)); // loop content FetchToken(LuaToken.KwRepeat, code); ParseBlock(loopScope, code); // get the loop expression FetchToken(LuaToken.KwUntil, code); loopScope.AddExpression( Expression.IfThenElse( ConvertExpression(scope.Runtime, code.Current, ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug), typeof(bool)), Expression.Empty(), Expression.Goto(loopScope.ContinueLabel) ) ); loopScope.AddExpression(Expression.Label(loopScope.BreakLabel)); scope.AddExpression(loopScope.ExpressionBlock); }