Exemplo n.º 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
Exemplo n.º 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);
        }
Exemplo n.º 3
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;
        }
Exemplo n.º 4
0
        private static Expression ParseLamdaDefinition(Scope parent, LuaLexer code, string sName, bool lSelfParameter, Action<Type> functionTypeCollected)
        {
            List<ParameterExpression> parameters = new List<ParameterExpression>();
            LambdaScope scope = new LambdaScope(parent);

            // Lese die Parameterliste ein
            FetchToken(LuaToken.BracketOpen, code);
            if (lSelfParameter)
                parameters.Add(scope.RegisterParameter(typeof(object), "self"));

            if (code.Current.Typ == LuaToken.Identifier || code.Current.Typ == LuaToken.DotDotDot)
            {
                if (code.Current.Typ == LuaToken.DotDotDot)
                {
                    code.Next();
                    ParseLamdaDefinitionArgList(scope, parameters);
                }
                else
                {
                    Token tName;
                    Type typeArgument;
                    ParseIdentifierAndType(scope, code, out tName, out typeArgument);
                    parameters.Add(scope.RegisterParameter(typeArgument, tName.Value));

                    while (code.Current.Typ == LuaToken.Comma)
                    {
                        code.Next();
                        if (code.Current.Typ == LuaToken.DotDotDot)
                        {
                            code.Next();
                            ParseLamdaDefinitionArgList(scope, parameters); // last argument
                            break;
                        }
                        else
                        {
                            ParseIdentifierAndType(scope, code, out tName, out typeArgument);
                            parameters.Add(scope.RegisterParameter(typeArgument, tName.Value));
                        }
                    }
                }
            }
            FetchToken(LuaToken.BracketClose, code);

            // Is there a specific result
            if (code.Current.Typ == LuaToken.Colon)
            {
                var t = code.Current;
                code.Next();
                Type typeResult = ParseType(scope, code, true);
                scope.ResetReturnLabel(typeResult, null);
            }
            else
                scope.ResetReturnLabel(typeof(LuaResult), Expression.Property(null, Lua.ResultEmptyPropertyInfo));

            // register the delegate
            if (functionTypeCollected != null)
            {
                functionTypeCollected(
                    Expression.GetFuncType(
                        (from p in parameters select p.Type).Concat(new Type[] { scope.ReturnType }).ToArray()
                    )
                );
            }

            // Lese den Code-Block
            ParseBlock(scope, code);

            FetchToken(LuaToken.KwEnd, code);
            return Expression.Lambda(
                scope.ExpressionBlock,
            (parent.EmitDebug & LuaDebugLevel.RegisterMethods) == LuaDebugLevel.RegisterMethods ? Lua.RegisterUniqueName(sName) : sName,
                parameters);
        }
Exemplo n.º 5
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;
        }
Exemplo n.º 6
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;
            }
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
 private static Token FetchToken(LuaToken typ, LuaLexer code, bool lOptional = false)
 {
     if (code.Current.Typ == typ)
     {
         var t = code.Current;
         code.Next();
         return t;
     }
     else if (lOptional)
         return null;
     else
         throw ParseError(code.Current, String.Format(Properties.Resources.rsParseUnexpectedToken, LuaLexer.GetTokenName(code.Current.Typ), LuaLexer.GetTokenName(typ)));
 }
Exemplo n.º 9
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;
            }
        }
Exemplo n.º 10
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)
                    );
                }
            }
        }
Exemplo n.º 11
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];
        }
