Example #1
0
    } // func T

    private bool TokenTest(string sToken, params KeyValuePair<LuaToken, string>[] token)
    {
      using (LuaLexer l = new LuaLexer("test.lua", new StringReader(sToken)))
      {
        l.Next();

        for (int i = 0; i < token.Length; i++)
        {
          Debug.Write(String.Format("Test: {0} = {1} ==>", l.Current.Typ, token[i].Key));
          if (l.Current.Typ != token[i].Key)
          {
            Debug.WriteLine("tokens FAILED");
            return false;
          }
          else if (l.Current.Value != token[i].Value)
          {
            Debug.WriteLine("values '{0}' != '{1}'   FAILED", l.Current.Value, token[i].Value);
            return false;
          }
          Debug.WriteLine("OK");
          l.Next();
        }
        if (l.Current.Typ != LuaToken.Eof)
          return false;
        return true;
      }
    } // func TokenTest
Example #2
0
        /// <summary>Parses the chunk to an function.</summary>
        /// <param name="runtime">Binder</param>
        /// <param name="options">Compile options for the script.</param>
        /// <param name="lHasEnvironment">Creates the _G parameter.</param>
        /// <param name="code">Lexer for the code.</param>
        /// <param name="typeDelegate">Type for the delegate. <c>null</c>, for an automatic type</param>
        /// <param name="returnType">Defines the return type of the chunk.</param>
        /// <param name="args">Arguments of the function.</param>
        /// <returns>Expression-Tree for the code.</returns>
        public static LambdaExpression ParseChunk(Lua runtime, LuaCompileOptions options, bool lHasEnvironment, LuaLexer code, Type typeDelegate, Type returnType, IEnumerable<KeyValuePair<string, Type>> args)
        {
            List<ParameterExpression> parameters = new List<ParameterExpression>();
            if (returnType == null)
                returnType = typeof(LuaResult);
            var globalScope = new GlobalScope(runtime, options, returnType, returnType == typeof(LuaResult) ? Expression.Property(null, Lua.ResultEmptyPropertyInfo) : null);

            // Registers the global LuaTable
            if (lHasEnvironment)
                parameters.Add(globalScope.RegisterParameter(typeof(LuaTable), csEnv));

            if (args != null)
            {
                foreach (var c in args)
                    parameters.Add(globalScope.RegisterParameter(c.Value, c.Key)); // Add alle arguments
            }

            // Get the first token
            if (code.Current == null)
                code.Next();

            // Get the name for the chunk and clean it from all unwanted chars
            string sChunkName = CreateNameFromFile(code.Current.Start.FileName);
              if ((globalScope.EmitDebug & LuaDebugLevel.RegisterMethods) == LuaDebugLevel.RegisterMethods)
                sChunkName = Lua.RegisterUniqueName(sChunkName);

            // Create the block
            ParseBlock(globalScope, code);

            if (code.Current.Typ != LuaToken.Eof)
                throw ParseError(code.Current, Properties.Resources.rsParseEof);

            // Create the function
            return typeDelegate == null ?
                Expression.Lambda(globalScope.ExpressionBlock, sChunkName, parameters) :
                Expression.Lambda(typeDelegate, globalScope.ExpressionBlock, sChunkName, parameters);
        }
