Пример #1
0
        private static Expression GenerateForLoop(LoopScope loopScope, Token tStart, List<ParameterExpression> loopVars, Expression[] explist)
        {
            const string csFunc = "#f";
            const string csState = "#s";
            const string csVar = "#var";

            ParameterExpression varTmp = Expression.Variable(typeof(LuaResult), "#tmp");
            ParameterExpression varFunc = Expression.Variable(explist.Length > 0 && typeof(Delegate).GetTypeInfo().IsAssignableFrom(explist[0].Type.GetTypeInfo()) ? explist[0].Type : typeof(object), csFunc);
            ParameterExpression varState = Expression.Variable(typeof(object), csState);
            ParameterExpression varVar = Expression.Variable(typeof(object), csVar);

            // local var1, ..., varn = tmp;
            for (int i = 0; i < loopVars.Count; i++)
                loopScope.InsertExpression(i, Expression.Assign(loopVars[i], ConvertExpression(loopScope.Runtime, tStart, GetResultExpression(loopScope.Runtime, tStart, varTmp, i), loopVars[i].Type)));
            return Expression.Block(new ParameterExpression[] { varTmp, varFunc, varState, varVar },
                // fill the local loop variables initial
                // local #f, #s, #var = explist
                Expression.Assign(varTmp, GetLuaResultExpression(loopScope, tStart, explist)),
                Expression.Assign(varFunc, ConvertExpression(loopScope.Runtime, tStart, GetResultExpression(loopScope.Runtime, tStart, varTmp, 0), varFunc.Type)),
                Expression.Assign(varState, GetResultExpression(loopScope.Runtime, tStart, varTmp, 1)),
                Expression.Assign(varVar, GetResultExpression(loopScope.Runtime, tStart, varTmp, 2)),

                Expression.Label(loopScope.ContinueLabel),

                // local tmp = f(s, var)
                Expression.Assign(varTmp, InvokeExpression(loopScope, tStart, varFunc, InvokeResult.LuaResult,
                    new ArgumentsList(varState, varVar), true)
                ),

                // var = tmp[0]
                Expression.Assign(varVar, GetResultExpression(loopScope.Runtime, tStart, varTmp, 0)),

                // if var == nil then goto break;
                Expression.IfThenElse(Expression.Equal(varVar, Expression.Constant(null, typeof(object))),
                    Expression.Goto(loopScope.BreakLabel),
                    loopScope.ExpressionBlock), // LoopBody

                Expression.Goto(loopScope.ContinueLabel),
                Expression.Label(loopScope.BreakLabel)
            );
        }
Пример #2
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)
                ));
        }
Пример #3
0
        private static Expression GenerateForLoop(LoopScope loopScope, Token tStart, ParameterExpression loopVar, Expression loopStart, Expression loopEnd, Expression loopStep)
        {
            const string csVar = "#var";
            const string csEnd = "#end";
            const string csStep = "#step";
            ParameterExpression internLoopVar = Expression.Variable(loopVar.Type, csVar);
            ParameterExpression endVar = Expression.Variable(loopEnd.Type, csEnd);
            ParameterExpression stepVar = Expression.Variable(loopStep.Type, csStep);
            LabelTarget labelLoop = Expression.Label("#loop");

            // Erzeuge CodeBlock
            loopScope.InsertExpression(0, Expression.Assign(loopVar, internLoopVar));

            // Erzeuge den Schleifenblock
            return Expression.Block(new ParameterExpression[] { internLoopVar, endVar, stepVar },
                Expression.Assign(internLoopVar, ConvertExpression(loopScope.Runtime, tStart, loopStart, internLoopVar.Type)),
                Expression.Assign(endVar, loopEnd),
                Expression.Assign(stepVar, loopStep),

                Expression.Label(labelLoop),

                Expression.IfThenElse(
                    BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.OrElse,
                        BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.AndAlso,
                            ConvertExpression(loopScope.Runtime, tStart, BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.GreaterThan, stepVar, Expression.Constant(0, typeof(int))), typeof(bool)),
                            ConvertExpression(loopScope.Runtime, tStart, BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.LessThanOrEqual, internLoopVar, endVar), typeof(bool))
                        ),
                        BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.AndAlso,
                            ConvertExpression(loopScope.Runtime, tStart, BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.LessThanOrEqual, stepVar, Expression.Constant(0, typeof(int))), typeof(bool)),
                            ConvertExpression(loopScope.Runtime, tStart, BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.GreaterThanOrEqual, internLoopVar, endVar), typeof(bool))
                        )
                    ),
                    loopScope.ExpressionBlock,
                    Expression.Goto(loopScope.BreakLabel)
                ),
                Expression.Label(loopScope.ContinueLabel),

                Expression.Assign(internLoopVar, ConvertExpression(loopScope.Runtime, tStart, BinaryOperationExpression(loopScope.Runtime, tStart, ExpressionType.Add, internLoopVar, stepVar), internLoopVar.Type)),

                Expression.Goto(labelLoop),
                Expression.Label(loopScope.BreakLabel)
            );
        }