Пример #1
0
        private static void ParseForEachLoop(Scope scope, LuaLexer code)
        {
            ParameterExpression varEnumerable = Expression.Variable(typeof(System.Collections.IEnumerable), "#enumerable");
            ParameterExpression varEnumerator = Expression.Variable(typeof(System.Collections.IEnumerator), "#enumerator");

            // foreach name in exp do block end;
            code.Next(); // foreach

            // fetch the loop variable
            LoopScope loopScope = new LoopScope(scope);
            Token tLoopVar;
            Type typeLoopVar;
            ParseIdentifierAndType(scope, code, out tLoopVar, out typeLoopVar);
            ParameterExpression loopVar = loopScope.RegisterVariable(typeLoopVar, tLoopVar.Value);

            // get the enumerable expression
            FetchToken(LuaToken.KwIn, code);
            Expression exprEnum = Lua.EnsureType(ParseExpression(scope, code, InvokeResult.None, scope.EmitExpressionDebug), typeof(object));

            // parse the loop body
            FetchToken(LuaToken.KwDo, code);
            ParseBlock(loopScope, code);
            FetchToken(LuaToken.KwEnd, code);

            loopScope.InsertExpression(0, Expression.Assign(loopVar, ConvertExpression(scope.Runtime, tLoopVar, Expression.Property(varEnumerator, Lua.EnumeratorCurrentPropertyInfo), loopVar.Type)));
            scope.AddExpression(
                Expression.Block(new ParameterExpression[] { varEnumerable, varEnumerator, loopVar },
                // local enumerable = exprEnum as IEnumerator
                Expression.Assign(varEnumerable, Expression.TypeAs(exprEnum, typeof(System.Collections.IEnumerable))),

                // if enumerable == nil then error
                Expression.IfThen(Expression.Equal(varEnumerable, Expression.Constant(null, typeof(object))), Lua.ThrowExpression(Properties.Resources.rsExpressionNotEnumerable)),

                // local enum = exprEnum.GetEnumerator()
                Expression.Assign(varEnumerator, Expression.Call(varEnumerable, Lua.EnumerableGetEnumeratorMethodInfo)),

                // while enum.MoveNext() do
                Expression.Label(loopScope.ContinueLabel),
                Expression.IfThenElse(Expression.Call(varEnumerator, Lua.EnumeratorMoveNextMethodInfo), Expression.Empty(), Expression.Goto(loopScope.BreakLabel)),

                //   loopVar = enum.Current
                loopScope.ExpressionBlock,

                // end;
                Expression.Goto(loopScope.ContinueLabel),
                Expression.Label(loopScope.BreakLabel)
                ));
        }
Пример #2
0
        private static void ParseForLoop(Scope scope, LuaLexer code)
        {
            // for name
            FetchToken(LuaToken.KwFor, code);
            Token tLoopVar;
            Type typeLoopVar;
            ParseIdentifierAndType(scope, code, out tLoopVar, out typeLoopVar);
            if (code.Current.Typ == LuaToken.Assign)
            {
                // = exp, exp [, exp] do block end
                FetchToken(LuaToken.Assign, code);
                Expression loopStart = ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug);
                FetchToken(LuaToken.Comma, code);
                Expression loopEnd = ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug);
                Expression loopStep;
                if (code.Current.Typ == LuaToken.Comma)
                {
                    code.Next();
                    loopStep = ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug);
                }
                else
                    loopStep = Expression.Constant(1, loopStart.Type);

                LoopScope loopScope = new LoopScope(scope);
                ParameterExpression loopVarParameter = loopScope.RegisterVariable(typeLoopVar == typeof(object) ? LuaEmit.LiftType(LuaEmit.LiftType(loopStart.Type, loopEnd.Type), loopStep.Type) : typeLoopVar, tLoopVar.Value);

                FetchToken(LuaToken.KwDo, code);
                ParseBlock(loopScope, code);
                FetchToken(LuaToken.KwEnd, code);
                scope.AddExpression(GenerateForLoop(loopScope, tLoopVar, loopVarParameter, loopStart, loopEnd, loopStep));
            }
            else
            {
                // {, name} in explist do block end

                // fetch all loop variables
                LoopScope loopScope = new LoopScope(scope);
                List<ParameterExpression> loopVars = new List<ParameterExpression>();
                loopVars.Add(loopScope.RegisterVariable(typeLoopVar, tLoopVar.Value));
                while (code.Current.Typ == LuaToken.Comma)
                {
                    code.Next();
                    ParseIdentifierAndType(scope, code, out tLoopVar, out typeLoopVar);
                    loopVars.Add(loopScope.RegisterVariable(typeLoopVar, tLoopVar.Value));
                }

                // get the loop expressions
                FetchToken(LuaToken.KwIn, code);
                Expression[] explist = ParseExpressionList(scope, code).ToArray();

                // parse the loop body
                FetchToken(LuaToken.KwDo, code);
                ParseBlock(loopScope, code);
                FetchToken(LuaToken.KwEnd, code);

                scope.AddExpression(GenerateForLoop(loopScope, tLoopVar, loopVars, explist));
            }
        }