Ejemplo n.º 1
0
        /// <summary>
        /// 执行数组访问,并返回执行结果。
        /// </summary>
        /// <param name="arrayAccess">指定一个数组实例。</param>
        /// <returns>object</returns>
        protected object EvalArrayAccess(ArrayAccess arrayAccess)
        {
            object obj = this.EvalExpression(arrayAccess.Exp);
            object index = this.EvalExpression(arrayAccess.Index);

            if (obj is Array)
            {
                Array array = (Array)obj;

                if (index is Int32)
                    return array.GetValue((int)index);
                else
                    throw new TemplateRuntimeException("数组索引必须是整形数字。", arrayAccess.Line, arrayAccess.Col);
            }
            else
                return this.EvalMethodCall(obj, "get_Item", new object[] { index });
        }
Ejemplo n.º 2
0
        private Expression _PrimaryExpression()
        {
            if (Current.TokenKind == TokenKind.StringStart)
                return _ReadString();
            else if (Current.TokenKind == TokenKind.id)
            {
                Token id = _Consume();

                Expression exp = null;

                // if ( follows ID, we have a function call
                if (Current.TokenKind == TokenKind.LParen)
                {
                    _Consume();	// consume LParen
                    Expression[] args = _ReadArguments();
                    _Consume(TokenKind.RParen);

                    exp = new FCall(id.Line, id.Col, id.Data, args);
                }
                else  // else, we just have id
                    exp = new Name(id.Line, id.Col, id.Data);

                // while we have ".", keep chaining up field access or method call
                while (Current.TokenKind == TokenKind.Dot || Current.TokenKind == TokenKind.LBracket)
                {
                    if (Current.TokenKind == TokenKind.Dot)
                    {
                        _Consume();	// consume DOT
                        Token field = _Consume(TokenKind.id);	// consume ID after dot

                        // if "(" after ID, then it's a method call
                        if (Current.TokenKind == TokenKind.LParen)
                        {
                            _Consume(); // consume "("
                            Expression[] args = _ReadArguments();
                            _Consume(TokenKind.RParen); // read ")"

                            exp = new MethodCall(field.Line, field.Col, exp, field.Data, args);
                        }
                        else
                            exp = new FieldAccess(field.Line, field.Col, exp, field.Data);
                    }
                    else // must be LBracket
                    {
                        // array access
                        Token bracket = Current;
                        _Consume(); // consume [
                        Expression indexExp = _TopExpression();
                        _Consume(TokenKind.RBracket);

                        exp = new ArrayAccess(bracket.Line, bracket.Col, exp, indexExp);
                    }

                }

                return exp;

            }
            else if (Current.TokenKind == TokenKind.Integer)
            {
                int value = Int32.Parse(Current.Data);
                IntLiteral intLiteral = new IntLiteral(Current.Line, Current.Col, value);
                _Consume(); // consume int
                return intLiteral;
            }
            else if (Current.TokenKind == TokenKind.Double)
            {
                double value = Double.Parse(Current.Data);
                DoubleLiteral dLiteral = new DoubleLiteral(Current.Line, Current.Col, value);
                _Consume(); // consume int
                return dLiteral;
            }
            else if (Current.TokenKind == TokenKind.LParen)
            {
                _Consume(); // eat (
                Expression exp = _TopExpression();
                _Consume(TokenKind.RParen); // eat )

                return exp;
            }
            else
                throw new ParseException("意外的 Token 表达式:" + Current.TokenKind + "。Token类型 即非 ID 也非 string。", Current.Line, Current.Col);
        }