/***************************************************************************
begin : Sat Jul 21 2001
copyright : ( C ) 2001 by Victor R <EFBFBD> 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 <tqvaluelist.h>
# include "expressioninfo.h"
# include "simpletype.h"
# include "declarationinfo.h"
# include <hashedstring.h>
class SimpleContext ;
void statusBarText ( const TQString & str , int time = 1000 ) ;
namespace CppEvaluation {
template < class To , class From >
extern TQValueList < To > convertList ( const TQValueList < From > & from ) ;
extern TQString nameFromType ( SimpleType t ) ;
class Operator ;
struct OperatorIdentification {
TQValueList < TQString > 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 < EvaluationResult > params , TQValueList < EvaluationResult > 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 < EvaluationResult > & 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 OperatorType >
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 < EvaluationResult > & innerParams ) = 0 ;
virtual bool checkParams ( const TQValueList < EvaluationResult > & params ) {
return ! params . isEmpty ( ) & & params [ 0 ] ;
}
virtual EvaluationResult apply ( TQValueList < EvaluationResult > params , TQValueList < EvaluationResult > 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 < 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 TQValueList < 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 TQValueList < 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 TQValueList < 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 TQValueList < 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 , 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 < 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 TQValueList < EvaluationResult > & params ) {
return ! params . isEmpty ( ) ;
}
virtual EvaluationResult unaryApply ( EvaluationResult param , const TQValueList < 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 ( 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