Example #3
0
        private static Expression ParseTableConstructor(Scope scope, LuaLexer code)
        {
            // table ::= '{' [field] { fieldsep field } [fieldsep] '}'
            // fieldsep ::= ',' | ';'
            FetchToken(LuaToken.BracketCurlyOpen, code);

            if (code.Current.Typ != LuaToken.BracketCurlyClose)
            {
                int iIndex = 1;
                Scope scopeTable = new Scope(scope);

                // Create the variable for the table
                ParameterExpression tableVar = scopeTable.RegisterVariable(typeof(LuaTable), "#table");
                scopeTable.AddExpression(Expression.Assign(tableVar, CreateEmptyTableExpression()));

                // fiest field
                ParseTableField(tableVar, scopeTable, code, ref iIndex);

                // collect more table fields
                while (code.Current.Typ == LuaToken.Comma || code.Current.Typ == LuaToken.Semicolon)
                {
                    code.Next();

                    // Optional last separator
                    if (code.Current.Typ == LuaToken.BracketCurlyClose)
                        break;

                    // Parse the field
                    ParseTableField(tableVar, scopeTable, code, ref iIndex);
                }

                scopeTable.AddExpression(tableVar);
                scopeTable.ExpressionBlockType = typeof(LuaTable);

                // Closing bracket
                FetchToken(LuaToken.BracketCurlyClose, code);

                return scopeTable.ExpressionBlock;
            }
            else
            {
                FetchToken(LuaToken.BracketCurlyClose, code);
                return CreateEmptyTableExpression();
            }
        }
Example #4
0
 private static LuaType ParseFirstType(Scope scope, LuaLexer code)
 {
     string sType = FetchToken(LuaToken.Identifier, code).Value;
     LuaType luaType = LuaType.GetCachedType(sType);
     if (luaType == null)
     {
         ConstantExpression expr = scope.LookupExpression(sType, false) as ConstantExpression;
         if (expr != null && expr.Type == typeof(LuaType))
             return (LuaType)expr.Value;
         else
             return LuaType.GetType(LuaType.Clr.GetIndex(sType, false, null));
     }
     else
         return luaType;
 }
