Exemplo n.º 1
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;
 }
Exemplo n.º 2
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.º 3
0
 private static Expression ParseFunctionAddChain(Scope scope, Token tStart, Expression assignee, string sMember)
 {
     if (assignee == null)
     {
         Expression expr = scope.LookupExpression(sMember);
         if (expr == null)
             assignee = ParseFunctionAddChain(scope, tStart, scope.LookupExpression(csEnv), sMember);
         else
             assignee = expr;
     }
     else
         assignee = MemberGetExpression(scope, tStart, assignee, sMember);
     return assignee;
 }
Exemplo n.º 4
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.º 5
0
        private static void ParseFunction(Scope scope, LuaLexer code, bool lLocal)
        {
            FetchToken(LuaToken.KwFunction, code);

            if (lLocal) // Local function, only one identifier is allowed
            {
                var t = FetchToken(LuaToken.Identifier, code);
                ParameterExpression funcVar = null;
                Expression exprFunction = ParseLamdaDefinition(scope, code, t.Value, false,
                    typeDelegate => funcVar = scope.RegisterVariable(typeDelegate, t.Value)
                );
                scope.AddExpression(Expression.Assign(funcVar, exprFunction));
            }
            else // Function that is assigned to a table. A chain of identifiers is allowed.
            {
                Expression assignee = null;
                Token tCurrent = FetchToken(LuaToken.Identifier, code);
                string sMember = tCurrent.Value;

                // Collect the chain of members
                while (code.Current.Typ == LuaToken.Dot)
                {
                    code.Next();

                    // Create the get-member for the current assignee
                    assignee = ParseFunctionAddChain(scope, tCurrent, assignee, sMember);
                    sMember = FetchToken(LuaToken.Identifier, code).Value;
                }
                // add a method to the table. methods get a hidden parameter and will bo marked
                bool lMethodMember;
                if (code.Current.Typ == LuaToken.Colon)
                {
                    code.Next();

                    // add the last member to the assignee chain
                    assignee = ParseFunctionAddChain(scope, tCurrent, assignee, sMember);
                    // fetch the method name
                    sMember = FetchToken(LuaToken.Identifier, code).Value;
                    lMethodMember = true;
                }
                else
                {
                    if (assignee == null)
                        assignee = scope.LookupExpression(csEnv); // create a global function
                    lMethodMember = false;
                }

                // generate lambda
                scope.AddExpression(MemberSetExpression(scope.Runtime, tCurrent, assignee, sMember, lMethodMember, ParseLamdaDefinition(scope, code, sMember, lMethodMember, null)));
            }
        }