MicroModelicaCCompiler  4.5.3
ast_util.hpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSS Solver.
4 
5  QSS Solver is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  QSS Solver is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QSS Solver. If not, see <http://www.gnu.org/licenses/>.
17 
18  ******************************************************************************/
19 
20 #pragma once
21 
22 #include <string>
23 
24 #include <ast/ast_types.hpp>
25 #include <ast/ast_builder.hpp>
26 #include <ast/expression.hpp>
27 #include <ast/statement.hpp>
28 #include <ast/equation.hpp>
29 #include <ir/index.hpp>
30 #include <ir/event.hpp>
31 #include "util_types.hpp"
32 
33 #define IS_CREF(X) ((X)->expressionType() == EXPCOMPREF)
34 #define IS_UMINUS(X) ((X)->expressionType() == EXPUMINUS)
35 #define IS_UMINUS_VAR(X) (IS_UMINUS(X) && IS_CREF((X)->getAsUMinus()->exp()))
36 #define UMINUS_EXP(X) ((X)->getAsUMinus()->exp())
37 #define CREF_NAME(X) \
38  (IS_UMINUS(X) ? *(UMINUS_EXP(X)->getAsComponentReference()->names()->front()) : *((X)->getAsComponentReference()->names()->front()))
39 #define IS_VAR(X) ((IS_CREF(X) || IS_UMINUS_VAR(X)) && (!IS_PARAMETER(X)))
40 #define IS_ZERO_REAL(X) ((X)->expressionType() == EXPREAL && (X)->getAsReal()->val() == 0.0)
41 #define IS_ZERO_INT(X) ((X)->expressionType() == EXPINTEGER && (X)->getAsInteger()->val() == 0)
42 #define IS_ZERO(X) (IS_ZERO_REAL(X) || IS_ZERO_INT(X))
43 #define IS_ADD(X) ((X)->expressionType() == EXPBINOP && (X)->getAsBinOp()->binopType() == BINOPADD)
44 #define LEFT_EXP(X) ((X)->getAsBinOp()->left())
45 #define RIGHT_EXP(X) ((X)->getAsBinOp()->right())
46 #define IS_SUB(X) ((X)->expressionType() == EXPBINOP && (X)->getAsBinOp()->binopType() == BINOPSUB)
47 #define IS_SUM_(X) (IS_SUB(X) || IS_ADD(X))
48 #define IS_SUM_OF_VARS(X) (IS_SUM_(X) && (IS_VAR((X)->getAsBinOp()->left()) && IS_VAR((X)->getAsBinOp()->right())))
49 #define IS_STATE(X) (_varSymbolTable->lookup(CREF_NAME(X)) != nullptr && _varSymbolTable->lookup(CREF_NAME(X))->isState())
50 #define IS_PARAMETER(X) \
51  (IS_UMINUS(X) \
52  ? _varSymbolTable->lookup(CREF_NAME(UMINUS_EXP(X))) != nullptr && _varSymbolTable->lookup(CREF_NAME(UMINUS_EXP(X)))->isParameter() \
53  : _varSymbolTable->lookup(CREF_NAME(X)) != nullptr && _varSymbolTable->lookup(CREF_NAME(X))->isParameter())
54 #define IS_RELOP(X) \
55  ((X)->expressionType() == EXPBINOP && (X)->getAsBinOp()->binopType() >= BINOPLOWER && (X)->getAsBinOp()->binopType() <= BINOPGREATEREQ)
56 #define IS_BNOT(X) ((X)->expressionType() == EXPBOOLEANNOT)
57 #define _VAR(v) newAST_Expression_ComponentReferenceExp(v)
58 #define GREATER(l, r) newAST_Expression_BinOp(l, r, BINOPGREATER)
59 #define LOWER(l, r) newAST_Expression_BinOp(l, r, BINOPLOWER)
60 #define ADD(l, r) newAST_Expression_BinOp(l, r, BINOPADD)
61 #define MULT(l, r) newAST_Expression_BinOp(l, r, BINOPMULT)
62 #define SUB(l, r) newAST_Expression_BinOp(l, r, BINOPSUB)
63 #define I(n) newAST_Expression_Integer(n)
64 #define _R(n) newAST_Expression_Real(n)
65 #define _PA(e) newAST_Expression_OutputExpressions(e)
66 #define UMENOS(e) SUB(I(1), e)
67 #define UNARYM(e) newAST_Expression_UnaryMinus(e)
68 #define GREATEREQ(l, r) newAST_Expression_BinOp(l, r, BINOPGREATEREQ)
69 #define LOWEREQ(l, r) newAST_Expression_BinOp(l, r, BINOPLOWERWQ)
70 #define EQUAL(l, r) newAST_Expression_BinOp(l, r, BINOPCOMPEQ)
71 
73  public:
74  virtual ~AST_Expression_Traverse() = default;
75  AST_Expression apply(AST_Expression);
76 
77  private:
78  virtual AST_Expression mapTraverseElement(AST_Expression) = 0;
79 };
80 
81 template <class R>
83  public:
84  AST_Expression_Visitor() : _left(nullptr), _right(nullptr), _in_bin_op(false){};
85  virtual ~AST_Expression_Visitor() = default;
86  R apply(AST_Expression e)
87  {
88  switch (e->expressionType()) {
89  case EXPBINOP: {
90  AST_Expression_BinOp b = e->getAsBinOp();
91  if (!_in_bin_op) {
92  _in_bin_op = true;
93  _left = b->left();
94  _right = b->right();
95  }
96  R ret = foldTraverseElement(apply(b->left()), apply(b->right()), b->binopType());
97  _in_bin_op = false;
98  return ret;
99  }
100  case EXPUMINUS:
101  return foldTraverseElementUMinus(e);
102  default:
103  return foldTraverseElement(e);
104  }
105  };
106 
107  protected:
108  AST_Expression _left;
109  AST_Expression _right;
111 
112  private:
113  virtual R foldTraverseElement(AST_Expression) = 0;
114  virtual R foldTraverseElementUMinus(AST_Expression) = 0;
115  virtual R foldTraverseElement(R, R, BinOpType) = 0;
116 };
117 
118 template <class F, class R, class V>
120  public:
121  AST_Statement_Visitor(V v, F c_init, bool lhs = true) : _visitor(v), _lhs(lhs), _c_init(c_init){};
122  virtual ~AST_Statement_Visitor() = default;
123 
124  F apply(AST_Statement stm)
125  {
126  F c = _c_init;
127  switch (stm->statementType()) {
128  case STWHEN: {
129  c = foldTraverse(_visitor.apply(stm->getAsWhen()->condition()));
130  AST_StatementListIterator it;
131  AST_StatementList l = stm->getAsWhen()->statements();
132  foreach (it, l) {
133  c = foldTraverse(c, apply(current_element(it)));
134  }
135  return c;
136  }
137  case STASSIGN:
138  if (_lhs) {
139  return foldTraverse(foldTraverse(_visitor.apply(stm->getAsAssign()->lhs())),
140  foldTraverse(_visitor.apply(stm->getAsAssign()->exp())));
141  } else {
142  return foldTraverse(_visitor.apply(stm->getAsAssign()->exp()));
143  }
144  case STIF: {
145  c = foldTraverse(_visitor.apply(stm->getAsIf()->condition()));
146  AST_StatementListIterator it;
147  AST_StatementList l = stm->getAsIf()->statements();
148  foreach (it, l) {
149  c = foldTraverse(c, apply(current_element(it)));
150  }
151  l = stm->getAsIf()->else_statements();
152  foreach (it, l) {
153  c = foldTraverse(c, apply(current_element(it)));
154  }
155  AST_Statement_ElseListIterator eit;
156  AST_Statement_ElseList el = stm->getAsIf()->else_if();
157  foreach (eit, el) {
158  c = foldTraverse(_visitor.apply(current_element(eit)->condition()));
159  l = current_element(eit)->statements();
160  foreach (it, l) {
161  c = foldTraverse(c, apply(current_element(it)));
162  }
163  }
164  return c;
165  }
166  case STFOR: {
167  AST_StatementListIterator it;
168  AST_StatementList l = stm->getAsFor()->statements();
169  foreach (it, l) {
170  c = foldTraverse(c, apply(current_element(it)));
171  }
172  return c;
173  }
174  case STOUTASSING: {
175  AST_Statement_OutputAssigment out_stm = stm->getAsOutputAssigment();
176  AST_Expression call_exp = newAST_Expression_Call(new string(out_stm->function()->cname()), nullptr, out_stm->arguments());
177  c = foldTraverse(_visitor.apply(call_exp));
178  return c;
179  }
180  default:
181  break;
182  }
183  return c;
184  };
185 
186  private:
187  V _visitor;
188  bool _lhs;
190  virtual F foldTraverse(R) = 0;
191  virtual F foldTraverse(F, F) = 0;
192 };
193 
194 template <class R>
196  public:
197  virtual ~AST_Expression_Fold() = default;
198 
199  R apply(AST_Expression e)
200  {
201  switch (e->expressionType()) {
202  case EXPBINOP: {
203  AST_Expression_BinOp b = e->getAsBinOp();
204  AST_Expression left = b->left(), right = b->right();
205  return (foldTraverseElement(apply(left), apply(right), b->binopType()));
206  }
207  case EXPOUTPUT: {
208  AST_Expression_Output o = e->getAsOutput();
209  return apply(AST_ListFirst(o->expressionList()));
210  }
211  case EXPUMINUS:
212  return foldTraverseElementUMinus(e);
213  default:
214  return foldTraverseElement(e);
215  }
216  };
217 
218  private:
219  virtual R foldTraverseElement(AST_Expression) = 0;
220  virtual R foldTraverseElementUMinus(AST_Expression) = 0;
221  virtual R foldTraverseElement(R, R, BinOpType) = 0;
222 };
223 
224 class AST_Visitor {
225  public:
226  ~AST_Visitor() = default;
227  virtual void visit(AST_Class x) = 0;
228  virtual void leave(AST_Class x) = 0;
229  virtual void visit(AST_Composition x) = 0;
230  virtual void leave(AST_Composition x) = 0;
231  virtual void visit(AST_CompositionElement x) = 0;
232  virtual void leave(AST_CompositionElement x) = 0;
233  virtual void visit(AST_CompositionEqsAlgs x) = 0;
234  virtual void leave(AST_CompositionEqsAlgs x) = 0;
235  virtual void visit(AST_External_Function_Call) = 0;
236  virtual void visit(AST_Element x) = 0;
237  virtual void visit(AST_Modification x) = 0;
238  virtual void leave(AST_Modification x) = 0;
239  virtual void visit(AST_Comment x) = 0;
240  virtual void visit(AST_Equation x) = 0;
241  virtual void visit(AST_ForIndex x) = 0;
242  virtual void visit(AST_Equation_Else x) = 0;
243  virtual void visit(AST_Expression x) = 0;
244  virtual void visit(AST_Argument x) = 0;
245  virtual void visit(AST_Statement x) = 0;
246  virtual void leave(AST_Statement x) = 0;
247  virtual void visit(AST_Statement_Else x) = 0;
248  virtual void visit(AST_StoredDefinition x) = 0;
249  virtual void leave(AST_StoredDefinition x) = 0;
250  virtual int apply(AST_Node x) = 0;
251 };
252 
253 class EqualExp {
254  public:
255  EqualExp();
256  bool equalTraverse(AST_Expression a, AST_Expression b);
257 
258  private:
259  bool _compareList(AST_ExpressionList ael, AST_ExpressionList bel);
260  bool equalTraverseElement(AST_Expression a, AST_Expression b);
261  Option<MicroModelica::Util::Variable> getVarInfo(AST_Expression_ComponentReference compRef);
262  bool compareArrays(AST_Expression_ComponentReference arrayA, AST_Expression_ComponentReference arrayB);
263 };
264 
265 class IsConstant : public AST_Expression_Fold<bool> {
266  public:
268 
269  private:
270  bool foldTraverseElement(AST_Expression);
271  bool foldTraverseElement(bool, bool, BinOpType);
272  bool foldTraverseElementUMinus(AST_Expression);
274 };
275 
277  public:
278  AST_Expression replaceExp(AST_Expression rep, AST_Expression for_exp, AST_Expression in,
280 
281  private:
282  AST_Expression mapTraverseElement(AST_Expression);
283  AST_Expression _rep, _for_exp, _in;
285 };
286 
287 class ReplaceBoolean : public AST_Expression_Fold<AST_Expression> {
288  public:
289  ReplaceBoolean();
290 
291  private:
292  AST_Expression foldTraverseElement(AST_Expression);
293  AST_Expression foldTraverseElement(AST_Expression, AST_Expression, BinOpType);
294  AST_Expression foldTraverseElementUMinus(AST_Expression);
295 };
296 
297 class WhenEqualityTrasforms : public AST_Expression_Fold<AST_Expression> {
298  public:
300 
301  private:
302  AST_Expression foldTraverseElement(AST_Expression);
303  AST_Expression foldTraverseElement(AST_Expression, AST_Expression, BinOpType);
304  AST_Expression foldTraverseElementUMinus(AST_Expression);
305 };
306 
307 class PreChange : public AST_Expression_Fold<AST_Expression> {
308  public:
309  PreChange(PreSet);
310 
311  private:
313  AST_Expression foldTraverseElement(AST_Expression);
314  AST_Expression foldTraverseElement(AST_Expression, AST_Expression, BinOpType);
315  AST_Expression foldTraverseElementUMinus(AST_Expression);
316 };
317 
318 class FindReference : public AST_Expression_Fold<bool> {
319  public:
321 
322  private:
324  bool foldTraverseElement(AST_Expression);
325  bool foldTraverseElement(bool, bool, BinOpType);
326  bool foldTraverseElementUMinus(AST_Expression);
327 };
328 
329 class ReplaceReference : public AST_Expression_Fold<AST_Expression> {
330  public:
332 
333  private:
336  AST_Expression foldTraverseElement(AST_Expression);
337  AST_Expression foldTraverseElement(AST_Expression, AST_Expression, BinOpType);
338  AST_Expression foldTraverseElementUMinus(AST_Expression);
339 };
PreSet
PreSet_ * PreSet
Definition: ast_types.hpp:44
ReplaceExp::_for_exp
AST_Expression _for_exp
Definition: ast_util.hpp:283
AST_Expression_Visitor::_right
AST_Expression _right
Definition: ast_util.hpp:109
equation.hpp
EqualExp::getVarInfo
Option< MicroModelica::Util::Variable > getVarInfo(AST_Expression_ComponentReference compRef)
Definition: ast_util.cpp:201
EXPOUTPUT
@ EXPOUTPUT
Definition: ast_types.hpp:182
AST_Expression_Traverse::mapTraverseElement
virtual AST_Expression mapTraverseElement(AST_Expression)=0
AST_Expression_Visitor::foldTraverseElementUMinus
virtual R foldTraverseElementUMinus(AST_Expression)=0
AST_Statement_Visitor::foldTraverse
virtual F foldTraverse(R)=0
ReplaceExp
Definition: ast_util.hpp:276
ast_builder.hpp
AST_Expression_Fold::~AST_Expression_Fold
virtual ~AST_Expression_Fold()=default
ReplaceReference::_post
AST_String _post
Definition: ast_util.hpp:335
MicroModelica::Util::VarSymbolTable
Definition: symbol_table.hpp:184
AST_Expression_Visitor::foldTraverseElement
virtual R foldTraverseElement(AST_Expression)=0
WhenEqualityTrasforms::foldTraverseElementUMinus
AST_Expression foldTraverseElementUMinus(AST_Expression)
Definition: ast_util.cpp:318
index.hpp
AST_Expression_Fold
Definition: ast_util.hpp:195
EXPUMINUS
@ EXPUMINUS
Definition: ast_types.hpp:176
WhenEqualityTrasforms::foldTraverseElement
AST_Expression foldTraverseElement(AST_Expression)
Definition: ast_util.cpp:323
AST_Expression_Fold::foldTraverseElementUMinus
virtual R foldTraverseElementUMinus(AST_Expression)=0
PreChange::_pre
PreSet _pre
Definition: ast_util.hpp:312
ReplaceExp::_symbol_table
MicroModelica::Util::VarSymbolTable _symbol_table
Definition: ast_util.hpp:284
EqualExp::compareArrays
bool compareArrays(AST_Expression_ComponentReference arrayA, AST_Expression_ComponentReference arrayB)
Definition: ast_util.cpp:217
ReplaceReference::foldTraverseElement
AST_Expression foldTraverseElement(AST_Expression)
Definition: ast_util.cpp:467
AST_Expression_Traverse
Definition: ast_util.hpp:72
FindReference::_var
AST_String _var
Definition: ast_util.hpp:323
AST_Expression_Visitor::~AST_Expression_Visitor
virtual ~AST_Expression_Visitor()=default
event.hpp
FindReference::FindReference
FindReference(AST_String)
Definition: ast_util.cpp:410
EqualExp::equalTraverse
bool equalTraverse(AST_Expression a, AST_Expression b)
Definition: ast_util.cpp:93
Option
Definition: util_types.hpp:32
AST_Expression_Traverse::~AST_Expression_Traverse
virtual ~AST_Expression_Traverse()=default
ReplaceExp::_in
AST_Expression _in
Definition: ast_util.hpp:283
AST_String
string * AST_String
Definition: ast_types.hpp:46
FindReference::foldTraverseElement
bool foldTraverseElement(AST_Expression)
Definition: ast_util.cpp:416
WhenEqualityTrasforms::WhenEqualityTrasforms
WhenEqualityTrasforms()
Definition: ast_util.cpp:311
AST_Expression_Visitor::_in_bin_op
bool _in_bin_op
Definition: ast_util.hpp:110
FindReference
Definition: ast_util.hpp:318
IsConstant::_st
MicroModelica::Util::VarSymbolTable _st
Definition: ast_util.hpp:273
AST_Statement_Visitor::AST_Statement_Visitor
AST_Statement_Visitor(V v, F c_init, bool lhs=true)
Definition: ast_util.hpp:121
AST_Statement_Visitor::_visitor
V _visitor
Definition: ast_util.hpp:184
AST_Visitor::apply
virtual int apply(AST_Node x)=0
PreChange::PreChange
PreChange(PreSet)
Definition: ast_util.cpp:367
STFOR
@ STFOR
Definition: ast_types.hpp:191
ReplaceReference
Definition: ast_util.hpp:329
PreChange::foldTraverseElementUMinus
AST_Expression foldTraverseElementUMinus(AST_Expression)
Definition: ast_util.cpp:374
FindReference::foldTraverseElementUMinus
bool foldTraverseElementUMinus(AST_Expression)
Definition: ast_util.cpp:414
ReplaceBoolean
Definition: ast_util.hpp:287
IsConstant::foldTraverseElement
bool foldTraverseElement(AST_Expression)
Definition: ast_util.cpp:242
util_types.hpp
ReplaceReference::foldTraverseElementUMinus
AST_Expression foldTraverseElementUMinus(AST_Expression)
Definition: ast_util.cpp:462
AST_Expression_Fold::foldTraverseElement
virtual R foldTraverseElement(AST_Expression)=0
PreChange
Definition: ast_util.hpp:307
AST_Statement_Visitor::_c_init
F _c_init
Definition: ast_util.hpp:189
STASSIGN
@ STASSIGN
Definition: ast_types.hpp:191
AST_Expression_Visitor::apply
R apply(AST_Expression e)
Definition: ast_util.hpp:86
EqualExp::EqualExp
EqualExp()
Definition: ast_util.cpp:91
STOUTASSING
@ STOUTASSING
Definition: ast_types.hpp:191
AST_ListFirst
T1 AST_ListFirst(list< T1 > *l)
Definition: ast_types.hpp:271
EqualExp::_compareList
bool _compareList(AST_ExpressionList ael, AST_ExpressionList bel)
Definition: ast_util.cpp:109
AST_Statement_Visitor::~AST_Statement_Visitor
virtual ~AST_Statement_Visitor()=default
STIF
@ STIF
Definition: ast_types.hpp:191
ReplaceExp::mapTraverseElement
AST_Expression mapTraverseElement(AST_Expression)
Definition: ast_util.cpp:274
ReplaceReference::_pre
AST_String _pre
Definition: ast_util.hpp:334
ReplaceBoolean::foldTraverseElement
AST_Expression foldTraverseElement(AST_Expression)
Definition: ast_util.cpp:295
ReplaceExp::_rep
AST_Expression _rep
Definition: ast_util.hpp:283
ReplaceExp::replaceExp
AST_Expression replaceExp(AST_Expression rep, AST_Expression for_exp, AST_Expression in, MicroModelica::Util::VarSymbolTable symbol_table)
Definition: ast_util.cpp:265
AST_Expression_Visitor::_left
AST_Expression _left
Definition: ast_util.hpp:105
AST_Expression_Visitor
Definition: ast_util.hpp:82
IsConstant::IsConstant
IsConstant(MicroModelica::Util::VarSymbolTable st)
Definition: ast_util.hpp:267
ReplaceBoolean::foldTraverseElementUMinus
AST_Expression foldTraverseElementUMinus(AST_Expression)
Definition: ast_util.cpp:290
AST_Visitor::visit
virtual void visit(AST_Class x)=0
AST_Statement_Visitor::apply
F apply(AST_Statement stm)
Definition: ast_util.hpp:124
ReplaceReference::ReplaceReference
ReplaceReference(AST_String, AST_String)
Definition: ast_util.cpp:451
AST_Visitor::~AST_Visitor
~AST_Visitor()=default
AST_Statement_Visitor::_lhs
bool _lhs
Definition: ast_util.hpp:188
IsConstant::foldTraverseElementUMinus
bool foldTraverseElementUMinus(AST_Expression)
Definition: ast_util.cpp:240
EXPBINOP
@ EXPBINOP
Definition: ast_types.hpp:166
IsConstant
Definition: ast_util.hpp:265
ast_types.hpp
ReplaceBoolean::ReplaceBoolean
ReplaceBoolean()
Definition: ast_util.cpp:283
AST_Expression_Fold::apply
R apply(AST_Expression e)
Definition: ast_util.hpp:199
newAST_Expression_Call
AST_Expression newAST_Expression_Call(AST_String name, AST_String rest, AST_ExpressionList args)
Definition: ast_builder.cpp:331
BinOpType
BinOpType
Definition: ast_types.hpp:137
STWHEN
@ STWHEN
Definition: ast_types.hpp:191
AST_Visitor
Definition: ast_util.hpp:224
AST_Expression_Traverse::apply
AST_Expression apply(AST_Expression)
Definition: ast_util.cpp:49
AST_Visitor::leave
virtual void leave(AST_Class x)=0
EqualExp
Definition: ast_util.hpp:253
AST_Statement_Visitor
Definition: ast_util.hpp:119
AST_Expression_Visitor::AST_Expression_Visitor
AST_Expression_Visitor()
Definition: ast_util.hpp:84
current_element
#define current_element(it)
Definition: ast_types.hpp:34
PreChange::foldTraverseElement
AST_Expression foldTraverseElement(AST_Expression)
Definition: ast_util.cpp:379
WhenEqualityTrasforms
Definition: ast_util.hpp:297
EqualExp::equalTraverseElement
bool equalTraverseElement(AST_Expression a, AST_Expression b)
Definition: ast_util.cpp:124
expression.hpp
statement.hpp