Example #5
0
        private static void ParseExpressionStatement(Scope scope, LuaLexer code, bool lLocal)
        {
            List<ParameterExpression> registerLocals = null;
            List<PrefixMemberInfo> prefixes = new List<PrefixMemberInfo>();

            // parse the assgiee list (var0, var1, var2, ...)
            while (true)
            {
                if (lLocal) // parse local variables
                {
                    Token tVar;
                    Type typeVar;
                    ParseIdentifierAndType(scope, code, out tVar, out typeVar);

                    ParameterExpression exprVar = scope.LookupExpression(tVar.Value, true) as ParameterExpression;
                    if (exprVar == null)
                    {
                        exprVar = Expression.Variable(typeVar, tVar.Value);
                        if (registerLocals == null)
                            registerLocals = new List<ParameterExpression>();
                        registerLocals.Add(exprVar);
                    }
                    else if (exprVar.Type != typeVar)
                        throw ParseError(tVar, Properties.Resources.rsParseTypeRedef);

                    prefixes.Add(new PrefixMemberInfo(tVar, exprVar, null, null, null));
                }
                else // parse a assignee
                {
                    // parse as a prefix
                    prefixes.Add(ParsePrefix(scope, code));
                }

                // is there another prefix
                if (code.Current.Typ == LuaToken.Comma)
                    code.Next();
                else
                    break;
            }

            // Optional assign
            if (code.Current.Typ == LuaToken.Assign)
            {
                code.Next();

                // parse all expressions
                IEnumerator<Expression> expr = ParseExpressionList(scope, code).GetEnumerator();
                expr.MoveNext();

                if (prefixes.Count == 1) // one expression, one variable?
                {
                    scope.AddExpression(
                        prefixes[0].GenerateSet(scope, expr.Current != null ? expr.Current : Expression.Constant(null, typeof(object)))
                    );
                }
                else if (expr.Current == null) // No expression, assign null
                {
                    for (int i = 0; i < prefixes.Count; i++)
                        scope.AddExpression(prefixes[i].GenerateSet(scope, Expression.Constant(null, typeof(object))));
                }
                else // assign on an unknown number of expressions
                {
                    #region -- unknown number --
                    List<ParameterExpression> assignTempVars = new List<ParameterExpression>();
                    List<Expression> assignExprs = new List<Expression>();
                    int iExpressionVarOffset;

                    // Safe the prefixes in variables
                    for (int k = 0; k < prefixes.Count; k++)
                    {
                        var p = prefixes[k];
                        if (p.Member != null || prefixes[k].Indices != null)
                        {
                            p.Instance = ParseExpressionStatementExchangeToTempVar(assignTempVars, assignExprs, p.Instance);

                            if (p.Indices != null)
                            {
                                for (int l = 0; l < p.Indices.Length; l++)
                                    p.Indices[l] = ParseExpressionStatementExchangeToTempVar(assignTempVars, assignExprs, p.Indices[l]);
                            }
                        }
                    }

                    // collect the results of the expressions
                    iExpressionVarOffset = assignTempVars.Count;
                    do
                    {
                        ParseExpressionStatementExchangeToTempVar(assignTempVars, assignExprs, expr.Current);
                    } while (expr.MoveNext());

                    // Assign the Result to the prefixes
                    int i = 0;
                    int j = 0;
                    ParameterExpression lastVariable = null;
                    while (i < prefixes.Count)
                    {
                        if (i < assignTempVars.Count - iExpressionVarOffset) // are the variables
                        {
                            if (i == assignTempVars.Count - iExpressionVarOffset - 1 && assignTempVars[i + iExpressionVarOffset].Type == typeof(LuaResult)) // check if the last expression is a LuaResult
                            {
                                lastVariable = assignTempVars[i + iExpressionVarOffset];
                                assignExprs.Add(prefixes[i].GenerateSet(scope, GetResultExpression(scope.Runtime, code.Current, lastVariable, j++)));
                            }
                            else
                            {
                                assignExprs.Add(prefixes[i].GenerateSet(scope, assignTempVars[i + iExpressionVarOffset]));
                            }
                        }
                        else if (lastVariable != null) // we enroll the last expression
                        {
                            assignExprs.Add(prefixes[i].GenerateSet(scope, GetResultExpression(scope.Runtime, code.Current, lastVariable, j++)));
                        }
                        else // no variable left
                        {
                            assignExprs.Add(prefixes[i].GenerateSet(scope, Expression.Default(typeof(object))));
                        }
                        i++;
                    }

                    // add the block
                    scope.AddExpression(Expression.Block(assignTempVars, assignExprs));

                    #endregion
                }

                // Führe die restlichen Expressions aus
                while (expr.MoveNext())
                    scope.AddExpression(expr.Current);
            }
            else if (!lLocal)
            {
                for (int i = 0; i < prefixes.Count; i++)
                {
                    if (prefixes[i].Arguments == null) // do not execute getMember
                        throw ParseError(prefixes[i].Position, Properties.Resources.rsParseAssignmentExpected);

                    scope.AddExpression(prefixes[i].GenerateGet(scope, InvokeResult.None));
                }
            }

            // register the variables
            if (registerLocals != null)
            {
                for (int i = 0; i < registerLocals.Count; i++)
                    scope.RegisterVariable(registerLocals[i]);
            }
        }
Example #6
0
        private static Expression ParseExpressionPower(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // expPow ::= cast [ ^ expPow ]
            Expression expr = ParseExpressionCast(scope, code, result, ref lWrap);

            if (code.Current.Typ == LuaToken.Caret)
            {
                code.Next();
                lWrap |= true;
                return BinaryOperationExpression(scope.Runtime, code.Current, ExpressionType.Power, expr, ParseExpressionPower(scope, code, InvokeResult.Object, ref lWrap));
            }
            else
                return expr;
        }
Example #7
0
        private static Expression ParseExpressionOr(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // exprOr ::= exprAnd { or exprAnd }
            var expr = ParseExpressionAnd(scope, code, result, ref lWrap);

            while (code.Current.Typ == LuaToken.KwOr)
            {
                code.Next();
                expr = BinaryOperationExpression(scope.Runtime, code.Current, ExpressionType.OrElse, expr, ParseExpressionAnd(scope, code, InvokeResult.Object, ref lWrap));
                lWrap |= true;
            }

            return expr;
        }
