예제 #1
0
 /// <summary>
 /// Visits the function call expression tree
 /// </summary>
 /// <param name="exp"></param>
 public object VisitMemberAccess(MemberAccessExpr exp)
 {
     return null;
 }
예제 #2
0
 /// <summary>
 /// Creates a function call expression.
 /// </summary>
 /// <param name="nameExpr"></param>
 /// <param name="parameters"></param>
 /// <param name="token"></param>
 /// <returns></returns>
 public static Expr MemberAccess(Expr nameExpr, string memberName, bool isAssignment, TokenData token)
 {
     var exp = new MemberAccessExpr();
     exp.IsAssignment = isAssignment;
     exp.VarExp = nameExpr;
     exp.MemberName = memberName;
     SetupContext(exp, token);
     return exp;
 }
예제 #3
0
        /// <summary>
        /// Either external function or member name.
        /// </summary>
        /// <returns></returns>
        public object VisitMemberAccess(MemberAccessExpr expr)
        {
            var memberAccess = MemberHelper.GetMemberAccess(expr, this.Ctx, expr.VarExp, expr.MemberName, this);
            if (expr.IsAssignment)
                return memberAccess;

            // NOTES:
            // 1. If property on a built in type && not assignment then just return the value of the property
            // 2. It's done here instead because there is no function/method call on a property.
            if (memberAccess.IsPropertyAccessOnBuiltInType())
            {
                var result = FunctionHelper.CallMemberOnBasicType(this.Ctx, expr, memberAccess, null, null, this);
                return result;
            }
            if (memberAccess.IsPropertyAccessOnClass() || memberAccess.IsFieldAccessOnClass())
            {
                var result = FunctionHelper.CallMemberOnClass(this.Ctx, expr, memberAccess, null, null, this);
                return result;
            }
            if (memberAccess.IsModuleAccess())
            {
                var result = MemberHelper.ResolveSymbol(memberAccess.Scope, expr.MemberName);
                return result;
            }
            return memberAccess;
        }
예제 #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;
        }