MicroModelicaCCompiler  4.5.3
function.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 <sstream>
21 
22 #include <generator/function.hpp>
23 #include <util/model_config.hpp>
24 
25 namespace MicroModelica {
26 using namespace IR;
27 using namespace Util;
28 namespace Generator {
29 
30 Function::Function(IR::Function& function, CompileFlags& flags, WriterPtr writer)
31  : _function(function), _flags(flags), _writer(writer), _prefix("__"), _include(), _return_variable(), _symbols(), _void_function(false)
32 {
33  _symbols = ModelConfig::instance().symbols();
37 }
38 
40 {
44 }
45 
47 {
48  includes();
49  body();
50 }
51 
52 void Function::includes()
53 {
54  list<string> code;
55  ImportTable imports = _function.imports();
57  for (string i = imports.begin(it); !imports.end(it); i = imports.next(it)) {
59  if (!_include.lookup(addInclude)) {
61  _writer->write("#include \"" + addInclude + ".h\"", WRITER::Function_Header);
62  }
63  }
66  if (!_include.lookup(addInclude)) {
69  }
70  }
71 }
72 
73 string Function::prototype()
74 {
75  stringstream input;
76  stringstream output;
77  stringstream func;
78  VariableList arguments = _function.arguments();
79  int outputs = _function.outputNbr();
80  string name = _function.name();
81  bool array_single_output = false;
82  for (Variable var : arguments) {
83  if (var.isInput()) {
84  if (var.isString()) {
85  input << "const char *" << var.name() << ",";
86  } else {
87  input << "double " << (var.isArray() ? "*" : "") << var.name() << ",";
88  }
89  } else if (var.isOutput()) {
90  output << "double *" << var.name() << ",";
91  _return_variable = var.name();
92  array_single_output = var.isArray();
93  }
94  }
95  string in = input.str();
96  if (outputs <= 1 && !in.empty()) {
97  in.erase(in.end() - 1, in.end());
98  }
99  if (outputs == 0 || (outputs == 1 && array_single_output) || outputs > 1) {
100  _void_function = true;
101  }
102  if (outputs == 0) {
103  func << "void " << _prefix << name << "(" << in << ")";
104  } else if (outputs == 1 && !array_single_output) {
105  func << "double " << _prefix << name << "(" << in << ")";
106  } else {
107  string out = output.str();
108  out.erase(out.end() - 1, out.end());
109  func << "void " << _prefix << name << "(" << input.str() << out << ")";
110  }
111  return func.str();
112 }
113 
114 string Function::header() { return prototype() + ";"; }
115 
116 void Function::body()
117 {
118  stringstream buffer;
120  _writer->beginBlock(WRITER::Function_Code);
121  localSymbols();
124  for (Statement stm = stms.begin(it); !stms.end(it); stm = stms.next(it)) {
125  buffer << stm << endl;
126  }
127  _writer->write(buffer, WRITER::Function_Code);
130  for (ExternalFunction ef = eft.begin(eit); !eft.end(eit); ef = eft.next(eit)) {
131  buffer << ef;
132  }
133  _writer->write(buffer.str(), WRITER::Function_Code);
134  if (!_void_function) {
135  _writer->write("return " + _return_variable + ";", WRITER::Function_Code);
136  }
137  _writer->endBlock(WRITER::Function_Code);
138  _writer->write("\n", WRITER::Function_Code);
139 }
140 
142 {
143  list<string> ret;
144  stringstream buffer;
145  VarSymbolTable symbols = _function.symbols();
147  bool local_symbols = false;
148  for (Variable var = symbols.begin(it); !symbols.end(it); var = symbols.next(it)) {
149  if (var.isConstant()) {
150  continue;
151  }
152  if (var.isOutput() && _void_function) {
153  continue;
154  }
155  if (!var.isInput()) {
156  local_symbols = true;
157  _writer->write(var.declaration(), WRITER::Function_Code);
158  _writer->write(var.initialization(), WRITER::Function_Code);
159  }
160  }
161  if (local_symbols) {
162  _writer->write("\n", WRITER::Function_Code);
163  }
164 }
165 
166 void Function::setPrefix(string prefix) { _prefix = prefix; }
167 
168 void Function::addInclude(string include) { _include[include] = include; }
169 
171 
172 } // namespace Generator
173 } // namespace MicroModelica
MicroModelica::Generator::Function::_prefix
std::string _prefix
Definition: function.hpp:100
MicroModelica::IR::Function::imports
Util::ImportTable imports() const
Definition: class.cpp:170
MicroModelica::Generator::Function::_return_variable
std::string _return_variable
Definition: function.hpp:102
MicroModelica::IR::Function::Function
Function()
Definition: class.cpp:70
function.hpp
ModelTable< std::string, std::string >
ModelTable::begin
iterator begin()
Definition: table.hpp:68
MicroModelica::Util::VarSymbolTable
Definition: symbol_table.hpp:184
MicroModelica::Util::ModelConfig::symbols
VarSymbolTable & symbols()
Definition: model_config.hpp:122
MicroModelica::IR::Function::statements
StatementTable statements() const
Definition: class.cpp:172
MicroModelica::Util::Variable
Definition: symbol_table.hpp:75
MicroModelica::Generator::Function::addInclude
void addInclude(std::string include)
MicroModelica::IR::Function::name
string name() const
Definition: class.cpp:168
MicroModelica::Util::ModelConfig::setFunctionCode
void setFunctionCode(bool function_code)
Definition: model_config.hpp:145
MicroModelica::Util::Utils::packageName
std::string packageName(std::string name)
Definition: util.cpp:298
MicroModelica::Util::ModelConfig::setSymbols
void setSymbols(const VarSymbolTable &symbols)
Definition: model_config.hpp:135
MicroModelica::Generator::Function::definition
void definition()
Definition: function.cpp:63
MicroModelica::Generator::Function::prototype
std::string prototype()
Definition: function.cpp:90
MicroModelica::Generator::Function::includes
void includes()
Definition: function.cpp:69
MicroModelica::IR::FunctionAnnotation::hasInclude
bool hasInclude()
Definition: annotation.cpp:69
MicroModelica::IR::Function::symbols
Util::VarSymbolTable symbols() const
Definition: class.cpp:98
model_config.hpp
MicroModelica::Generator::Function::_include
Util::SymbolTable _include
Definition: function.hpp:101
MicroModelica::Util::SymbolTable
ModelTable< std::string, std::string > SymbolTable
Definition: equation.hpp:62
MicroModelica::IR::Function::arguments
Util::VariableList arguments() const
Definition: class.cpp:182
MicroModelica::Generator::Function::~Function
~Function()
Definition: function.cpp:56
MicroModelica::Util::ModelConfig::setFunctionOutputs
void setFunctionOutputs(bool function_outputs)
Definition: model_config.hpp:143
ModelTable::end
iterator end()
Definition: table.hpp:70
MicroModelica::IR::Function::annotations
FunctionAnnotation annotations() const
Definition: class.cpp:180
MicroModelica::Generator::Function::_writer
WriterPtr _writer
Definition: function.hpp:99
MicroModelica::IR::ExternalFunctionTable
ModelTable< int, ExternalFunction > ExternalFunctionTable
Definition: helpers.hpp:85
MicroModelica::Generator::Generator::_function
IR::Function _function
Definition: generator.hpp:99
MicroModelica::Generator::Function::header
std::string header()
Definition: function.cpp:131
MicroModelica::Generator::Function::_function
IR::Function _function
Definition: function.hpp:97
MicroModelica::Generator::Function::setPrefix
void setPrefix(std::string prefix)
Definition: function.cpp:183
ModelTable< std::string, std::string >::iterator
std::map< std::string, std::string >::iterator iterator
Definition: table.hpp:61
MicroModelica::Util::ModelConfig::instance
static ModelConfig & instance()
Definition: model_config.hpp:87
MicroModelica::Generator::Function::_symbols
Util::VarSymbolTable _symbols
Definition: function.hpp:103
MicroModelica::Generator::WRITER::Function_Code
@ Function_Code
Definition: writer.hpp:102
MicroModelica::IR::FunctionAnnotation::include
string include()
Definition: annotation.cpp:129
MicroModelica::Generator::WRITER::Function_Header
@ Function_Header
Definition: writer.hpp:101
MicroModelica::IR::Function::outputNbr
unsigned int outputNbr() const
Definition: class.cpp:178
MicroModelica
Definition: files.cpp:45
ModelTable::lookup
bool lookup(Key key)
Definition: table.hpp:63
MicroModelica::IR::StatementTable
ModelTable< int, Statement > StatementTable
Definition: statement.hpp:98
MicroModelica::Util::Utils::instance
static Utils & instance()
Definition: util.hpp:83
MicroModelica::Generator::Function::_void_function
bool _void_function
Definition: function.hpp:104
ModelTable::insert
void insert(Key k, Value v)
Definition: table.hpp:48
MicroModelica::Util::VariableList
std::list< Variable > VariableList
Definition: symbol_table.hpp:199
MicroModelica::IR::Function::externalFunctions
ExternalFunctionTable externalFunctions() const
Definition: class.cpp:174
MicroModelica::Generator::Function::localSymbols
void localSymbols()
Definition: function.cpp:158
MicroModelica::Generator::WriterPtr
std::shared_ptr< Writer > WriterPtr
Definition: writer.hpp:146
MicroModelica::Generator::Function::body
void body()
Definition: function.cpp:133
ModelTable::merge
void merge(ModelTable< Key, Value > other)
Definition: table.hpp:95
ModelTable::next
Value next(iterator &it)
Definition: table.hpp:78