Example #8
0
        private static IEnumerable<Expression> ParseExpressionList(Scope scope, LuaLexer code)
        {
            while (true)
            {
                yield return ParseExpression(scope, code, InvokeResult.LuaResult, scope.EmitExpressionDebug);

                // Noch eine Expression
                if (code.Current.Typ == LuaToken.Comma)
                    code.Next();
                else
                    break;
            }
        }
Example #9
0
        private static void ParseBreak(Scope scope, LuaLexer code)
        {
            FetchToken(LuaToken.KwBreak, code);

            // Erzeuge die Expression
            scope.AddExpression(Expression.Goto(scope.LookupLabel(null, csBreakLabel)));

            // Optionales Semicolon
            FetchToken(LuaToken.Semicolon, code, true);
        }
Example #10
0
        private static void ParseBlock(Scope scope, LuaLexer code)
        {
            // Lese die Statement
            int iLastDebugInfo = -1;
            bool lLoop = true;
            while (lLoop)
            {
                bool lDebugInfoEmitted = false;

                if ((scope.EmitDebug & LuaDebugLevel.Line) != 0) // debug info for line
                {
                    if (code.Current.Start.Line != iLastDebugInfo)
                    {
                        iLastDebugInfo = code.Current.Start.Line;
                        scope.AddExpression(GetDebugInfo(code.Current, code.Current));
                        lDebugInfoEmitted = true;
                    }
                }

                switch (code.Current.Typ)
                {
                    case LuaToken.Eof: // End of file
                        lLoop = false;
                        break;

                    case LuaToken.KwReturn: //  The return-statement is only allowed on the end of a scope
                        ParseReturn(scope, code);
                        break;

                    case LuaToken.KwBreak: // The break-statement is only allowed on the end of a scope
                        ParseBreak(scope, code);
                        lLoop = false;
                        break;

                    case LuaToken.Semicolon: // End of statement => ignore
                        code.Next();
                        break;

                    default:
                        if (!lDebugInfoEmitted && (scope.EmitDebug & LuaDebugLevel.Expression) != 0) // Start every statement with a debug point
                            scope.AddExpression(GetDebugInfo(code.Current, code.Current));

                        if (!ParseStatement(scope, code)) // Parse normal statements
                            lLoop = false;
                        break;
                }
            }
            if (scope.EmitDebug != LuaDebugLevel.None)
                scope.AddExpression(Expression.ClearDebugInfo(code.Current.Start.Document)); // Clear debug info
        }
Example #11
0
        private static ArgumentsList ParseArgumentList(Scope scope, LuaLexer code)
        {
            FetchToken(LuaToken.BracketOpen, code);

            // exprArgumentList := '(' [ exprArg { , exprArg } ] ')'
            var argumentsList = new ArgumentsList();
            while (code.Current.Typ != LuaToken.BracketClose)
            {
                Token tName = null;
                if (code.LookAhead.Typ == LuaToken.Assign) // named argument
                {
                    tName = FetchToken(LuaToken.Identifier, code);
                    code.Next(); // equal
                }

                // parse the expression
                var tFirst = code.Current;
                var expr = ParseExpression(scope, code, InvokeResult.LuaResult, scope.EmitExpressionDebug);

                if (tName == null)
                    argumentsList.AddPositionalArgument(tFirst, expr);
                else
                    argumentsList.AddNamedArgument(tName, expr);

                // optinal comma
                FetchToken(LuaToken.Comma, code, true);
            }
            code.Next();
            return argumentsList;
        }
