Example #1
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);
		}
Example #2
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 });
		}