MicroModelicaCCompiler  4.5.3
macros.cpp
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 #include "macros.hpp"
21 
22 #include <sstream>
23 
24 #include <ir/helpers.hpp>
25 
26 using namespace std;
27 
28 namespace MicroModelica {
29 using namespace Util;
30 using namespace IR;
31 namespace Generator {
32 
33 Macros::Macros(IR::Model& model, Util::Variable& variable) : _model(model), _variable(variable), _is_qss(false)
34 {
36  initialize();
37 }
38 
39 string Macros::parameters(MACROS::Offset offset) const
40 {
41  stringstream buffer;
42  string dim_offset = "";
43  if (offset == MACROS::Engine) {
44  dim_offset = "-1";
45  }
46  int dim = _variable.dimensions();
47  if (dim) {
48  buffer << "(";
49  }
50  for (int i = 0; i < dim; i++) {
51  buffer << "d" << i + 1 << dim_offset << (((i == dim - 1) && !_is_qss) ? ")" : ",");
52  }
53  if (_is_qss && dim) {
54  buffer << "coeff)";
55  } else if (_is_qss) {
56  buffer << "(coeff)";
57  }
58  return buffer.str();
59 }
60 
61 string Macros::arguments(bool state) const
62 {
63  stringstream arguments;
64  string index_offset = "-1";
65  int dim = _variable.dimensions();
66  stringstream end;
67  if (_is_qss && state) {
68  end << "*" << _model.annotations().polyCoeffs() << " + coeff";
69  }
70  if (dim) {
71  arguments << "(";
72  if (_variable.offset()) {
73  arguments << _variable.offset() << "+";
74  }
75  for (int i = 0; i < dim; i++) {
76  stringstream variable;
77  stringstream index;
78  index << i + 1 << index_offset;
79  variable << "*" << _variable.rowSize(i) << "+";
80  arguments << (_variable.size(i) == 1 ? "0" : "(d" + index.str() + ")");
81  arguments << (i == dim - 1 ? ")" + end.str() : variable.str());
82  }
84  arguments << _variable.offset() << end.str();
85  }
86  arguments << endl;
87  return arguments.str();
88 }
89 
91 {
92  stringstream arguments;
93  int dim = _variable.dimensions();
94  stringstream end;
95  if (dim) {
96  arguments << "(";
97  if (_variable.offset()) {
98  arguments << _variable.offset() << "+";
99  }
100  for (int i = 0; i < dim; i++) {
101  stringstream variable;
102  variable << "*" << _variable.rowSize(i) << "+";
103  arguments << "(d" << i + 1 << "-1)" << (i == dim - 1 ? ")" + end.str() : variable.str());
104  }
105  } else {
106  arguments << _variable.offset() << end.str();
107  }
108  return arguments.str();
109 }
110 
111 string Macros::engineIndex() const
112 {
113  stringstream buffer;
114  int dim = _variable.dimensions();
115  if (dim) {
116  buffer << "(";
117  }
118  for (int i = 0; i < dim; i++) {
119  buffer << "d" << i + 1 << (i == dim - 1 ? ")" : ",");
120  }
121  return buffer.str();
122 }
123 
125 {
126  stringstream index, def, state_index, state_def, init_code, quantized_def;
127  int dim = _variable.dimensions();
128  bool idx = !_variable.isParameter() || dim;
129  const bool IS_STATE = _variable.isState();
130  string params = parameters();
131  if (idx) {
132  index << "_idx" << _variable << params;
133  static const bool MATRIX_INDEX = false;
134  _macros << "#define " << index.str() << " " << arguments(MATRIX_INDEX);
135  if (_is_qss) {
136  state_index << "_state_idx" << _variable << params;
137  _macros << "#define " << state_index.str() << " " << arguments();
138  }
139  }
140  if (!_variable.isEqType() && !_variable.isOutput()) {
141  _macros << "#define " << _variable << params << " ";
142  if (IS_STATE) {
143  _macros << "x";
144  quantized_def << "#define _q" << _variable << params << " q";
145  init_code << "#define _init" << _variable << params << " x";
146  }
147  if (_variable.isAlgebraic()) {
148  _macros << "a";
149  }
150  if (_variable.isDiscrete()) {
151  _macros << "d";
152  }
153  if (_variable.isParameter()) {
154  _macros << "__PAR__" << _variable.name();
155  }
156  if (idx) {
157  def << "[";
158  }
159  if (_is_qss) {
160  def << state_index.str();
161  } else {
162  def << index.str();
163  }
164  if (idx) {
165  def << "]";
166  }
167  state_def << def.str();
168  if (_is_qss && IS_STATE) {
169  state_def << " * COEFF_MULTIPLIER(coeff)";
170  }
171  _macros << state_def.str() << endl;
172  if (IS_STATE) {
173  init_code << def.str() << endl;
174  _macros << init_code.str();
175  quantized_def << state_def.str() << endl;
176  if (_is_qss) {
177  _macros << quantized_def.str();
178  }
179  }
180  }
181 
182  int offset = _variable.offset();
183  Range range = Range(_variable);
186  _macros << "#define _eval" << _variable << parameters() << " ";
187  _macros << engineIndexArguments() << endl;
188  _macros << fp.accessMacros(_variable.print(), offset, range);
189  } else if (_variable.isAlgebraic()) {
190  _macros << fp.accessMacros(_variable.print(), offset, range);
191  }
192  if (_is_qss && _variable.isState()) {
193  _macros << "#define _eval_dep" << _variable << params << " ";
194  _macros << "dx" << def.str() << endl;
195  }
196 }
197 
198 string Macros::usage(string token, Option<Range> range, int id) const
199 {
200  stringstream buffer, index;
201  if (range) {
202  index << "(" << range->indexes() << ")";
203  }
204  buffer << token << index.str();
205  return buffer.str();
206 }
207 
208 string Macros::indexMacro(string token, Option<Range> range, int id) const
209 {
210  stringstream buffer, index, arguments;
211  if (range) {
212  index << "(" << range->indexes() << ")";
213  }
214  buffer << "#define " << token << index.str() << " ";
215  if (range) {
216  int dim = range->definition().size();
217  stringstream end;
218  RangeDefinitionTable rdt = range->definition();
220  arguments << "(";
221  int i = 0;
222  for (RangeDefinition rd = rdt.begin(it); !rdt.end(it); rd = rdt.next(it), i++) {
223  stringstream variable;
224  variable << "*" << range->rowSize(i) << "+";
225  arguments << "(" << rdt.key(it) << "-1)" << (i == dim - 1 ? ")" : variable.str());
226  }
227  buffer << arguments.str();
228  } else {
229  buffer << id - 1 << endl;
230  }
231  return buffer.str();
232 }
233 
234 string Macros::modelAccess(int discretes, int algebraics)
235 {
236  stringstream buffer;
237  buffer << "#define MODEL_DATA_ACCESS(m) \\" << endl;
238  if (discretes && algebraics) {
239  buffer << " double* x = m->x; \\" << endl;
240  buffer << " double* d = m->d; \\" << endl;
241  buffer << " double* a = m->alg;" << endl;
242  } else if (discretes) {
243  buffer << " double* x = m->x; \\" << endl;
244  buffer << " double* d = m->d;" << endl;
245  } else if (algebraics) {
246  buffer << " double* x = m->x; \\" << endl;
247  buffer << " double* a = m->alg;" << endl;
248  } else {
249  buffer << " double* x = m->x; " << endl;
250  }
251  buffer << endl;
252  return buffer.str();
253 }
254 
255 string Macros::coeffMultipliers(int order)
256 {
257  stringstream buffer;
258  buffer << "#define COEFF_MULTIPLIER(c) COEFF_MULTIPLIER_##c" << endl;
259  switch (order) {
260  case 1:
261  buffer << "#define COEFF_MULTIPLIER_0 1" << endl;
262  buffer << "#define COEFF_MULTIPLIER_1 1" << endl;
263  break;
264  case 2:
265  buffer << "#define COEFF_MULTIPLIER_0 1" << endl;
266  buffer << "#define COEFF_MULTIPLIER_1 1" << endl;
267  buffer << "#define COEFF_MULTIPLIER_2 2" << endl;
268  break;
269  case 3:
270  buffer << "#define COEFF_MULTIPLIER_0 1" << endl;
271  buffer << "#define COEFF_MULTIPLIER_1 1" << endl;
272  buffer << "#define COEFF_MULTIPLIER_2 2" << endl;
273  buffer << "#define COEFF_MULTIPLIER_3 6" << endl;
274  break;
275  case 4:
276  buffer << "#define COEFF_MULTIPLIER_0 1" << endl;
277  buffer << "#define COEFF_MULTIPLIER_1 1" << endl;
278  buffer << "#define COEFF_MULTIPLIER_2 2" << endl;
279  buffer << "#define COEFF_MULTIPLIER_3 6" << endl;
280  buffer << "#define COEFF_MULTIPLIER_4 24" << endl;
281  break;
282  }
283  buffer << endl;
284  return buffer.str();
285 }
286 
287 std::string Macros::print() const { return _macros.str(); };
288 
289 std::ostream& operator<<(std::ostream& out, const Macros& m) { return out << m.print(); }
290 
291 } // namespace Generator
292 } // namespace MicroModelica
MicroModelica::IR::FunctionPrinter
Definition: helpers.hpp:147
MicroModelica::IR::Range
Definition: index.hpp:164
MicroModelica::Generator::Macros::engineIndex
std::string engineIndex() const
Definition: macros.cpp:111
ModelTable< std::string, RangeDefinition >
ModelTable::begin
iterator begin()
Definition: table.hpp:68
MicroModelica::Generator::Macros::print
std::string print() const
Definition: macros.cpp:287
MicroModelica::Util::Variable
Definition: symbol_table.hpp:75
macros.hpp
MicroModelica::Util::Variable::size
unsigned int size()
Definition: symbol_table.cpp:192
MicroModelica::Util::Variable::isOutput
bool isOutput() const
Definition: symbol_table.hpp:109
MicroModelica::Generator::Macros::_model
IR::Model _model
Definition: macros.hpp:91
MicroModelica::Generator::MACROS::Engine
@ Engine
Definition: macros.hpp:102
ModelTable::key
Key key(iterator &it)
Definition: table.hpp:94
helpers.hpp
Option
Definition: util_types.hpp:32
MicroModelica::Util::Variable::print
std::string print() const
Definition: symbol_table.cpp:210
MicroModelica::Util::Variable::name
string name() const
Definition: symbol_table.hpp:127
MicroModelica::Generator::Macros::_variable
Util::Variable _variable
Definition: macros.hpp:92
MicroModelica::Generator::Macros::indexMacro
std::string indexMacro(std::string token, Option< IR::Range > range, int id) const
Definition: macros.cpp:208
MicroModelica::Util::Variable::offset
int offset() const
Definition: symbol_table.hpp:144
MicroModelica::Util::Variable::isEqType
bool isEqType() const
Definition: symbol_table.hpp:111
MicroModelica::Util::Variable::isParameter
bool isParameter() const
Definition: symbol_table.hpp:103
MicroModelica::IR::ModelAnnotation::isClassic
bool isClassic()
Definition: annotation.cpp:666
IS_STATE
#define IS_STATE(X)
Definition: ast_util.hpp:49
ModelTable::end
iterator end()
Definition: table.hpp:70
MicroModelica::Generator::Macros::arguments
std::string arguments(bool state=true) const
Definition: macros.cpp:61
MicroModelica::IR::ModelAnnotation::polyCoeffs
int polyCoeffs()
Definition: annotation.cpp:702
MicroModelica::Generator::Macros::_macros
std::stringstream _macros
Definition: macros.hpp:94
MicroModelica::Util::Variable::isAlgebraic
bool isAlgebraic() const
Definition: symbol_table.hpp:119
ModelTable< std::string, RangeDefinition >::iterator
std::map< std::string, RangeDefinition >::iterator iterator
Definition: table.hpp:61
MicroModelica::Generator::Macros::engineIndexArguments
std::string engineIndexArguments() const
Definition: macros.cpp:90
MicroModelica::Generator::Macros
Definition: macros.hpp:71
MicroModelica::Generator::Macros::coeffMultipliers
std::string coeffMultipliers(int order)
Definition: macros.cpp:255
MicroModelica::Util::Variable::rowSize
unsigned int rowSize(unsigned int dim) const
Definition: symbol_table.cpp:201
MicroModelica::Generator::Macros::parameters
std::string parameters(MACROS::Offset offset=MACROS::Modelica) const
Definition: macros.cpp:39
MicroModelica::Util::Variable::isState
bool isState() const
Definition: symbol_table.hpp:113
MicroModelica
Definition: files.cpp:45
MicroModelica::Util::Variable::isDiscrete
bool isDiscrete() const
Definition: symbol_table.hpp:104
MicroModelica::IR::Model
Definition: class.hpp:160
MicroModelica::Generator::Macros::initialize
void initialize()
Definition: macros.cpp:124
MicroModelica::Generator::Macros::usage
std::string usage(std::string token, Option< IR::Range > range, int id) const
Definition: macros.cpp:198
MicroModelica::Util::Variable::dimensions
unsigned long dimensions() const
Definition: symbol_table.hpp:135
MicroModelica::Generator::MACROS::Offset
Offset
Definition: macros.hpp:85
MicroModelica::Generator::operator<<
std::ostream & operator<<(std::ostream &out, const Macros &m)
Definition: macros.cpp:289
MicroModelica::Generator::Macros::_is_qss
bool _is_qss
Definition: macros.hpp:93
MicroModelica::IR::Model::annotations
ModelAnnotation annotations() const
Definition: class.hpp:177
MicroModelica::IR::RangeDefinition
Definition: index.hpp:136
MicroModelica::Generator::Macros::modelAccess
std::string modelAccess(int discretes, int algebraics)
Definition: macros.cpp:234
MicroModelica::IR::FunctionPrinter::accessMacros
std::string accessMacros(std::string token, int offset, Option< Range > range, bool modelica_index=true) const
TODO: Review modelica_index parameter usage.
Definition: helpers.cpp:371
ModelTable::next
Value next(iterator &it)
Definition: table.hpp:78