Example #1
0
 /// <summary>
 /// Visits the function call expression tree
 /// </summary>
 /// <param name="exp"></param>
 public object VisitIndex(IndexExpr exp)
 {
     _callBackOnNodeStart(exp);
     _callBackOnNodeStart(exp.VarExp);
     _callBackOnNodeStart(exp.IndexExp);
     return null;
 }
Example #2
0
 /// <summary>
 /// Creates an index expression from the parameters supplied.
 /// </summary>
 /// <param name="varExp"></param>
 /// <param name="indexExp"></param>
 /// <param name="isAssignment"></param>
 /// <param name="token"></param>
 /// <returns></returns>
 public static Expr Index(Expr varExp, Expr indexExp, bool isAssignment, TokenData token)
 {
     var exp = new IndexExpr();
     exp.IsAssignment = isAssignment;
     exp.VarExp = varExp;
     exp.IndexExp = indexExp;
     SetupContext(exp, token);
     return exp;
 }
Example #3
0
        /// <summary>
        /// Evaluate object[index]
        /// </summary>
        /// <returns></returns>
        public static object EvalIndexAccess(IndexExpr expr)
        {
            var ndxVal = expr.IndexExp.Evaluate();
            var listObject = expr.VariableExp.Evaluate();

            // Check for empty objects.
            ExceptionHelper.NotNull(expr, listObject, "indexing");
            ExceptionHelper.NotNull(expr, ndxVal, "indexing");

            var lobj = (LObject)listObject;

            // CASE 1. Access
            //      e.g. Array: users[0]
            //      e.g. Map:   users['total']
            if (!expr.IsAssignment)
            {
                var result = EvalHelper.AccessIndex(Ctx.Methods, expr, lobj, (LObject)ndxVal);
                return result;
            }

            // CASE 2.  Assignment
            //      e.g. Array: users[0]        = 'john'
            //      e.g. Map:   users['total']  = 200
            // NOTE: In this case of assignment, return back a MemberAccess object descripting what is assign
            var indexAccess = new IndexAccess();
            indexAccess.Instance = lobj;
            indexAccess.MemberName = (LObject)ndxVal;
            return indexAccess;
        }
Example #4
0
        /// <summary>
        /// Parses an Id based expression:
        /// 1. user         : variable
        /// 2. getUser()    : function call
        /// 3. users[       : index expression
        /// 4. user.name    : member access
        /// 
        /// ASSIGNMENT:						EXPRESSION:						
        /// result = 2;						result					-> variableexpression				
        /// items[0] = 'kishore';			items[0]				-> indexexpression( variableexpression  | name)
        /// getuser();					    getuser()				-> functionexpression()
        /// user.age = 30;					user.age				-> memberexpression( variableexpression | name/member )
        /// items[0].name = 'kishore';		items[0].name			-> memberexpression( indexexpression( variableexpression ) )
        /// getuser()[0] = 0;				getuser()[0]			-> indexexpression( functionexpression )
        /// user.name.last = 'kishore';		user.name.last			-> memberexpression( memberexpression )
        /// </summary>
        /// <param name="name"></param>
        /// <param name="existing"></param>
        /// <param name="isCurrentTokenAMember">Whether or not the current token is a '[', '(' or a '.'</param>
        /// <returns></returns>
        public Expr ParseIdExpression(string name = null, Expr existing = null, bool isCurrentTokenAMember = false)
        {
            Expr exp = existing;
            var aheadToken = isCurrentTokenAMember ? _tokenIt.NextToken : _tokenIt.Peek();
            var currentName = "";
            if (existing == null)
            {
                currentName = string.IsNullOrEmpty(name) ? _tokenIt.NextToken.Token.Text : name;
                exp = this.ToIdentExpr(currentName, _tokenIt.NextToken);
            }
            if(!isCurrentTokenAMember)
                _tokenIt.Advance();

            int memberAccess = 0;
            bool isFunction = (exp.IsNodeType(NodeTypes.SysVariable) && _context.Symbols.IsFunc(((VariableExpr)exp).Name));

            // CASE 1: function call without out parenthesis.
            if (isFunction && aheadToken.Token != Tokens.LeftParenthesis)
            {
                exp = ParseFuncExpression(exp, null);
                exp.Ctx = _context;
                return exp;
            }

            // CASE 2: Simple variable expression - e.g. result + 2
            bool isMemberAccessAhead = ( aheadToken.Token == Tokens.LeftParenthesis || aheadToken.Token == Tokens.LeftBracket || aheadToken.Token == Tokens.Dot );
            if( !isFunction && !isMemberAccessAhead )
            {
                exp.Ctx = _context;
                return exp;
            }

            // CASE 3: Member access of some sort using either "." | "[]" | "()"
            // 1. result.total  : Dot access
            // 2. result[0]     : Array access
            // 3. add( 2, 3 )   : Function access/call
            var tokenData = _tokenIt.NextToken;
            var token = _tokenIt.NextToken.Token;
            var members = new List<string>();
            members.Add(exp.ToQualifiedName());

            while (token == Tokens.LeftParenthesis || token == Tokens.LeftBracket || token == Tokens.Dot)
            {
                // Case 2: "("- function call
                if (token == Tokens.LeftParenthesis)
                {
                    exp = ParseFuncExpression(exp, members);
                }

                // Case 3: "[" - indexing
                else if (token == Tokens.LeftBracket)
                {
                    _tokenIt.Advance();
                    _state.IndexExp++;

                    // Get index exp ( n+1 ) or n, etc.
                    var index = ParseExpression(Terminators.ExpBracketEnd);
                    _tokenIt.Expect(Tokens.RightBracket);

                    _state.IndexExp--;
                    // Note: if = sign then property access should return a property info.
                    // otherwise get the value of the property.
                    bool isAssignment = _tokenIt.NextToken.Token == Tokens.Assignment;
                    exp = new IndexExpr(exp, index, isAssignment);
                }

                // Case 4: "." - member access
                else if (_tokenIt.NextToken.Token == Tokens.Dot)
                {
                    _tokenIt.Advance();
                    var member = _tokenIt.ExpectId();

                    // Keep list of each member name.
                    members.Add(member);

                    // Note: if = sign then property access should return a property info.
                    // otherwise get the value of the property.
                    bool isAssignment = _tokenIt.NextToken.Token == Tokens.Assignment;
                    exp = new MemberAccessExpr(exp, member, isAssignment);
                }
                this.SetupContext(exp, tokenData);
                memberAccess++;

                // Check limit.
                _context.Limits.CheckParserMemberAccess(exp, memberAccess);
                tokenData = _tokenIt.NextToken;
                token = tokenData.Token;
            }
            return exp;
        }