MicroModelicaCCompiler  4.5.3
expression.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 "expression.hpp"
21 
22 #include <sstream>
23 
24 #include <ast/expression.hpp>
25 #include <ir/helpers.hpp>
26 #include <ast/parser/parse.hpp>
27 #include <util/error.hpp>
28 #include <util/model_config.hpp>
29 #include <util/util.hpp>
30 #include <util/visitors/autonomous.hpp>
31 #include <util/visitors/expression_printer.hpp>
32 #include <util/visitors/get_index_variables.hpp>
33 #include <util/visitors/is_constant_index.hpp>
34 #include <util/visitors/partial_eval_exp.hpp>
35 
36 namespace MicroModelica {
37 using namespace Util;
38 namespace IR {
39 
40 Expression::Expression(AST_Expression exp, int order) : _exp(exp), _order(order) {}
41 
42 Expression::Expression() : _exp(nullptr), _order(0) {}
43 
44 string Expression::print() const
45 {
46  stringstream buffer, exp;
47  if (!isEmpty()) {
48  ExpressionPrinter printer(_order);
49  exp << printer.apply(_exp);
50  buffer << exp.str();
51  return buffer.str();
52  }
53  return "";
54 }
55 
56 bool Expression::isScalar() const
57 {
58  if (isReference()) {
59  Option<Variable> var = reference();
60  if (var->isArray()) {
61  CheckIndexExpression constant_index;
62  return constant_index.apply(_exp);
63  }
64  return true;
65  }
66  return false;
67 }
68 
69 bool Expression::isReference() const
70 {
71  if (isEmpty()) {
72  return false;
73  }
74  return _exp->expressionType() == EXPCOMPREF;
75 }
76 
77 Option<Variable> Expression::reference() const
78 {
79  assert(isReference());
80  AST_Expression_ComponentReference cr = _exp->getAsComponentReference();
81  return ModelConfig::instance().lookup(cr->name());
82 }
83 
84 string Expression::usage() const
85 {
86  stringstream buffer;
87  vector<Expression> exps = usageExps();
88  int size = exps.size(), i = 0;
89  for (Expression exp : exps) {
90  PartialEvalExp partial_eval;
91  Expression usage_exp = partial_eval.apply(exp.expression());
92  buffer << usage_exp << (++i < size ? "," : "");
93  }
94  return buffer.str();
95 }
96 
97 string Expression::dimVariables(bool range_idxs) const
98 {
99  stringstream buffer;
100  vector<Expression> exps = usageExps();
101  int size = exps.size(), i = 1;
102  for (Expression exp : exps) {
103  if (range_idxs) {
104  buffer << "_rg";
105  }
106  buffer << "_d" << i << (i < size ? "," : "");
107  i++;
108  }
109  return buffer.str();
110 }
111 
112 vector<Expression> Expression::usageExps() const
113 {
114  vector<Expression> exps;
115  if (isReference()) {
116  AST_Expression_ComponentReference cr = _exp->getAsComponentReference();
117  if (cr->hasIndexes()) {
118  AST_ExpressionList indexes = cr->firstIndex();
119  AST_ExpressionListIterator it;
120  foreach (it, indexes) {
121  exps.push_back(Expression(current_element(it)));
122  }
123  }
124  }
125  return exps;
126 }
127 
128 list<Expression> Expression::indexes() const
129 {
130  list<Expression> exps;
131  if (isReference()) {
132  AST_Expression_ComponentReference cr = _exp->getAsComponentReference();
133  if (cr->hasIndexes()) {
134  AST_ExpressionList indexes = cr->firstIndex();
135  AST_ExpressionListIterator it;
136  foreach (it, indexes) {
138  exps.push_back(idx);
139  }
140  }
141  }
142  return exps;
143 }
144 
145 Expression Expression::generate(string var_name, vector<string> indices)
146 {
147  stringstream code;
148  code << var_name;
149  if (indices.size()) {
150  code << "[";
151  }
152  int i = 0, size = indices.size();
153  for (string exp : indices) {
154  code << exp << ((++i == size) ? "]" : ",");
155  }
156  AST_Expression ast_exp = parseExpression(code.str(), &i);
157  assert(i == 0);
158  return Expression(ast_exp);
159 }
160 
161 std::ostream& operator<<(std::ostream& out, const Expression& s)
162 {
163  out << s.print();
164  return out;
165 }
166 bool Expression::operator<(const Expression& other) const
167 {
168  std::stringstream cmp_this;
169  std::stringstream cmp_other;
170  cmp_this << *this;
171  cmp_other << other;
172  return cmp_this.str() < cmp_other.str();
173 }
174 
175 std::multimap<std::string, int> Expression::usedVariables() const
176 {
177  GetIndexVariables used_variables;
178  return used_variables.apply(_exp);
179 }
180 
181 bool Expression::autonomous() const
182 {
183  Autonomous autonomous;
184  return autonomous.apply(expression());
185 }
186 
187 } // namespace IR
188 } // namespace MicroModelica
EXPCOMPREF
@ EXPCOMPREF
Definition: ast_types.hpp:165
usage
void usage()
Definition: main.cpp:48
MicroModelica::IR::Expression::print
std::string print() const
Definition: expression.cpp:61
helpers.hpp
Option
Definition: util_types.hpp:32
model_config.hpp
MicroModelica::IR::Expression
Definition: expression.hpp:64
MicroModelica::IR::Expression::Expression
Expression()
Definition: expression.cpp:59
MicroModelica::IR::operator<<
std::ostream & operator<<(std::ostream &out, const Expression &s)
Definition: expression.cpp:178
MicroModelica
Definition: files.cpp:45
current_element
#define current_element(it)
Definition: ast_types.hpp:34
util.hpp
error.hpp
expression.hpp