Example #12
0
 private static bool IsExpressionStart(LuaLexer code)
 {
     return code.Current.Typ == LuaToken.BracketOpen ||
         code.Current.Typ == LuaToken.Identifier ||
         code.Current.Typ == LuaToken.DotDotDot ||
         code.Current.Typ == LuaToken.String ||
         code.Current.Typ == LuaToken.Number ||
         code.Current.Typ == LuaToken.KwTrue ||
         code.Current.Typ == LuaToken.KwFalse ||
         code.Current.Typ == LuaToken.KwNil ||
         code.Current.Typ == LuaToken.BracketCurlyOpen ||
         code.Current.Typ == LuaToken.Minus ||
         code.Current.Typ == LuaToken.Dilde ||
         code.Current.Typ == LuaToken.Cross ||
         code.Current.Typ == LuaToken.KwNot ||
         code.Current.Typ == LuaToken.KwFunction ||
         code.Current.Typ == LuaToken.KwCast;
 }
Example #13
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);
        }
Example #14
0
        private static LuaType ParseType(Scope scope, LuaLexer code, bool lNeedType)
        {
            // is the first token an alias
            LuaType currentType = ParseFirstType(scope, code);

            while (code.Current.Typ == LuaToken.Dot ||
                        code.Current.Typ == LuaToken.Plus ||
                        code.Current.Typ == LuaToken.BracketSquareOpen)
            {
                if (code.Current.Typ == LuaToken.BracketSquareOpen)
                {
                    List<LuaType> genericeTypes = new List<LuaType>();
                    code.Next();
                    if (code.Current.Typ != LuaToken.BracketSquareClose)
                    {
                        genericeTypes.Add(ParseType(scope, code, lNeedType));
                        while (code.Current.Typ == LuaToken.Comma)
                        {
                            code.Next();
                            genericeTypes.Add(ParseType(scope, code, lNeedType));
                        }
                    }
                    FetchToken(LuaToken.BracketSquareClose, code);

                    if (genericeTypes.Count == 0) // create a array at the end
                    {
                        if (currentType.Type == null)
                            throw ParseError(code.Current, String.Format(Properties.Resources.rsParseUnknownType, currentType.FullName));

                        currentType = LuaType.GetType(currentType.GetIndex("[]", false, () => currentType.Type.MakeArrayType()));
                    }
                    else // build a generic type
                    {
                        var typeGeneric = LuaType.GetType(currentType.FullName + "`" + genericeTypes.Count.ToString()).Type;
                        if (typeGeneric == null)
                            throw ParseError(code.Current, String.Format(Properties.Resources.rsParseUnknownType, currentType.FullName));

                        currentType = LuaType.GetType(currentType.GetGenericItem(typeGeneric, genericeTypes.ToArray()));
                    }
                }
                else
                {
                    code.Next();
                    currentType = LuaType.GetType(currentType.GetIndex(FetchToken(LuaToken.Identifier, code).Value, false, null));
                }
            }

            if (lNeedType && currentType.Type == null)
                throw ParseError(code.Current, String.Format(Properties.Resources.rsParseUnknownType, currentType.FullName));

            return currentType;
        }
Example #15
0
        private static void ParseTableField(ParameterExpression tableVar, Scope scope, LuaLexer code, ref int iIndex)
        {
            // field ::= '[' exp ']' '=' exp | Name '=' exp | exp
            if (code.Current.Typ == LuaToken.BracketSquareOpen)
            {
                // Parse the index
                code.Next();
                var index = ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug);
                FetchToken(LuaToken.BracketSquareClose, code);
                FetchToken(LuaToken.Assign, code);

                // Expression that results in a value
                scope.AddExpression(
                    IndexSetExpression(scope.Runtime, code.Current, tableVar, new Expression[] { index },
                        ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug)
                    )
                );

            }
            else if (code.Current.Typ == LuaToken.Identifier && code.LookAhead.Typ == LuaToken.Assign)
            {
                // Read the identifier
                Token tMember = code.Current;
                code.Next();
                FetchToken(LuaToken.Assign, code);

                // Expression
                scope.AddExpression(
                    IndexSetExpression(scope.Runtime, code.Current, tableVar, new Expression[] { Expression.Constant(tMember.Value) },
                        ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug)
                    )
                );
            }
            else
            {
                Token tStart = code.Current;
                Expression expr = ParseExpression(scope, code, InvokeResult.None, scope.EmitExpressionDebug);

                // Last assign, enroll parameter
                if (code.Current.Typ == LuaToken.BracketCurlyClose && LuaEmit.IsDynamicType(expr.Type))
                {
                    scope.AddExpression(
                        Expression.Call(Lua.TableSetObjectsMethod,
                            tableVar,
                            Expression.Convert(expr, typeof(object)),
                            Expression.Constant(iIndex, typeof(int))
                        )
                    );
                }
                else // Normal index set
                {
                    scope.AddExpression(
                        IndexSetExpression(scope.Runtime, code.Current, tableVar, new Expression[] { Expression.Constant(iIndex++, typeof(object)) }, expr)
                    );
                }
            }
        }
Example #16
0
 private static Expression ParseExpressionCast(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
 {
     // cast ::= cast(type, expr)
     if (code.Current.Typ == LuaToken.KwCast)
     {
         Token tStart = code.Current;
         lWrap |= true;
         PrefixMemberInfo prefix = new PrefixMemberInfo(tStart, ParsePrefixCast(scope, code), null, null, null);
         ParseSuffix(scope, code, prefix);
         return prefix.GenerateGet(scope, result);
     }
     else
         return ParsePrefix(scope, code).GenerateGet(scope, result);
 }
Example #17
0
        private static Expression ParseExpressionCmp(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // expCmd ::= expCon { ( < | > | <= | >= | ~= | == ) expCon }
            Token tStart = code.Current;
            var expr = ParseExpressionCon(scope, code, result, ref lWrap);

            while (true)
            {
                LuaToken tokenTyp = code.Current.Typ;
                ExpressionType exprTyp;
                if (tokenTyp == LuaToken.Lower)
                    exprTyp = ExpressionType.LessThan;
                else if (tokenTyp == LuaToken.Greater)
                    exprTyp = ExpressionType.GreaterThan;
                else if (tokenTyp == LuaToken.LowerEqual)
                    exprTyp = ExpressionType.LessThanOrEqual;
                else if (tokenTyp == LuaToken.GreaterEqual)
                    exprTyp = ExpressionType.GreaterThanOrEqual;
                else if (tokenTyp == LuaToken.NotEqual)
                    exprTyp = ExpressionType.NotEqual;
                else if (tokenTyp == LuaToken.Equal)
                    exprTyp = ExpressionType.Equal;
                else
                    return expr;
                code.Next();

                expr = BinaryOperationExpression(scope.Runtime, code.Current, exprTyp, expr, ParseExpressionCon(scope, code, InvokeResult.Object, ref lWrap));
                lWrap |= true;
            }
        }
Example #18
0
        private static void ParseConst(Scope scope, LuaLexer code)
        {
            // const ::= variable '=' ( expr | clr '.' Type )

            Token tVarName;
            Type typeVar;
            ParseIdentifierAndType(scope, code, out tVarName, out typeVar);

            if (code.Current.Typ == LuaToken.Identifier || code.Current.Value == "typeof")
            {
                code.Next();

                // Parse the type
                scope.RegisterConst(tVarName.Value, Expression.Constant(ParseType(scope, code, false)));
            }
            else
            {
                FetchToken(LuaToken.Assign, code);

                Expression exprConst = ParseExpression(scope, code, InvokeResult.Object, false); // No Debug-Emits
                if (typeVar != typeof(object))
                    exprConst = ConvertExpression(scope.Runtime, tVarName, exprConst, typeVar);

                // Try to eval the statement
                if (exprConst.Type == typeof(object) || exprConst.Type == typeof(LuaResult)) // dynamic calls, no constant possible
                    throw ParseError(tVarName, Properties.Resources.rsConstExpressionNeeded);
                else
                    try
                    {
                        object r = EvaluateExpression(exprConst);
                        if (r == null) // Eval via compile
                        {
                            Type typeFunc = Expression.GetFuncType(exprConst.Type);
                            LambdaExpression exprEval = Expression.Lambda(typeFunc, exprConst);
                            Delegate dlg = exprEval.Compile();
                            r = dlg.DynamicInvoke();
                        }
                        scope.RegisterConst(tVarName.Value, Expression.Constant(r, exprConst.Type));
                    }
                    catch (Exception e)
                    {
                        throw ParseError(tVarName, String.Format(Properties.Resources.rsConstExpressionEvalError, e.Message));
                    }
            }
        }
Example #19
0
        private static Expression ParseExpressionCon(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // exprCon::= exprShift { '..' exprShift }
            List<Expression> exprs = new List<Expression>();
            exprs.Add(ParseExpressionShift(scope, code, result, ref lWrap));

            while (code.Current.Typ == LuaToken.DotDot)
            {
                code.Next();
                exprs.Add(ParseExpressionShift(scope, code, InvokeResult.Object, ref lWrap));
            }

            // Erzeuge Concat
            if (exprs.Count > 1)
            {
                lWrap |= true;
                return ConcatOperationExpression(scope.Runtime, code.Current, exprs.ToArray());
            }
            else
                return exprs[0];
        }
Example #20
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);
        }