Exemplo n.º 12
0
        private static PrefixMemberInfo ParseSuffix(Scope scope, LuaLexer code, PrefixMemberInfo info)
        {
            // suffix_opt ::= [ suffix ]
            // suffix ::= { '[' exp ']'  | '.' Identifier | args | ':' Identifier args }
            // args ::= tablector | string | '(' explist ')'

            while (true)
            {
                switch (code.Current.Typ)
                {
                    case LuaToken.BracketSquareOpen: // Index
                        code.Next();
                        info.GenerateGet(scope, InvokeResult.Object);
                        if (code.Current.Typ == LuaToken.BracketSquareClose)
                            info.Indices = new Expression[0];
                        else
                            info.Indices = ParseExpressionList(scope, code).ToArray();
                        FetchToken(LuaToken.BracketSquareClose, code);
                        break;

                    case LuaToken.Dot: // Property of an class
                        code.Next();
                        info.GenerateGet(scope, InvokeResult.Object);
                        info.SetMember(FetchToken(LuaToken.Identifier, code), false);
                        break;

                    case LuaToken.BracketOpen: // List of arguments
                        info.GenerateGet(scope, InvokeResult.Object);
                        info.Arguments = ParseArgumentList(scope, code);
                        break;

                    case LuaToken.BracketCurlyOpen: // LuaTable as an argument
                        info.GenerateGet(scope, InvokeResult.Object);
                        info.Arguments = new ArgumentsList(ParseTableConstructor(scope, code));
                        break;

                    case LuaToken.String: // String as an argument
                        info.GenerateGet(scope, InvokeResult.Object);
                        info.Arguments = new ArgumentsList(Expression.Constant(FetchToken(LuaToken.String, code).Value, typeof(object)));
                        break;

                    case LuaToken.Colon: // Methodenaufruf
                        code.Next();

                        // Lese den Namen um den Member zu belegen
                        info.GenerateGet(scope, InvokeResult.Object);
                        info.SetMember(FetchToken(LuaToken.Identifier, code), true);

                        // Parse die Parameter
                        switch (code.Current.Typ)
                        {
                            case LuaToken.BracketOpen: // Argumentenliste
                                info.Arguments = ParseArgumentList(scope, code);
                                break;

                            case LuaToken.BracketCurlyOpen: // LuaTable als Argument
                                info.Arguments = new ArgumentsList(ParseTableConstructor(scope, code) );
                                break;

                            case LuaToken.String: // String als Argument
                                info.Arguments = new ArgumentsList(Expression.Constant(FetchToken(LuaToken.String, code).Value, typeof(string)));
                                break;
                        }
                        break;

                    default:
                        return info;
                }
            }
        }
Exemplo n.º 13
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();
            }
        }
Exemplo n.º 14
0
        private static bool ParseStatement(Scope scope, LuaLexer code)
        {
            switch (code.Current.Typ)
            {
                case LuaToken.Identifier: // Expression
                case LuaToken.DotDotDot:
                case LuaToken.BracketOpen:
                case LuaToken.String:
                case LuaToken.Number:
                case LuaToken.KwFalse:
                case LuaToken.KwTrue:
                case LuaToken.KwNil:
                case LuaToken.BracketCurlyOpen:
                case LuaToken.Minus:
                case LuaToken.KwCast:
                    ParseExpressionStatement(scope, code, false);
                    return true;

                case LuaToken.ColonColon: // Start of a label
                    ParseLabel(scope, code);
                    return true;

                case LuaToken.KwGoto:
                    ParseGoto(scope, code);
                    return true;

                case LuaToken.KwDo:
                    ParseDoLoop(scope, code);
                    return true;

                case LuaToken.KwWhile:
                    ParseWhileLoop(scope, code);
                    return true;

                case LuaToken.KwRepeat:
                    ParseRepeatLoop(scope, code);
                    return true;

                case LuaToken.KwIf:
                    ParseIfStatement(scope, code);
                    return true;

                case LuaToken.KwFor:
                    ParseForLoop(scope, code);
                    return true;

                case LuaToken.KwForEach:
                    ParseForEachLoop(scope, code);
                    return true;

                case LuaToken.KwFunction:
                    ParseFunction(scope, code, false);
                    return true;

                case LuaToken.KwLocal:
                    code.Next();
                    if (code.Current.Typ == LuaToken.KwFunction)
                        ParseFunction(scope, code, true);
                    else
                        ParseExpressionStatement(scope, code, true);
                    return true;
                case LuaToken.KwConst:
                    code.Next();
                    ParseConst(scope, code);
                    return true;

                case LuaToken.InvalidString:
                    throw ParseError(code.Current, Properties.Resources.rsParseInvalidString);
                case LuaToken.InvalidComment:
                    throw ParseError(code.Current, Properties.Resources.rsParseInvalidComment);
                case LuaToken.InvalidChar:
                    throw ParseError(code.Current, Properties.Resources.rsParseInvalidChar);

                default:
                    return false;
            }
        }
