summaryrefslogtreecommitdiffstats
path: root/languages/cpp/cppevaluation.h
blob: e4adeb2857bcd5304fad38c6711f64f1af818f45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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;