Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }