/// <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 }); }
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); }