Exemplo n.º 15
0
        private static void ParseReturn(Scope scope, LuaLexer code)
        {
            // eat return
            code.Next();

            // Build the return expression for all parameters
            Expression exprReturnValue;

            if (IsExpressionStart(code)) // there is a return value
            {
                if (scope.ReturnType == typeof(LuaResult))
                {
                    exprReturnValue = GetLuaResultExpression(scope, code.Current, ParseExpressionList(scope, code).ToArray());
                }
                else if (scope.ReturnType.IsArray)
                {
                    Type typeArray = scope.ReturnType.GetElementType();
                    exprReturnValue = Expression.NewArrayInit(
                        typeArray,
                        from c in ParseExpressionList(scope, code) select ConvertExpression(scope.Runtime, code.Current, c, typeArray));
                }
                else
                {
                    List<Expression> exprList = new List<Expression>(ParseExpressionList(scope, code));

                    if (exprList.Count == 1)
                        exprReturnValue = ConvertExpression(scope.Runtime, code.Current, exprList[0], scope.ReturnType);
                    else
                    {
                        ParameterExpression tmpVar = Expression.Variable(scope.ReturnType);
                        exprList[0] = Expression.Assign(tmpVar, ConvertExpression(scope.Runtime, code.Current, exprList[0], scope.ReturnType));
                        exprList.Add(tmpVar);
                        exprReturnValue = Expression.Block(scope.ReturnType, new ParameterExpression[] { tmpVar }, exprList);
                    }
                }
            }
            else // use the default-value
            {
                if (scope.ReturnType == typeof(LuaResult))
                    exprReturnValue = Expression.Property(null, Lua.ResultEmptyPropertyInfo);
                else if (scope.ReturnType.IsArray)
                    exprReturnValue = Expression.NewArrayInit(scope.ReturnType.GetElementType());
                else
                    exprReturnValue = Expression.Default(scope.ReturnType);
            }

            if (code.Current.Typ == LuaToken.Semicolon)
                code.Next();

            scope.AddExpression(Expression.Goto(scope.LookupLabel(scope.ReturnType, csReturnLabel), exprReturnValue));
        }
Exemplo n.º 16
0
        private static Expression ParsePrefixCast(Scope scope, LuaLexer code)
        {
            LuaType luaType;
            Token t = code.Current;
            code.Next();

            FetchToken(LuaToken.BracketOpen, code);

            // Read the type
            luaType = ParseType(scope, code, true);
            FetchToken(LuaToken.Comma, code);

            bool lWrap = scope.EmitExpressionDebug;
            Expression expr = ParseExpression(scope, code, InvokeResult.Object, ref lWrap);

            FetchToken(LuaToken.BracketClose, code);

            return ConvertExpression(scope.Runtime, t, expr, luaType);
        }
Exemplo n.º 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;
            }
        }
Exemplo n.º 18
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;
            }
        }
Exemplo n.º 19
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;
        }
