MicroModelicaCCompiler  4.5.3
process_statement.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 <ast/ast_builder.hpp>
21 #include <ir/helpers.hpp>
22 #include "../ir/reduction_functions.hpp"
23 #include "error.hpp"
24 #include "model_config.hpp"
25 #include "util.hpp"
26 #include "symbol_table.hpp"
27 #include "./visitors/convert_disc_red.hpp"
28 
29 #include "process_statement.hpp"
30 
31 namespace MicroModelica {
32 using namespace IR;
33 namespace Util {
34 
35 void processStatement(AST_Statement stm)
36 {
37  switch (stm->statementType()) {
38  case STIF: {
39  AST_Statement_If sti = stm->getAsIf();
40  AST_StatementList stl = sti->statements();
41  AST_StatementListIterator stlit;
42  foreach (stlit, stl) {
44  }
45  AST_Statement_ElseList stelsel = sti->else_if();
46  AST_Statement_ElseListIterator stelselit;
47  foreach (stelselit, stelsel) {
48  stl = current_element(stelselit)->statements();
49  foreach (stlit, stl) {
51  }
52  }
53  stl = sti->else_statements();
54  if (!stl->empty()) {
55  foreach (stlit, stl) {
57  }
58  }
59  break;
60  }
61  case STASSIGN: {
62  AST_Statement_Assign sa = stm->getAsAssign();
63  if (sa->exp()->expressionType() == EXPCALLARG) {
64  AST_Expression_CallArgs eca = sa->exp()->getAsCallArgs();
65  AST_Expression_ComponentReference cr = sa->lhs();
66  int arg_num = eca->arguments()->size();
67  string function_name = cr->name();
68  const string REINIT = "reinit";
69  const string TERMINATE = "terminate";
70  if (function_name.compare(REINIT) == 0) {
71  if (arg_num > 2) {
72  Error::instance().add(eca->lineNum(), EM_IR | EM_WRONG_EXP, ER_Error, "Expected 2 arguments, found %d", arg_num);
73  }
74  AST_Expression e = AST_ListFirst(eca->arguments());
75  AST_Expression_ComponentReference lhs = nullptr;
76  AST_Expression rhs = nullptr;
77  if (e->expressionType() != EXPCOMPREF) {
78  Error::instance().add(e->lineNum(), EM_IR | EM_WRONG_EXP, ER_Error,
79  "Only variables references allowed, expressions not allowed.");
80  } else {
81  lhs = e->getAsComponentReference();
82  VarSymbolTable symbols = ModelConfig::instance().symbols();
83  string sname = lhs->name();
84  Option<Variable> var = symbols[sname];
85  if (!var) {
86  Error::instance().add(lhs->lineNum(), EM_IR | EM_VARIABLE_NOT_FOUND, ER_Error, "process_statement.cpp:88 %s", sname.c_str());
87  }
88  if (!var->isState()) {
89  Error::instance().add(lhs->lineNum(), EM_IR | EM_WRONG_EXP, ER_Error, "Only state variables allowed.");
90  } else {
91  AST_ExpressionListIterator eli;
92  AST_ExpressionList el = eca->arguments();
93  int c = 0;
94  foreach (eli, el) {
95  if (c == 0) {
96  c++;
97  continue;
98  }
99  rhs = current_element(eli);
100  }
101  }
102  sa->setLHS(lhs);
103  sa->setExp(rhs);
104  }
105  } else if (function_name.compare(TERMINATE) == 0) {
106  assert(sa->lhs() != nullptr);
107  assert(sa->exp() != nullptr);
108  if (arg_num) {
109  Error::instance().add(eca->lineNum(), EM_IR | EM_WRONG_EXP, ER_Error, "No arguments expected, found %d", arg_num);
110  }
111  }
112  }
113  break;
114  }
115  case STFOR: {
116  AST_Statement_For stf = stm->getAsFor();
117  AST_StatementList stms = stf->statements();
118  AST_StatementListIterator stmit;
119  foreach (stmit, stms) {
121  }
122  break;
123  }
124  default:
125  break;
126  }
127 }
128 
129 void applyReduction(AST_Statement_Assign asg, AST_StatementList stms, AST_StatementListIterator stm_it)
130 {
131  VarSymbolTable symbols = ModelConfig::instance().symbols();
132  ReductionFunctions<AST_Statement, ConvertDiscRed> reduction_functions(asg->exp(), Utils::instance().variable(asg->lhs()));
133  AST_Expression new_exp = reduction_functions.apply();
134  if (reduction_functions.hasReductionFunctions()) {
135  asg->setExp(new_exp);
136  list<AST_Statement> code = reduction_functions.code();
137  // In case of statements we only add one additional statement.
138  assert(code.size() == 1);
139  AST_Statement ast = code.front();
140  assert(ast != nullptr);
141  AST_ListInsert(stms, stm_it++, ast);
142  }
143 }
144 
145 void reduceStatement(AST_Statement stm, AST_StatementList stms, AST_StatementListIterator stm_it)
146 {
147  processStatement(stm);
148  if (stm->statementType() == STASSIGN) {
149  AST_Statement_Assign asg = stm->getAsAssign();
150  applyReduction(asg, stms, stm_it);
151  } else if (stm->statementType() == STFOR) {
152  AST_Statement_For stm_for = stm->getAsFor();
153  AST_StatementList for_stms = stm_for->statements();
154  AST_StatementListIterator for_it;
155  foreach (for_it, for_stms) {
156  reduceStatement(current_element(for_it), for_stms, for_it);
157  }
158  } else if (stm->statementType() == STIF) {
159  AST_Statement_If stm_if = stm->getAsIf();
160  AST_StatementList if_stms = stm_if->statements();
161  AST_StatementListIterator if_it;
162  foreach (if_it, if_stms) {
163  reduceStatement(current_element(if_it), if_stms, if_it);
164  }
165  AST_Statement_ElseList else_if_stms = stm_if->else_if();
166  AST_Statement_ElseListIterator else_if_it;
167  foreach (else_if_it, else_if_stms) {
168  if_stms = current_element(else_if_it)->statements();
169  foreach (if_it, if_stms) {
170  reduceStatement(current_element(if_it), if_stms, if_it);
171  }
172  }
173  if_stms = stm_if->else_statements();
174  if (!if_stms->empty()) {
175  foreach (if_it, if_stms) {
176  reduceStatement(current_element(if_it), if_stms, if_it);
177  }
178  }
179  }
180 }
181 
182 } // namespace Util
183 } // namespace MicroModelica
MicroModelica::Util::Error::instance
static Error & instance()
Definition: error.hpp:128
ast_builder.hpp
EXPCOMPREF
@ EXPCOMPREF
Definition: ast_types.hpp:165
MicroModelica::Util::ModelConfig::symbols
VarSymbolTable & symbols()
Definition: model_config.hpp:122
EXPCALLARG
@ EXPCALLARG
Definition: ast_types.hpp:171
symbol_table.hpp
helpers.hpp
Option
Definition: util_types.hpp:32
MicroModelica::Util::reduceStatement
void reduceStatement(AST_Statement stm, AST_StatementList stms, AST_StatementListIterator stm_it)
Definition: process_statement.cpp:162
model_config.hpp
STFOR
@ STFOR
Definition: ast_types.hpp:191
MicroModelica::Util::ER_Error
@ ER_Error
ER_Error.
Definition: error.hpp:122
AST_ListInsert
void AST_ListInsert(list< T1 > *l1, typename std::list< T1 >::iterator it, T1 e)
Definition: ast_types.hpp:261
MicroModelica::Util::Utils::variable
Variable variable(AST_Expression exp)
Definition: util.cpp:363
MicroModelica::Util::Error::add
void add(int pos, unsigned int code, ER_Type t, const std::string message,...)
Definition: error.cpp:42
MicroModelica::Util::ModelConfig::instance
static ModelConfig & instance()
Definition: model_config.hpp:87
EM_VARIABLE_NOT_FOUND
#define EM_VARIABLE_NOT_FOUND
Definition: error.hpp:71
STASSIGN
@ STASSIGN
Definition: ast_types.hpp:191
AST_ListFirst
T1 AST_ListFirst(list< T1 > *l)
Definition: ast_types.hpp:271
MicroModelica::Util::processStatement
void processStatement(AST_Statement stm)
Definition: process_statement.cpp:52
STIF
@ STIF
Definition: ast_types.hpp:191
process_statement.hpp
EM_IR
#define EM_IR
Definition: error.hpp:66
MicroModelica
Definition: files.cpp:45
MicroModelica::Util::Utils::instance
static Utils & instance()
Definition: util.hpp:83
MicroModelica::Util::applyReduction
void applyReduction(AST_Statement_Assign asg, AST_StatementList stms, AST_StatementListIterator stm_it)
Definition: process_statement.cpp:146
EM_WRONG_EXP
#define EM_WRONG_EXP
Definition: error.hpp:77
current_element
#define current_element(it)
Definition: ast_types.hpp:34
util.hpp
error.hpp