Example #21
0
        private static Expression ParseExpressionMultiply(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // expMul ::= expUn { ( * | / | // | % ) expUn }
            var expr = ParseExpressionUnary(scope, code, result, ref lWrap);

            while (true)
            {
                LuaToken tokenTyp = code.Current.Typ;
                ExpressionType exprTyp;
                if (tokenTyp == LuaToken.Star)
                    exprTyp = ExpressionType.Multiply;
                else if (tokenTyp == LuaToken.Slash)
                    exprTyp = ExpressionType.Divide;
                else if (tokenTyp == LuaToken.SlashShlash)
                    exprTyp = Lua.IntegerDivide;
                else if (tokenTyp == LuaToken.Percent)
                    exprTyp = ExpressionType.Modulo;
                else
                    return expr;

                code.Next();

                expr = BinaryOperationExpression(scope.Runtime, code.Current, exprTyp, expr, ParseExpressionUnary(scope, code, InvokeResult.Object, ref lWrap));
                lWrap |= true;
            }
        }
Example #22
0
        private static Expression ParseElseStatement(Scope scope, LuaLexer code)
        {
            if (code.Current.Typ == LuaToken.KwElseif)
            {
                code.Next();
                var expr = ConvertExpression(scope.Runtime, code.Current, ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug), typeof(bool));
                FetchToken(LuaToken.KwThen, code);

                return Expression.IfThenElse(expr, ParseIfElseBlock(scope, code), ParseElseStatement(scope, code));
            }
            else if (code.Current.Typ == LuaToken.KwElse)
            {
                code.Next();
                var block = ParseIfElseBlock(scope, code);
                FetchToken(LuaToken.KwEnd, code);
                return block;
            }
            else if (code.Current.Typ == LuaToken.KwEnd)
            {
                code.Next();
                return Expression.Empty();
            }
            else
                throw ParseError(code.Current, Properties.Resources.rsParseUnexpectedTokenElse);
        }
Example #23
0
        private static Expression ParseExpressionPlus(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // expPlus ::= expMul { ( + | - ) expMul}
            var expr = ParseExpressionMultiply(scope, code, result, ref lWrap);

            while (true)
            {
                LuaToken tokenTyp = code.Current.Typ;
                ExpressionType exprTyp;
                if (tokenTyp == LuaToken.Plus)
                    exprTyp = ExpressionType.Add;
                else if (tokenTyp == LuaToken.Minus)
                    exprTyp = ExpressionType.Subtract;
                else
                    return expr;

                code.Next();
                expr = BinaryOperationExpression(scope.Runtime, code.Current, exprTyp, expr, ParseExpressionMultiply(scope, code, InvokeResult.Object, ref lWrap));
                lWrap |= true;
            }
        }
