diff options
Diffstat (limited to 'languages/cpp/cppevaluation.h')
-rw-r--r-- | languages/cpp/cppevaluation.h | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/languages/cpp/cppevaluation.h b/languages/cpp/cppevaluation.h new file mode 100644 index 00000000..e4adeb28 --- /dev/null +++ b/languages/cpp/cppevaluation.h @@ -0,0 +1,367 @@ +/*************************************************************************** + 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 <qvaluelist.h> + +#include "expressioninfo.h" +#include "simpletype.h" +#include "declarationinfo.h" +#include <hashedstring.h> + +class SimpleContext; + +void statusBarText( const QString& str, int time = 1000 ); + +namespace CppEvaluation { + +template <class To, class From> +extern QValueList<To> convertList( const QValueList<From>& from ); + +extern QString nameFromType( SimpleType t ); + +class Operator; + +struct OperatorIdentification { + QValueList<QString> 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( QString& str ) = 0; + + ///params + virtual EvaluationResult apply( QValueList<EvaluationResult> params, QValueList<EvaluationResult> innerParams ) = 0; + + virtual QString 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 QString& msg ); + QString printTypeList( QValueList<EvaluationResult>& lst ); +}; + + +class OperatorSet { + private: + typedef QValueList< Operator* > OperatorList; + OperatorList m_operators; + public: + OperatorSet() {} + + ~OperatorSet(); + + void registerOperator( Operator* op ) { + m_operators << op; + } + + OperatorIdentification identifyOperator( const QString& str_ , Operator::BindingSide allowedBindings = ( Operator::BindingSide ) ( Operator::Left | Operator::Right | Operator::Neutral ) ); + +}; +extern OperatorSet AllOperators; + + +template <class OperatorType> +class RegisterOperator { + public: + RegisterOperator( OperatorSet& set + ) { + set.registerOperator( new OperatorType() ); + } + ~RegisterOperator() {} +} +; + + +class UnaryOperator : public Operator { + public: + UnaryOperator( int priority , QString identString, QString 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( QString& str ); + + virtual EvaluationResult unaryApply( EvaluationResult param, const QValueList<EvaluationResult>& innerParams ) = 0; + + virtual bool checkParams( const QValueList<EvaluationResult>& params ) { + return !params.isEmpty() && params[ 0 ]; + } + + virtual EvaluationResult apply( QValueList<EvaluationResult> params, QValueList<EvaluationResult> innerParams ); + + virtual QString name() { + return m_name; + } + + private: + int m_priority; + QString m_identString; + QString m_name; + Operator::BindingSide m_binding; + protected: + + QString identString() const { + return m_identString; + } + +}; + + +class NestedTypeOperator : public UnaryOperator { + public: + NestedTypeOperator() : UnaryOperator( 18, "::", "nested-type-operator", Operator::Left ) {} + + virtual EvaluationResult unaryApply( EvaluationResult param, const QValueList<EvaluationResult>& /*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 QValueList<EvaluationResult>& /*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 QValueList<EvaluationResult>& 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 QValueList<EvaluationResult>& /*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 QValueList<EvaluationResult>& /*innerParams*/ ); + + virtual bool canBeType( BindingSide side ) { + return false; + } +}; + + +class UnaryParenOperator : public UnaryOperator { + public: + ///Identstring should be both parens, for Example "[]" or "()" + UnaryParenOperator( int priority , QString identString, QString description, Operator::BindingSide binding ) : UnaryOperator( priority, identString, description, binding ) {} + + virtual OperatorIdentification identify( QString& 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 QValueList<EvaluationResult>& innerParams ); + + virtual bool canBeType( BindingSide side ) { + return false; + } +}; + + +class ParenOperator : public UnaryParenOperator { + public: + ParenOperator() : UnaryParenOperator( 16, "()", "paren-operator", Operator::Left ) {} + + virtual bool checkParams( const QValueList<EvaluationResult>& params ) { + return !params.isEmpty(); + } + + virtual EvaluationResult unaryApply( EvaluationResult param, const QValueList<EvaluationResult>& 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( QString 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; |