Exemplo n.º 20
0
        private static PrefixMemberInfo ParsePrefix(Scope scope, LuaLexer code)
        {
            // prefix ::= Identifier suffix_opt |  '(' exp ')' suffix | literal | tablector

            Token tStart = code.Current;
            PrefixMemberInfo info;
            switch (tStart.Typ)
            {
                case LuaToken.BracketOpen: // Parse eine Expression
                    {
                        code.Next();
                        var expr = ConvertObjectExpression(scope.Runtime, tStart, ParseExpression(scope, code, InvokeResult.Object, scope.EmitExpressionDebug));
                        FetchToken(LuaToken.BracketClose, code);

                        info = new PrefixMemberInfo(tStart, expr, null, null, null);
                    }
                    break;

                case LuaToken.DotDotDot:
                case LuaToken.Identifier:
                case LuaToken.KwForEach:
                    var t = code.Current;
                    if (t.Value == csClr) // clr is a special package, that always exists
                    {
                        code.Next();
                        info = new PrefixMemberInfo(tStart, Expression.Property(null, Lua.TypeClrPropertyInfo), null, null, null);
                    }
                    else
                    {
                        string sMemberName;
                        if (t.Typ == LuaToken.DotDotDot)
                            sMemberName = csArgList;
                        else if (t.Typ == LuaToken.KwCast)
                            sMemberName = "cast";
                        else if (t.Typ == LuaToken.KwForEach)
                            sMemberName = "foreach";
                        else
                            sMemberName = t.Value;
                        var p = scope.LookupExpression(sMemberName);
                        if (t.Typ == LuaToken.DotDotDot && p == null)
                            throw ParseError(t, Properties.Resources.rsParseNoArgList);
                        code.Next();
                        if (p == null) // No local variable found
                            info = new PrefixMemberInfo(tStart, scope.LookupExpression(csEnv), t.Value, null, null);
                        else
                            info = new PrefixMemberInfo(tStart, p, null, null, null);
                    }
                    break;

                case LuaToken.KwCast:
                    info = new PrefixMemberInfo(tStart, ParsePrefixCast(scope, code), null, null, null);
                    break;

                case LuaToken.String: // Literal String
                    info = new PrefixMemberInfo(tStart, Expression.Constant(FetchToken(LuaToken.String, code).Value, typeof(string)), null, null, null);
                    break;

                case LuaToken.Number: // Literal Zahl
                    info = new PrefixMemberInfo(tStart, ParseNumber(scope.Runtime, FetchToken(LuaToken.Number, code)), null, null, null);
                    break;

                case LuaToken.KwTrue: // Literal TRUE
                    code.Next();
                    info = new PrefixMemberInfo(tStart, Expression.Constant(true, typeof(bool)), null, null, null);
                    break;

                case LuaToken.KwFalse: // Literal FALSE
                    code.Next();
                    info = new PrefixMemberInfo(tStart, Expression.Constant(false, typeof(bool)), null, null, null);
                    break;

                case LuaToken.KwNil: // Literal NIL
                    code.Next();
                    info = new PrefixMemberInfo(tStart, Expression.Constant(null, typeof(object)), null, null, null);
                    break;

                case LuaToken.BracketCurlyOpen: // tablector
                    info = new PrefixMemberInfo(tStart, ParseTableConstructor(scope, code), null, null, null);
                    break;

                case LuaToken.KwFunction: // Function definition
                    code.Next();
                    info = new PrefixMemberInfo(tStart, ParseLamdaDefinition(scope, code, "lambda", false, null), null, null, null);
                    break;

                default:
                    throw ParseError(code.Current, Properties.Resources.rsParseUnexpectedTokenPrefix);
            }

            return ParseSuffix(scope, code, info);
        }
Exemplo n.º 21
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;
            }
        }
Exemplo n.º 22
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;
        }
Exemplo n.º 23
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;
        }
Exemplo n.º 24
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
        }
Exemplo n.º 25
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;
        }
Exemplo n.º 26
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));
                    }
            }
        }
Exemplo n.º 27
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]);
            }
        }
Exemplo n.º 28
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);
        }
Exemplo n.º 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)
                ));
        }
Exemplo n.º 30
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);
        }