Example #24
0
 private static Expression ParseExpression(Scope scope, LuaLexer code, InvokeResult result, bool lDebug)
 {
     Token tStart = code.Current;
     bool lWrap = false;
     Expression expr = ParseExpression(scope, code, result, ref lWrap);
     if (lWrap && lDebug)
         return WrapDebugInfo(true, false, tStart, code.Current, expr);
     else
         return expr;
 }
Example #25
0
        private static Expression ParseExpressionShift(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // exprBitAnd ::= exprCmp { ( << | >> ) exprCmp }
            var expr = ParseExpressionPlus(scope, code, result, ref lWrap);

            while (true)
            {
                LuaToken tokenTyp = code.Current.Typ;
                ExpressionType exprTyp;

                if (tokenTyp == LuaToken.ShiftLeft)
                    exprTyp = ExpressionType.LeftShift;
                else if (tokenTyp == LuaToken.ShiftRight)
                    exprTyp = ExpressionType.RightShift;
                else
                    return expr;

                code.Next();
                expr = BinaryOperationExpression(scope.Runtime, code.Current, exprTyp, expr, ParseExpressionPlus(scope, code, InvokeResult.Object, ref lWrap));
                lWrap |= true;
            }
        }
Example #26
0
 private static Expression ParseExpression(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
 {
     // expr ::= exprOr
     return ParseExpressionOr(scope, code, result, ref lWrap);
 }
Example #27
0
        private static Expression ParseExpressionUnary(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // expUn ::= { 'not' | - | # | ~ } expPow
            LuaToken typ = code.Current.Typ;
            if (typ == LuaToken.KwNot ||
                    typ == LuaToken.Minus ||
                    typ == LuaToken.Dilde ||
                    typ == LuaToken.Cross)
            {
                code.Next();
                Expression expr = ParseExpressionUnary(scope, code, InvokeResult.Object, ref lWrap);
                lWrap |= true;

                ExpressionType exprType;
                if (typ == LuaToken.KwNot)
                    exprType = ExpressionType.Not;
                else if (typ == LuaToken.Minus)
                    exprType = ExpressionType.Negate;
                else if (typ == LuaToken.Dilde)
                    exprType = ExpressionType.OnesComplement;
                else
                    exprType = ExpressionType.ArrayLength;

                lWrap |= true;
                return UnaryOperationExpression(scope.Runtime, code.Current, exprType, expr);
            }
            else
                return ParseExpressionPower(scope, code, result, ref lWrap);
        }
Example #28
0
        private static Expression ParseExpressionBitAnd(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // exprBitAnd ::= exprCmp { & exprCmp }
            var expr = ParseExpressionCmp(scope, code, result, ref lWrap);

            while (code.Current.Typ == LuaToken.BitAnd)
            {
                code.Next();
                expr = BinaryOperationExpression(scope.Runtime, code.Current, ExpressionType.And,
                    expr,
                    ParseExpressionCmp(scope, code, InvokeResult.Object, ref lWrap)
                );
                lWrap |= true;
            }

            return expr;
        }
Example #29
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)
                ));
        }
Example #30
0
        private static Expression ParseExpressionBitXOr(Scope scope, LuaLexer code, InvokeResult result, ref bool lWrap)
        {
            // exprBitXOr ::= exprBitAnd { ~ exprBitAnd }
            var expr = ParseExpressionBitAnd(scope, code, result, ref lWrap);

            while (code.Current.Typ == LuaToken.Dilde)
            {
                code.Next();
                expr = BinaryOperationExpression(scope.Runtime, code.Current, ExpressionType.ExclusiveOr,
                    expr,
                    ParseExpressionBitAnd(scope, code, InvokeResult.Object, ref lWrap)
                );
                lWrap |= true;
            }

            return expr;
        }