/*************************************************************************** begin : Sat Jul 21 2001 copyright : (C) 2001 by Victor R�er email : victor_roeder@gmx.de copyright : (C) 2002,2003 by Roberto Raggi email : roberto@kdevelop.org copyright : (C) 2005 by Adam Treat email : manyoso@yahoo.com copyright : (C) 2006 by David Nolden email : david.nolden.kdevelop@art-master.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CPPEVALUATION_H #define CPPEVALUATION_H #include #include "expressioninfo.h" #include "simpletype.h" #include "declarationinfo.h" #include class SimpleContext; void statusBarText( const TQString& str, int time = 1000 ); namespace CppEvaluation { template extern TQValueList convertList( const TQValueList& from ); extern TQString nameFromType( SimpleType t ); class Operator; struct OperatorIdentification { TQValueList innerParams; /** Inner parameters of the operator( for the vec["hello"] the "hello" ) */ int start, end; /** Range the operator occupies */ bool found; Operator* op; ///Can be 0 ! OperatorIdentification() : start( 0 ), end( 0 ), found( false ), op( 0 ) {} operator bool() { return found; } }; class EvaluationResult { public: EvaluationResult& operator = ( const EvaluationResult& rhs ) { resultType = rhs.resultType; sourceVariable = rhs.sourceVariable; expr = rhs.expr; isMacro = rhs.isMacro; macro = rhs.macro; return *this; } EvaluationResult( const EvaluationResult& rhs ) : resultType( rhs.resultType ), expr( rhs.expr ), sourceVariable( rhs.sourceVariable ), isMacro( rhs.isMacro ), macro( rhs.macro ) {} LocateResult resultType; ///The resulting type ExpressionInfo expr; ///Information about the expression that was processed DeclarationInfo sourceVariable; ///If the type comes from a variable, this stores Information about it bool isMacro; Macro macro; ///should be removed EvaluationResult( SimpleType rhs ) : isMacro( false ) { if ( rhs.get() != 0 ) resultType = rhs->desc(); } EvaluationResult( LocateResult tp = TypeDesc(), DeclarationInfo var = DeclarationInfo() ) : resultType( tp ), sourceVariable( var ), isMacro( false ) {} /*operator TypeDesc () const { return (TypeDesc)resultType; }*/ ///This must be removed operator SimpleType() const { if ( resultType->resolved() ) { return SimpleType( resultType->resolved() ); } else { return SimpleType( new SimpleTypeImpl( ( TypeDesc ) resultType ) ); } } TypeDesc* operator -> () { return & resultType.desc(); } operator LocateResult () const { return resultType; } operator bool() const { return ( bool ) resultType; } }; class Operator { public: enum BindingSide { Neutral = 0, Left = 1, Right = 2 }; enum Type { Unary = 1, Binary = 2, Ternary = 3 }; virtual ~Operator() {} virtual int priority() = 0; virtual Type type() = 0; virtual int paramCount() = 0; ///"binding" means that the operator needs the evaluated type of the expression on that side ///The types of all bound sides will later be sent in the "params"-list of the apply-function virtual BindingSide binding() = 0; ///The side to which the operator binds ///When this returns true, the ident-structure must be filled correctly virtual OperatorIdentification identify( TQString& str ) = 0; ///params virtual EvaluationResult apply( TQValueList params, TQValueList innerParams ) = 0; virtual TQString name() = 0; ///Should return whether the item it the given side can be a type(Neutral stands for the inner paremeters) virtual bool canBeType( BindingSide side ) { return true; } protected: void log( const TQString& msg ); TQString printTypeList( TQValueList& lst ); }; class OperatorSet { private: typedef TQValueList< Operator* > OperatorList; OperatorList m_operators; public: OperatorSet() {} ~OperatorSet(); void registerOperator( Operator* op ) { m_operators << op; } OperatorIdentification identifyOperator( const TQString& str_ , Operator::BindingSide allowedBindings = ( Operator::BindingSide ) ( Operator::Left | Operator::Right | Operator::Neutral ) ); }; extern OperatorSet AllOperators; template class RegisterOperator { public: RegisterOperator( OperatorSet& set ) { set.registerOperator( new OperatorType() ); } ~RegisterOperator() {} } ; class UnaryOperator : public Operator { public: UnaryOperator( int priority , TQString identString, TQString description, Operator::BindingSide binding ) : Operator(), m_priority( priority ), m_identString( identString ), m_name( description ), m_binding( binding ) {} virtual int priority() { return m_priority; } virtual Operator::Type type() { return Operator::Unary; } virtual Operator::BindingSide binding() { return m_binding; } virtual int paramCount() { return 1; } virtual OperatorIdentification identify( TQString& str ); virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& innerParams ) = 0; virtual bool checkParams( const TQValueList& params ) { return !params.isEmpty() && params[ 0 ]; } virtual EvaluationResult apply( TQValueList params, TQValueList innerParams ); virtual TQString name() { return m_name; } private: int m_priority; TQString m_identString; TQString m_name; Operator::BindingSide m_binding; protected: TQString identString() const { return m_identString; } }; class NestedTypeOperator : public UnaryOperator { public: NestedTypeOperator() : UnaryOperator( 18, "::", "nested-type-operator", Operator::Left ) {} virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& /*innerParams*/ ); }; //RegisterOperator< NestedTypeOperator > NestedTypeReg( AllOperators ); ///This registers the operator to the list of all operators class DotOperator : public UnaryOperator { public: DotOperator() : UnaryOperator( 17, ".", "dot-operator", Operator::Left ) {} virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& /*innerParams*/ ); virtual bool canBeType( BindingSide side ) { return false; } }; class ArrowOperator : public UnaryOperator { public: ArrowOperator() : UnaryOperator( 17, "->", "arrow-operator", Operator::Left ) {} virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& innerParams ); virtual bool canBeType( BindingSide side ) { return false; } }; class StarOperator : public UnaryOperator { public: StarOperator() : UnaryOperator( 15, "*", "star-operator", Operator::Right ) { ///Normally this should have a priority of 16, but that would need changes to the expression-parsin g-loop } virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& /*innerParams*/ ); virtual bool canBeType( BindingSide side ) { return false; } }; class AddressOperator : public UnaryOperator { public: AddressOperator() : UnaryOperator( 16, "&", "address-operator", Operator::Right ) {} virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& /*innerParams*/ ); virtual bool canBeType( BindingSide side ) { return false; } }; class UnaryParenOperator : public UnaryOperator { public: ///Identstring should be both parens, for Example "[]" or "()" UnaryParenOperator( int priority , TQString identString, TQString description, Operator::BindingSide binding ) : UnaryOperator( priority, identString, description, binding ) {} virtual OperatorIdentification identify( TQString& str ); virtual bool canBeType( BindingSide side ) { return false; } }; class IndexOperator : public UnaryParenOperator { public: IndexOperator() : UnaryParenOperator( 17, "[]", "index-operator", Operator::Left ) {} virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& innerParams ); virtual bool canBeType( BindingSide side ) { return false; } }; class ParenOperator : public UnaryParenOperator { public: ParenOperator() : UnaryParenOperator( 16, "()", "paren-operator", Operator::Left ) {} virtual bool checkParams( const TQValueList& params ) { return !params.isEmpty(); } virtual EvaluationResult unaryApply( EvaluationResult param, const TQValueList& innerParams ); virtual bool canBeType( BindingSide side ) { return false; } }; //This is used in CppCodeCompletion::evaluateExpression(..) class ExpressionEvaluation { private: CppCodeCompletion* m_data; SimpleContext* m_ctx; ExpressionInfo m_expr; bool m_global; OperatorSet& m_operators; HashedStringSet m_includeFiles; public: ExpressionEvaluation( CppCodeCompletion* data, ExpressionInfo expr, OperatorSet& operators, const HashedStringSet& includeFiles, SimpleContext* ctx = 0 ); EvaluationResult evaluate(); private: /** recursion-method: 1. Find the rightmost operator with the lowest priority, split the expression vector[ (*it)->position ](). */ virtual EvaluationResult evaluateExpressionInternal( TQString expr, EvaluationResult scope, SimpleContext * ctx, SimpleContext* innerCtx , bool canBeTypeExpression = true ); ///Locates types or members EvaluationResult evaluateAtomicExpression( TypeDesc expr, EvaluationResult scope, SimpleContext * ctx = 0, bool canBeTypeExpression = true ); }; } #endif // kate: indent-mode csands; tab-width 4;