diff --git a/src/engine/.vscode/launch.json b/src/engine/.vscode/launch.json index 17c762f7..68010dee 100644 --- a/src/engine/.vscode/launch.json +++ b/src/engine/.vscode/launch.json @@ -23,6 +23,25 @@ "ignoreFailures": true } ] + }, + + // Advection model + { + "name": "Advection.", + "type": "cppdbg", + "request": "launch", + "program": "/home/joaquin/work/qss-solver/build/advection/advection", + "cwd": "/home/joaquin/work/qss-solver/build/advection/", + "environment": [], + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] } + ] } \ No newline at end of file diff --git a/src/engine/.vscode/settings.json b/src/engine/.vscode/settings.json index 4a1504b0..a5623fce 100644 --- a/src/engine/.vscode/settings.json +++ b/src/engine/.vscode/settings.json @@ -1,7 +1,20 @@ { "files.associations": { "random": "cpp", - "qss_bdf.h": "c" + "qss_bdf.h": "c", + "array": "c", + "compare": "c", + "functional": "c", + "istream": "c", + "ostream": "c", + "ranges": "c", + "tuple": "c", + "type_traits": "c", + "utility": "c", + "typeindex": "c", + "typeinfo": "c", + "qss_data.h": "c" }, - "C_Cpp.dimInactiveRegions": true + "C_Cpp.dimInactiveRegions": true, + "sonarlint.pathToCompileCommands": "${workspaceFolder}/compile_commands.json" } \ No newline at end of file diff --git a/src/mmoc/.vscode/settings.json b/src/mmoc/.vscode/settings.json index 6ac21905..221ab129 100644 --- a/src/mmoc/.vscode/settings.json +++ b/src/mmoc/.vscode/settings.json @@ -78,5 +78,6 @@ "docwriter.progress.trackFunctions": true, "docwriter.progress.trackMethods": false, "docwriter.progress.trackClasses": false, - "docwriter.progress.trackTypes": false + "docwriter.progress.trackTypes": false, + "sonarlint.pathToCompileCommands": "${workspaceFolder}/compile_commands.json" } \ No newline at end of file diff --git a/src/mmoc/generator/files.cpp b/src/mmoc/generator/files.cpp index 49d3612d..044983df 100644 --- a/src/mmoc/generator/files.cpp +++ b/src/mmoc/generator/files.cpp @@ -51,22 +51,20 @@ using namespace Util; namespace Generator { Files::Files(ModelInstancePtr modelInstance, Model& model, CompileFlags& flags) - : _fname(model.name()), _model(model), _modelInstance(modelInstance), _writer(new FileWriter()), _flags(flags) + : _fname(model.name()), _model(model), _modelInstance(modelInstance), _writer(std::make_shared()), _flags(flags) { if (_flags.hasOutputFile()) { _fname = _flags.outputFile(); } } -Files::Files(string name, CompileFlags& flags) : _fname(name), _model(), _writer(new FileWriter()), _flags(flags) +Files::Files(string name, CompileFlags& flags) : _fname(name), _model(), _writer(std::make_shared()), _flags(flags) { if (_flags.hasOutputFile()) { _fname = _flags.outputFile(); } } -Files::~Files() {} - void Files::makefile() { stringstream buffer; @@ -99,11 +97,10 @@ void Files::makefile() } if (_flags.hasObjects()) { list objects = _flags.objects(); - for (list::iterator it = objects.begin(); it != objects.end(); it++) { - string inc = *it; - unsigned int f = inc.rfind("/"); - inc.erase(inc.begin() + f, inc.end()); - include.insert(inc, inc); + for (auto obj : objects) { + unsigned long f = obj.rfind("/"); + obj.erase(obj.begin() + f, obj.end()); + include.insert(obj, obj); } } string pinclude = Utils::instance().environmentVariable("MMOC_INCLUDE"); @@ -136,8 +133,8 @@ void Files::makefile() if (_flags.hasObjects()) { buffer << "SRC := "; list objects = _flags.objects(); - for (list::iterator it = objects.begin(); it != objects.end(); it++) { - buffer << *it << " "; + for (const auto& obj : objects) { + buffer << obj << " "; } _writer->print(buffer); } @@ -305,9 +302,10 @@ void Files::settings(ModelAnnotation annotation) _writer->print("sol=\"" + annotation.solverString() + "\";"); list dq = annotation.dqmin(); buffer << "dqmin=("; - int count = 0, size = dq.size(); - for (list::iterator it = dq.begin(); it != dq.end(); it++) { - buffer << *it; + unsigned long count = 0; + unsigned long size = dq.size(); + for (const auto& it : dq) { + buffer << it; if (++count < size) { buffer << ","; } @@ -318,8 +316,8 @@ void Files::settings(ModelAnnotation annotation) buffer << "dqrel=("; count = 0; size = dq.size(); - for (list::iterator it = dq.begin(); it != dq.end(); it++) { - buffer << *it; + for (const auto& it : dq) { + buffer << it; if (++count < size) { buffer << ","; } @@ -340,19 +338,31 @@ void Files::settings(ModelAnnotation annotation) _writer->print(buffer); buffer << "BDFMaxStep=" << annotation.BDFMaxStep() << ";"; _writer->print(buffer); + addAnnotation(annotation, "CVODEMaxOrder", IntegerAnnotations::CVODEMaxOrder); + addAnnotation(annotation, "XOutput", IntegerAnnotations::XOutput); _writer->clearFile(); } -void Files::printList(list ann, string tag) +void Files::addAnnotation(const IR::ModelAnnotation& annotation, const string& mmo_name, IntegerAnnotations name) +{ + if (annotation.hasAnnotation(name)) { + stringstream buffer; + buffer << mmo_name << "=" << annotation.getAnnotation(name) << ";"; + _writer->print(buffer); + } +} + +void Files::printList(const list& ann, const string& tag) const { stringstream buffer; if (ann.empty()) { return; } buffer << tag << "=("; - int count = 0, size = ann.size(); - for (list::iterator it = ann.begin(); it != ann.end(); it++) { - buffer << *it; + unsigned long count = 0; + unsigned long size = ann.size(); + for (const auto& it : ann) { + buffer << it; if (++count < size) { buffer << ","; } @@ -366,7 +376,6 @@ void Files::bdfPartition() AST_ExpressionList BDF_exps = _model.annotations().BDFPartition(); AST_ExpressionListIterator bdf_exp_it; list variables; - list::iterator var_it; foreach (bdf_exp_it, BDF_exps) { PartitionInterval partition_interval; list ret = partition_interval.apply(current_element(bdf_exp_it)); @@ -374,11 +383,10 @@ void Files::bdfPartition() } string file_name = _fname + "_BDF.part"; ofstream partition(file_name.c_str(), ios::out); - int partition_size = variables.size(); + unsigned long partition_size = variables.size(); partition << partition_size << endl; - for (var_it = variables.begin(); var_it != variables.end(); var_it++) { - int val = *var_it; - partition << val << endl; + for (const auto& var_it : variables) { + partition << var_it << endl; } partition.close(); } diff --git a/src/mmoc/generator/files.h b/src/mmoc/generator/files.h index 695ccdb2..57bce4f5 100644 --- a/src/mmoc/generator/files.h +++ b/src/mmoc/generator/files.h @@ -35,7 +35,7 @@ class Files { public: Files(ModelInstancePtr modelInstance, IR::Model& model, Util::CompileFlags& flags); Files(string name, Util::CompileFlags& flags); - ~Files(); + ~Files() = default; void makefile(); void run(); void plot(); @@ -43,9 +43,11 @@ class Files { void graph(); void bdfPartition(); - private: + protected: std::string variablePlotSettings(); - void printList(list ann, string tag); + void printList(const list& ann, const string& tag) const; + void addAnnotation(const IR::ModelAnnotation& annotation, const string& mmo_name, IR::IntegerAnnotations name); + string _fname; IR::Model _model; ModelInstancePtr _modelInstance; diff --git a/src/mmoc/generator/generator.cpp b/src/mmoc/generator/generator.cpp index 8408c7f5..48ef8460 100644 --- a/src/mmoc/generator/generator.cpp +++ b/src/mmoc/generator/generator.cpp @@ -36,13 +36,13 @@ using namespace IR; using namespace Util; namespace Generator { -Generator::Generator(const StoredDefinition& std, CompileFlags& flags) +Generator::Generator(const StoredDefinition& std, const CompileFlags& flags) : _std(std), _flags(flags), _model_instance(nullptr), _writer(nullptr), _includes(), _fheader() { if (_flags.output()) { - _writer = WriterPtr(new MemoryWriter()); + _writer = WriterPtr(std::make_shared()); } else { - _writer = WriterPtr(new FileWriter()); + _writer = WriterPtr(std::make_shared()); } } @@ -56,15 +56,15 @@ int Generator::generate() } _writer->setFile(base_name + ".c"); switch (model.annotations().solver()) { - case DOPRI: - case DASSL: - case CVODE_BDF: - case IDA: - case CVODE_AM: - _model_instance = ModelInstancePtr(new ClassicModelInstance(model, _flags, _writer)); + case Solver::DOPRI: + case Solver::DASSL: + case Solver::CVODE_BDF: + case Solver::IDA: + case Solver::CVODE_AM: + _model_instance = ModelInstancePtr(std::make_shared(model, _flags, _writer)); break; default: - _model_instance = ModelInstancePtr(new QSSModelInstance(model, _flags, _writer)); + _model_instance = ModelInstancePtr(std::make_shared(model, _flags, _writer)); } _model_instance->generate(); _writer->clearFile(); @@ -77,7 +77,7 @@ int Generator::generate() files.run(); files.plot(); files.settings(model.annotations()); - if (model.annotations().solver() == LIQSS_BDF && !model.annotations().BDFPartition()->empty()) { + if (model.annotations().solver() == Solver::LIQSS_BDF && !model.annotations().BDFPartition()->empty()) { files.bdfPartition(); } if (model.externalFunctions()) { @@ -103,7 +103,7 @@ int Generator::generate() return Error::instance().errors(); } -void Generator::generateIncludes(string name) +void Generator::generateIncludes(const string& name) { stringstream buffer; buffer << "#include " << endl; @@ -112,15 +112,13 @@ void Generator::generateIncludes(string name) _writer->write(buffer, WRITER::Function_Header); } -void Generator::generateModel() {} - -void Generator::calledFunctionHeader(string file_name) +void Generator::calledFunctionHeader(const string& file_name) { string indent = _writer->indent(1); string file = file_name; file.append(".h"); _writer->setFile(file); - for (list::iterator it = _fheader.begin(); it != _fheader.end(); it++) { + for (auto it = _fheader.begin(); it != _fheader.end(); it++) { _writer->print(*it); } _writer->clearFile(); diff --git a/src/mmoc/generator/generator.h b/src/mmoc/generator/generator.h index c4d9713c..249d55d2 100644 --- a/src/mmoc/generator/generator.h +++ b/src/mmoc/generator/generator.h @@ -17,7 +17,7 @@ ******************************************************************************/ -#pragma once +#pragma once #include #include @@ -37,14 +37,13 @@ namespace Generator { class Generator { public: - Generator(const IR::StoredDefinition& std, Util::CompileFlags& flags); + Generator(const IR::StoredDefinition& std, const Util::CompileFlags& flags); ~Generator() = default; int generate(); private: - void generateIncludes(string name); - void generateModel(); - void calledFunctionHeader(string file_name); + void generateIncludes(const string& name); + void calledFunctionHeader(const string& file_name); IR::StoredDefinition _std; IR::Function _function; IR::Package _package; @@ -57,4 +56,3 @@ class Generator { }; } // namespace Generator } // namespace MicroModelica - diff --git a/src/mmoc/generator/model_instance.h b/src/mmoc/generator/model_instance.h index 5a81efb1..c2b5b8be 100644 --- a/src/mmoc/generator/model_instance.h +++ b/src/mmoc/generator/model_instance.h @@ -35,7 +35,7 @@ namespace Generator { namespace MODEL_INSTANCE { -typedef enum { +enum class Component { Model_Settings, Model, Deps, @@ -47,9 +47,10 @@ typedef enum { BdfModel, CLC_Init, QSS_Init -} Component; +}; + +enum class NodeType { SD, SZ, HD, HZ, DD }; -typedef enum { SD, SZ, HD, HZ, DD } NodeType; } // namespace MODEL_INSTANCE class ModelInstance { @@ -118,14 +119,14 @@ class QSSModelInstance : public ModelInstance { public: QSSModelInstance(); QSSModelInstance(IR::Model &model, Util::CompileFlags &flags, WriterPtr writer); - ~QSSModelInstance() = default; - void initializeDataStructures(); - Graph computationalGraph(); - void generate(); - void header(); + ~QSSModelInstance() override = default; + void initializeDataStructures() override; + Graph computationalGraph() override; + void generate() override; + void header() override; protected: - void definition(); + void definition() override; void dependencies(); void bdfDefinition(); @@ -142,13 +143,13 @@ class QSSModelInstance : public ModelInstance { class ClassicModelInstance : public ModelInstance { public: ClassicModelInstance(IR::Model &model, Util::CompileFlags &flags, WriterPtr writer); - ~ClassicModelInstance() = default; - void initializeDataStructures(); - void generate(); - void header(); + ~ClassicModelInstance() override = default; + void initializeDataStructures() override; + void generate() override; + void header() override; protected: - void definition(); + void definition() override; private: void allocateSolver(); @@ -159,6 +160,7 @@ class ClassicModelInstance : public ModelInstance { WriterPtr _writer; }; -typedef std::shared_ptr ModelInstancePtr; +using ModelInstancePtr = std::shared_ptr; + } // namespace Generator } // namespace MicroModelica diff --git a/src/mmoc/ir/annotation.cpp b/src/mmoc/ir/annotation.cpp index e4587339..d53227b1 100644 --- a/src/mmoc/ir/annotation.cpp +++ b/src/mmoc/ir/annotation.cpp @@ -17,31 +17,34 @@ ******************************************************************************/ -#include "annotation.h" - +#include #include -#include "../ast/element.h" -#include "../ast/expression.h" -#include "../ast/modification.h" -#include "../util/error.h" -#include "../util/model_config.h" -#include "../util/symbol_table.h" -#include "../util/util.h" +#include "annotation.h" +#include +#include +#include +#include "annotation.h" +#include +#include +#include +#include namespace MicroModelica { using namespace Util; namespace IR { -FunctionAnnotation::FunctionAnnotation() : _annotations(), _derivative(), _include() +FunctionAnnotation::FunctionAnnotation() : _annotations(), _derivative(), _include() { initialize(); } + +void FunctionAnnotation::initialize() { _libraryDirectory = Utils::instance().environmentVariable("MMOC_LIBRARIES"); _includeDirectory = Utils::instance().environmentVariable("MMOC_INCLUDE"); - _annotations.insert(pair("derivative", DERIVATIVE)); - _annotations.insert(pair("Include", INCLUDE)); - _annotations.insert(pair("IncludeDirectory", INCLUDE_DIRECTORY)); - _annotations.insert(pair("Library", LIBRARY)); - _annotations.insert(pair("LibraryDirectory", LIBRARY_DIRECTORY)); + _annotations.insert(pair("derivative", type::DERIVATIVE)); + _annotations.insert(pair("Include", type::INCLUDE)); + _annotations.insert(pair("IncludeDirectory", type::INCLUDE_DIRECTORY)); + _annotations.insert(pair("Library", type::LIBRARY)); + _annotations.insert(pair("LibraryDirectory", type::LIBRARY_DIRECTORY)); } bool FunctionAnnotation::hasDerivative() { return !_derivative.empty(); } @@ -61,48 +64,45 @@ bool FunctionAnnotation::insert(AST_Argument_Modification x) if (itf == _annotations.end()) { return false; } - AST_Expression mod = nullptr; - if (x->hasModification()) { - if (x->modification()->modificationType() == MODEQUAL) { - mod = x->modification()->getAsEqual()->exp(); - } - } - switch (itf->second) { - case INCLUDE: - if (mod->expressionType() == EXPSTRING) { - _include = mod->getAsString()->str(); - } - break; - case INCLUDE_DIRECTORY: - if (mod->expressionType() == EXPSTRING) { - _includeDirectory = mod->getAsString()->str(); - } - break; - case LIBRARY: - if (mod->expressionType() == EXPSTRING) { - string l = mod->getAsString()->str(); - _libraries.insert(l, l); - } else if (mod->expressionType() == EXPBRACE) { - AST_ExpressionList el = mod->getAsBrace()->arguments(); - AST_ExpressionListIterator eli; - foreach (eli, el) { - string l = current_element(eli)->getAsString()->str(); + if (x->hasModification() && (x->modification()->modificationType() == MODEQUAL)) { + AST_Expression mod = x->modification()->getAsEqual()->exp(); + switch (itf->second) { + case type::INCLUDE: + if (mod->expressionType() == EXPSTRING) { + _include = mod->getAsString()->str(); + } + break; + case type::INCLUDE_DIRECTORY: + if (mod->expressionType() == EXPSTRING) { + _includeDirectory = mod->getAsString()->str(); + } + break; + case type::LIBRARY: + if (mod->expressionType() == EXPSTRING) { + string l = mod->getAsString()->str(); _libraries.insert(l, l); + } else if (mod->expressionType() == EXPBRACE) { + AST_ExpressionList el = mod->getAsBrace()->arguments(); + AST_ExpressionListIterator eli; + foreach (eli, el) { + string l = current_element(eli)->getAsString()->str(); + _libraries.insert(l, l); + } } + break; + case type::LIBRARY_DIRECTORY: + if (mod->expressionType() == EXPSTRING) { + _libraryDirectory = mod->getAsString()->str(); + } + break; + case type::DERIVATIVE: + if (mod->expressionType() == EXPSTRING) { + _derivative = mod->getAsString()->str(); + } + break; + default: + break; } - break; - case LIBRARY_DIRECTORY: - if (mod->expressionType() == EXPSTRING) { - _libraryDirectory = mod->getAsString()->str(); - } - break; - case DERIVATIVE: - if (mod->expressionType() == EXPSTRING) { - _derivative = mod->getAsString()->str(); - } - break; - default: - break; } return true; } @@ -118,7 +118,7 @@ SymbolTable FunctionAnnotation::libraries() const { return _libraries; } string FunctionAnnotation::libraryDirectory() { return _libraryDirectory; } ModelAnnotation::ModelAnnotation() - : _solver(LIQSS2), + : _solver(Solver::LIQSS2), _solverString("LIQSS2"), _commInterval("CI_Step"), _symDiff(true), @@ -138,12 +138,12 @@ ModelAnnotation::ModelAnnotation() _output(), _initialTime(0), _finalTime(0), - _partitionMethod(Metis), - _partitionMethodString("Metis"), + _partitionMethod(PartitionMethod::Scotch), + _partitionMethodString("Scotch"), _parallel(false), _dt(0), _polyCoeffs(1), - _dtSynch(DT_Fixed), + _dtSynch(DT_Synch::DT_Fixed), _dtSynchString("SD_DT_Asynchronous"), _desc(), _patohSettings(), @@ -159,49 +159,58 @@ ModelAnnotation::ModelAnnotation() _sd_matrix(), _sz_matrix(), _event_ids(), - _current_exp_id(-1), - _random_seed(0) + _current_exp_id(-1) { - _annotations.insert(pair("experiment", EXPERIMENT)); - _annotations.insert(pair("MMO_Description", DESC)); - _annotations.insert(pair("Tolerance", DQREL)); - _annotations.insert(pair("AbsTolerance", DQMIN)); - _annotations.insert(pair("MMO_Weight", WEIGHT)); - _annotations.insert(pair("MMO_Solver", SOLVER)); - _annotations.insert(pair("StartTime", INITIAL_TIME)); - _annotations.insert(pair("StopTime", FINAL_TIME)); - _annotations.insert(pair("MMO_MinStep", MIN_STEP)); - _annotations.insert(pair("MMO_ZCHyst", ZCHYST)); - _annotations.insert(pair("MMO_DerDelta", DER_DELTA)); - _annotations.insert(pair("MMO_LPS", LPS)); - _annotations.insert(pair("MMO_NodeSize", NODE_SIZE)); - _annotations.insert(pair("MMO_OutputType", COMM_INTERVAL)); - _annotations.insert(pair("MMO_Period", STEP_SIZE)); - _annotations.insert(pair("Jacobian", JACOBIAN)); - _annotations.insert(pair("MMO_SymDiff", SYM_DIFF)); - _annotations.insert(pair("MMO_Scheduler", SCHEDULER)); - _annotations.insert(pair("MMO_Output", OUTPUT)); - _annotations.insert(pair("MMO_StoreData", STORE_DATA)); - _annotations.insert(pair("MMO_PartitionMethod", PARTITION_METHOD)); - _annotations.insert(pair("MMO_Parallel", PARALLEL)); - _annotations.insert(pair("MMO_DT_Min", DELTAT)); - _annotations.insert(pair("MMO_DT_Synch", DELTAT_SYNCH)); - _annotations.insert(pair("MMO_PatohSettings", PATOH_SETTINGS)); - _annotations.insert(pair("MMO_MetisSettings", METIS_SETTINGS)); - _annotations.insert(pair("MMO_ScotchSettings", SCOTCH_SETTINGS)); - _annotations.insert(pair("MMO_BDF_Part", BDF_PARTITION)); - _annotations.insert(pair("MMO_BDF_PDepth", BDF_PARTITION_DEPTH)); - _annotations.insert(pair("MMO_BDF_Max_Step", BDF_MAX_STEP)); - _annotations.insert(pair("MMO_Event_Id", EVENT_ID)); - _annotations.insert(pair("MMO_HD", HD_MATRIX)); - _annotations.insert(pair("MMO_HZ", HZ_MATRIX)); - _annotations.insert(pair("MMO_HH", HH_MATRIX)); - _annotations.insert(pair("MMO_LHS_ST", LHS_ST_MATRIX)); - _annotations.insert(pair("MMO_LHS_DSC", LHS_DSC_MATRIX)); - _annotations.insert(pair("MMO_RHS_ST", RHS_ST_MATRIX)); - _annotations.insert(pair("MMO_SD", SD_MATRIX)); - _annotations.insert(pair("MMO_SZ", SZ_MATRIX)); - _annotations.insert(pair("MMO_RandomSeed", RANDOM_SEED)); + initialize(); +} + +void ModelAnnotation::initialize() +{ + _annotations.insert(pair("experiment", type::EXPERIMENT)); + _annotations.insert(pair("MMO_Description", type::DESC)); + _annotations.insert(pair("Tolerance", type::DQREL)); + _annotations.insert(pair("AbsTolerance", type::DQMIN)); + _annotations.insert(pair("MMO_Weight", type::WEIGHT)); + _annotations.insert(pair("MMO_Solver", type::SOLVER)); + _annotations.insert(pair("StartTime", type::INITIAL_TIME)); + _annotations.insert(pair("StopTime", type::FINAL_TIME)); + _annotations.insert(pair("MMO_MinStep", type::MIN_STEP)); + _annotations.insert(pair("MMO_ZCHyst", type::ZCHYST)); + _annotations.insert(pair("MMO_DerDelta", type::DER_DELTA)); + _annotations.insert(pair("MMO_LPS", type::LPS)); + _annotations.insert(pair("MMO_NodeSize", type::NODE_SIZE)); + _annotations.insert(pair("MMO_OutputType", type::COMM_INTERVAL)); + _annotations.insert(pair("MMO_Period", type::STEP_SIZE)); + _annotations.insert(pair("Jacobian", type::JACOBIAN)); + _annotations.insert(pair("MMO_SymDiff", type::SYM_DIFF)); + _annotations.insert(pair("MMO_Scheduler", type::SCHEDULER)); + _annotations.insert(pair("MMO_Output", type::OUTPUT)); + _annotations.insert(pair("MMO_StoreData", type::STORE_DATA)); + _annotations.insert(pair("MMO_PartitionMethod", type::PARTITION_METHOD)); + _annotations.insert(pair("MMO_Parallel", type::PARALLEL)); + _annotations.insert(pair("MMO_DT_Min", type::DELTAT)); + _annotations.insert(pair("MMO_DT_Synch", type::DELTAT_SYNCH)); + _annotations.insert(pair("MMO_PatohSettings", type::PATOH_SETTINGS)); + _annotations.insert(pair("MMO_MetisSettings", type::METIS_SETTINGS)); + _annotations.insert(pair("MMO_ScotchSettings", type::SCOTCH_SETTINGS)); + _annotations.insert(pair("MMO_BDF_Part", type::BDF_PARTITION)); + _annotations.insert(pair("MMO_BDF_PDepth", type::BDF_PARTITION_DEPTH)); + _annotations.insert(pair("MMO_BDF_Max_Step", type::BDF_MAX_STEP)); + _annotations.insert(pair("MMO_Event_Id", type::EVENT_ID)); + _annotations.insert(pair("MMO_HD", type::HD_MATRIX)); + _annotations.insert(pair("MMO_HZ", type::HZ_MATRIX)); + _annotations.insert(pair("MMO_HH", type::HH_MATRIX)); + _annotations.insert(pair("MMO_LHS_ST", type::LHS_ST_MATRIX)); + _annotations.insert(pair("MMO_LHS_DSC", type::LHS_DSC_MATRIX)); + _annotations.insert(pair("MMO_RHS_ST", type::RHS_ST_MATRIX)); + _annotations.insert(pair("MMO_SD", type::SD_MATRIX)); + _annotations.insert(pair("MMO_SZ", type::SZ_MATRIX)); + _annotations.insert(pair("MMO_RandomSeed", type::RANDOM_SEED)); + _annotations.insert(pair("MMO_CVODEMaxOrder", type::CV_ODE_MAX_ORDER)); + _annotations.insert(pair("MMO_XOutput", type::X_OUTPUT)); + _integer_annotations_map.insert(pair("MMO_RandomSeed", IntegerAnnotations::RandomSeed)); + _integer_annotations_map.insert(pair("MMO_CVODEMaxOrder", IntegerAnnotations::CVODEMaxOrder)); + _integer_annotations_map.insert(pair("MMO_XOutput", IntegerAnnotations::XOutput)); _sample.push_back(1e-2); _DQMin.push_back(1e-3); _DQRel.push_back(1e-3); @@ -246,7 +255,7 @@ bool ModelAnnotation::insert(AST_Argument_Modification x) return false; } switch (itf->second) { - case EXPERIMENT: { + case type::EXPERIMENT: { if (x->hasModification()) { AST_Modification mod = x->modification(); if (mod->modificationType() == MODCLASS) { @@ -267,16 +276,16 @@ bool ModelAnnotation::insert(AST_Argument_Modification x) Error::instance().add(x->lineNum(), EM_IR | EM_ANNOTATION_NOT_FOUND, ER_Warning, "%s", x->name()->c_str()); } } break; - case WEIGHT: - case EVENT_ID: - case HD_MATRIX: - case HZ_MATRIX: - case HH_MATRIX: - case LHS_ST_MATRIX: - case LHS_DSC_MATRIX: - case RHS_ST_MATRIX: - case SD_MATRIX: - case SZ_MATRIX: + case type::WEIGHT: + case type::EVENT_ID: + case type::HD_MATRIX: + case type::HZ_MATRIX: + case type::HH_MATRIX: + case type::LHS_ST_MATRIX: + case type::LHS_DSC_MATRIX: + case type::RHS_ST_MATRIX: + case type::SD_MATRIX: + case type::SZ_MATRIX: processArgument(x); break; default: @@ -363,31 +372,31 @@ PartitionMethod ModelAnnotation::partitionMethod() { return _partitionMethod; } DT_Synch ModelAnnotation::getDtSynch(string s) { if (!s.compare("SD_DT_Fixed")) { - return DT_Fixed; + return DT_Synch::DT_Fixed; } else if (!s.compare("SD_DT_Asynchronous")) { - return DT_Asynchronous; + return DT_Synch::DT_Asynchronous; } - return DT_Fixed; + return DT_Synch::DT_Fixed; } PartitionMethod ModelAnnotation::getPartitionMethod(string s) { if (!s.compare("Metis")) { - return Metis; + return PartitionMethod::Metis; } else if (!s.compare("HMetis")) { - return HMetis; + return PartitionMethod::HMetis; } else if (!s.compare("Scotch")) { - return Scotch; + return PartitionMethod::Scotch; } else if (!s.compare("Patoh")) { - return Patoh; + return PartitionMethod::Patoh; } else if (!s.compare("MTPL")) { - return MTPL; + return PartitionMethod::MTPL; } else if (!s.compare("MTPL_IT")) { - return MTPL_IT; + return PartitionMethod::MTPL_IT; } else if (!s.compare("Manual")) { - return Manual; + return PartitionMethod::Manual; } - return Metis; + return PartitionMethod::Scotch; } Solver ModelAnnotation::getSolver(string s) @@ -395,69 +404,69 @@ Solver ModelAnnotation::getSolver(string s) if (!s.compare("QSS")) { _order = 1; _polyCoeffs = 2; - return QSS; + return Solver::QSS; } else if (!s.compare("CQSS")) { _order = 1; _polyCoeffs = 2; - return CQSS; + return Solver::CQSS; } else if (!s.compare("LIQSS")) { _order = 1; _polyCoeffs = 2; - return LIQSS; + return Solver::LIQSS; } else if (!s.compare("QSS2")) { _order = 2; _polyCoeffs = 3; - return QSS2; + return Solver::QSS2; } else if (!s.compare("LIQSS2")) { _order = 2; _polyCoeffs = 3; - return LIQSS2; + return Solver::LIQSS2; } else if (!s.compare("LIQSS_BDF")) { _order = 2; _polyCoeffs = 3; - return LIQSS_BDF; + return Solver::LIQSS_BDF; } else if (!s.compare("QSS3")) { _order = 3; _polyCoeffs = 4; - return QSS3; + return Solver::QSS3; } else if (!s.compare("LIQSS3")) { _order = 3; _polyCoeffs = 4; - return LIQSS3; + return Solver::LIQSS3; } else if (!s.compare("DASSL")) { _order = 1; _polyCoeffs = 1; - return DASSL; + return Solver::DASSL; } else if (!s.compare("DOPRI")) { _order = 1; _polyCoeffs = 1; - return DOPRI; + return Solver::DOPRI; } else if (!s.compare("CVODE_BDF")) { _order = 1; _polyCoeffs = 1; - return CVODE_BDF; + return Solver::CVODE_BDF; } else if (!s.compare("IDA")) { _order = 1; _polyCoeffs = 1; - return IDA; + return Solver::IDA; } else if (!s.compare("CVODE_AM")) { _order = 1; _polyCoeffs = 1; - return CVODE_AM; + return Solver::CVODE_AM; } else if (!s.compare("QSS4")) { _order = 4; _polyCoeffs = 5; - return QSS4; + return Solver::QSS4; } else if (!s.compare("mLIQSS")) { _order = 1; _polyCoeffs = 2; - return mLIQSS; + return Solver::mLIQSS; } else if (!s.compare("mLIQSS2")) { _order = 2; _polyCoeffs = 3; - return mLIQSS2; + return Solver::mLIQSS2; } - return QSS; + return Solver::QSS; } void ModelAnnotation::parseMatrix(AST_Expression exp, IR::MATRIX::UserDefMatrixExps &matrix) @@ -475,140 +484,158 @@ void ModelAnnotation::processAnnotation(string annot, AST_Modification_Equal x) } EvalAnnotation ea; AnnotationValue av; - if (itf->second != DQMIN && itf->second != DQREL && itf->second != STEP_SIZE) { + if (itf->second != type::DQMIN && itf->second != type::DQREL && itf->second != type::STEP_SIZE) { av = ea.apply(x->exp()); } switch (itf->second) { - case DESC: + case type::DESC: _desc = av.str(); break; - case DQMIN: + case type::DQMIN: processList(x->exp(), &_DQMin); break; - case DQREL: + case type::DQREL: processList(x->exp(), &_DQRel); break; - case WEIGHT: + case type::WEIGHT: _weight = av.real(); break; - case SOLVER: + case type::SOLVER: _solver = getSolver(av.str()); _solverString = av.str(); break; - case INITIAL_TIME: + case type::INITIAL_TIME: _initialTime = av.real(); break; - case FINAL_TIME: + case type::FINAL_TIME: _finalTime = av.real(); break; - case MIN_STEP: + case type::MIN_STEP: _minStep = av.real(); break; - case ZCHYST: + case type::ZCHYST: _ZCHyst = av.real(); break; - case DER_DELTA: + case type::DER_DELTA: _derDelta = av.real(); break; - case LPS: + case type::LPS: _lps = av.integer(); break; - case NODE_SIZE: + case type::NODE_SIZE: _nodeSize = av.integer(); break; - case COMM_INTERVAL: + case type::COMM_INTERVAL: _commInterval = av.str(); break; - case STEP_SIZE: + case type::STEP_SIZE: processList(x->exp(), &_sample); break; - case SCHEDULER: + case type::SCHEDULER: _scheduler = av.str(); break; - case JACOBIAN: + case type::JACOBIAN: _jacobian = ("Sparse" == av.str() ? 0 : 1); break; - case SYM_DIFF: + case type::SYM_DIFF: _symDiff = true; if (av.integer() == 0) { _symDiff = false; } break; - case OUTPUT: + case type::OUTPUT: processExpressionList(x->exp(), &_output); break; - case PARTITION_METHOD: + case type::PARTITION_METHOD: _partitionMethod = getPartitionMethod(av.str()); _partitionMethodString = av.str(); break; - case DELTAT_SYNCH: + case type::DELTAT_SYNCH: _dtSynch = getDtSynch(av.str()); _dtSynchString = av.str(); break; - case PARALLEL: + case type::PARALLEL: _parallel = true; if (av.integer() == 0) { _parallel = false; } break; - case DELTAT: + case type::DELTAT: _dt = av.real(); break; - case STORE_DATA: + case type::STORE_DATA: break; - case PATOH_SETTINGS: + case type::PATOH_SETTINGS: processList(x->exp(), &_patohSettings); break; - case SCOTCH_SETTINGS: + case type::SCOTCH_SETTINGS: processList(x->exp(), &_scotchSettings); break; - case METIS_SETTINGS: + case type::METIS_SETTINGS: processList(x->exp(), &_metisSettings); break; - case BDF_PARTITION: + case type::BDF_PARTITION: processExpressionList(x->exp(), _BDFPartition); break; - case BDF_PARTITION_DEPTH: + case type::BDF_PARTITION_DEPTH: _BDFPartitionDepth = av.integer(); break; - case BDF_MAX_STEP: + case type::BDF_MAX_STEP: _BDFMaxStep = av.real(); break; - case EVENT_ID: + case type::EVENT_ID: _event_ids = av.plainStr(); break; - case HD_MATRIX: + case type::HD_MATRIX: parseMatrix(x->exp(), _hd_matrix); break; - case HZ_MATRIX: + case type::HZ_MATRIX: parseMatrix(x->exp(), _hz_matrix); break; - case HH_MATRIX: + case type::HH_MATRIX: parseMatrix(x->exp(), _hh_matrix); break; - case LHS_ST_MATRIX: + case type::LHS_ST_MATRIX: parseMatrix(x->exp(), _lhs_st_matrix); break; - case RHS_ST_MATRIX: + case type::RHS_ST_MATRIX: parseMatrix(x->exp(), _rhs_st_matrix); break; - case LHS_DSC_MATRIX: + case type::LHS_DSC_MATRIX: parseMatrix(x->exp(), _lhs_dsc_matrix); break; - case SD_MATRIX: + case type::SD_MATRIX: parseMatrix(x->exp(), _sd_matrix); break; - case SZ_MATRIX: + case type::SZ_MATRIX: parseMatrix(x->exp(), _sz_matrix); break; - case RANDOM_SEED: - _random_seed = (unsigned long)av.integer(); + case type::RANDOM_SEED: + case type::CV_ODE_MAX_ORDER: + case type::X_OUTPUT: { + IntegerAnnotations int_annot = _integer_annotations_map[itf->first]; + _integer_annotations_val.insert(pair(int_annot, av.integer())); break; + } default: break; } } +/// @todo Fix annotations structure, see https://github.com/CIFASIS/qss-solver/issues/261 +int ModelAnnotation::getAnnotation(IntegerAnnotations annot) const +{ + if (hasAnnotation(annot)) { + return _integer_annotations_val.at(annot); + } + return 0; +} + +bool ModelAnnotation::hasAnnotation(IntegerAnnotations annot) const +{ + return _integer_annotations_val.find(annot) != _integer_annotations_val.end(); +} + string ModelAnnotation::desc() { return _desc; } list ModelAnnotation::dqmin() { return _DQMin; } @@ -645,7 +672,8 @@ int ModelAnnotation::jacobian() { return _jacobian; } bool ModelAnnotation::isClassic() { - return _solver == DASSL || _solver == DOPRI || _solver == CVODE_BDF || _solver == IDA || _solver == CVODE_AM; + return _solver == Solver::DASSL || _solver == Solver::DOPRI || _solver == Solver::CVODE_BDF || _solver == Solver::IDA || + _solver == Solver::CVODE_AM; } int ModelAnnotation::lps() { return _lps; } @@ -698,14 +726,10 @@ IR::MATRIX::UserDefMatrixExps ModelAnnotation::SDMatrix() { return _sd_matrix; } IR::MATRIX::UserDefMatrixExps ModelAnnotation::SZMatrix() { return _sz_matrix; } -unsigned long ModelAnnotation::randomSeed() { return _random_seed; } - /* AnnotationValue class */ AnnotationValue::AnnotationValue() : _integer(0), _real(0), _str(), _plain_str() {} -AnnotationValue::~AnnotationValue() {} - int AnnotationValue::integer() { return _integer; } void AnnotationValue::setInteger(int i) { _integer = i; } @@ -726,46 +750,46 @@ void AnnotationValue::setPlainStr(string plain_str) { _plain_str = plain_str; } EvalAnnotation::EvalAnnotation() : _tokens() { - _tokens.insert(pair("QSS", "QSS")); - _tokens.insert(pair("CQSS", "CQSS")); - _tokens.insert(pair("QSS2", "QSS2")); - _tokens.insert(pair("QSS3", "QSS3")); - _tokens.insert(pair("LIQSS", "LIQSS")); - _tokens.insert(pair("LIQSS2", "LIQSS2")); - _tokens.insert(pair("LIQSS_BDF", "LIQSS_BDF")); - _tokens.insert(pair("LIQSS3", "LIQSS3")); - _tokens.insert(pair("QSS4", "QSS4")); - _tokens.insert(pair("mLIQSS", "mLIQSS")); - _tokens.insert(pair("mLIQSS2", "mLIQSS2")); - _tokens.insert(pair("DASSL", "DASSL")); - _tokens.insert(pair("DOPRI", "DOPRI")); - _tokens.insert(pair("CVODE_AM", "CVODE_AM")); - _tokens.insert(pair("IDA", "IDA")); - _tokens.insert(pair("CVODE_BDF", "CVODE_BDF")); - _tokens.insert(pair("ST_Linear", "ST_Linear")); - _tokens.insert(pair("ST_Binary", "ST_Binary")); - _tokens.insert(pair("ST_Random", "ST_Random")); - _tokens.insert(pair("CI_Step", "CI_Step")); - _tokens.insert(pair("CI_Dense", "CI_Dense")); - _tokens.insert(pair("CI_Sampled", "CI_Sampled")); - _tokens.insert(pair("SD_File", "SD_File")); - _tokens.insert(pair("SD_Memory", "SD_Memory")); - _tokens.insert(pair("Metis", "Metis")); - _tokens.insert(pair("HMetis", "HMetis")); - _tokens.insert(pair("Scotch", "Scotch")); - _tokens.insert(pair("Patoh", "Patoh")); - _tokens.insert(pair("MTPL", "MTPL")); - _tokens.insert(pair("MTPL_IT", "MTPL_IT")); - _tokens.insert(pair("Manual", "Manual")); - _tokens.insert(pair("SD_DT_Fixed", "SD_DT_Fixed")); - _tokens.insert(pair("Sparse", "Sparse")); - _tokens.insert(pair("Dense", "Dense")); - _tokens.insert(pair("SD_DT_Asynchronous", "SD_DT_Asynchronous")); + _tokens.emplace_back("QSS"); + _tokens.emplace_back("CQSS"); + _tokens.emplace_back("QSS2"); + _tokens.emplace_back("QSS3"); + _tokens.emplace_back("LIQSS"); + _tokens.emplace_back("LIQSS2"); + _tokens.emplace_back("LIQSS_BDF"); + _tokens.emplace_back("LIQSS3"); + _tokens.emplace_back("QSS4"); + _tokens.emplace_back("mLIQSS"); + _tokens.emplace_back("mLIQSS2"); + _tokens.emplace_back("DASSL"); + _tokens.emplace_back("DOPRI"); + _tokens.emplace_back("CVODE_AM"); + _tokens.emplace_back("IDA"); + _tokens.emplace_back("CVODE_BDF"); + _tokens.emplace_back("ST_Linear"); + _tokens.emplace_back("ST_Binary"); + _tokens.emplace_back("ST_Random"); + _tokens.emplace_back("CI_Step"); + _tokens.emplace_back("CI_Dense"); + _tokens.emplace_back("CI_Sampled"); + _tokens.emplace_back("SD_File"); + _tokens.emplace_back("SD_Memory"); + _tokens.emplace_back("Metis"); + _tokens.emplace_back("HMetis"); + _tokens.emplace_back("Scotch"); + _tokens.emplace_back("Patoh"); + _tokens.emplace_back("MTPL"); + _tokens.emplace_back("MTPL_IT"); + _tokens.emplace_back("Manual"); + _tokens.emplace_back("SD_DT_Fixed"); + _tokens.emplace_back("Sparse"); + _tokens.emplace_back("Dense"); + _tokens.emplace_back("SD_DT_Asynchronous"); } AnnotationValue EvalAnnotation::foldTraverseElement(AST_Expression e) { - AnnotationValue av = AnnotationValue(); + auto av = AnnotationValue(); switch (e->expressionType()) { case EXPSTRING: av.setStr(e->getAsString()->print()); @@ -780,7 +804,7 @@ AnnotationValue EvalAnnotation::foldTraverseElement(AST_Expression e) av.setInteger(vi->value()); } } else { - if (_tokens.find(name) != _tokens.end()) { + if (std::find(_tokens.begin(), _tokens.end(), name) != _tokens.end()) { av.setStr(name); } } @@ -791,7 +815,7 @@ AnnotationValue EvalAnnotation::foldTraverseElement(AST_Expression e) break; case EXPREAL: av.setReal(e->getAsReal()->val()); - av.setInteger(e->getAsReal()->val()); + av.setInteger(static_cast(e->getAsReal()->val())); break; case EXPBOOLEAN: if (e->getAsBoolean()->value()) { @@ -826,7 +850,7 @@ void EvalAnnotation::setBoolean(bool condition, AnnotationValue *e) AnnotationValue EvalAnnotation::foldTraverseElement(AnnotationValue e1, AnnotationValue e2, BinOpType bot) { - AnnotationValue av = AnnotationValue(); + auto av = AnnotationValue(); switch (bot) { case BINOPOR: setBoolean(e1.integer() || e2.integer(), &av); diff --git a/src/mmoc/ir/annotation.h b/src/mmoc/ir/annotation.h index 1a7cae24..a4bc5295 100644 --- a/src/mmoc/ir/annotation.h +++ b/src/mmoc/ir/annotation.h @@ -32,7 +32,7 @@ namespace MicroModelica { namespace IR { -typedef enum { +enum class Solver { QSS, CQSS, LIQSS, @@ -49,11 +49,11 @@ typedef enum { IDA, mLIQSS, mLIQSS2 -} Solver; +}; -typedef enum { Metis, HMetis, Scotch, Patoh, MTPL, MTPL_IT, Manual } PartitionMethod; +enum class PartitionMethod { Metis, HMetis, Scotch, Patoh, MTPL, MTPL_IT, Manual }; -typedef enum { DT_Fixed, DT_Asynchronous } DT_Synch; +enum class DT_Synch { DT_Fixed, DT_Asynchronous }; class FunctionAnnotation { public: @@ -71,14 +71,11 @@ class FunctionAnnotation { Util::SymbolTable libraries() const; string libraryDirectory(); - private: - typedef enum { - INCLUDE, //!< INCLUDE - INCLUDE_DIRECTORY, //!< INCLUDE_DIRECTORY - LIBRARY, //!< LIBRARY - LIBRARY_DIRECTORY, //!< LIBRARY_DIRECTORY - DERIVATIVE //!< DERIVATIVE - } type; + protected: + enum class type { INCLUDE, INCLUDE_DIRECTORY, LIBRARY, LIBRARY_DIRECTORY, DERIVATIVE }; + + void initialize(); + map _annotations; std::string _derivative; std::string _include; @@ -87,6 +84,8 @@ class FunctionAnnotation { std::string _libraryDirectory; }; +enum class IntegerAnnotations { RandomSeed, CVODEMaxOrder, XOutput }; + class ModelAnnotation { public: ModelAnnotation(); @@ -138,10 +137,11 @@ class ModelAnnotation { IR::MATRIX::UserDefMatrixExps RHSSTMatrix(); IR::MATRIX::UserDefMatrixExps SDMatrix(); IR::MATRIX::UserDefMatrixExps SZMatrix(); - unsigned long randomSeed(); + int getAnnotation(IntegerAnnotations annot) const; + bool hasAnnotation(IntegerAnnotations annot) const; protected: - typedef enum { + enum class type { EXPERIMENT, DESC, DQMIN, @@ -181,9 +181,14 @@ class ModelAnnotation { LHS_DSC_MATRIX, SD_MATRIX, SZ_MATRIX, - RANDOM_SEED - } type; + RANDOM_SEED, + CV_ODE_MAX_ORDER, + X_OUTPUT + }; + + using IntAnnotValMap = std::map; + void initialize(); void processAnnotation(string annot, AST_Modification_Equal x); void processArgument(AST_Argument_Modification arg); void processList(AST_Expression x, list *l); @@ -239,15 +244,16 @@ class ModelAnnotation { IR::MATRIX::UserDefMatrixExps _sz_matrix; string _event_ids; int _current_exp_id; - unsigned long _random_seed; + map _integer_annotations_map; + IntAnnotValMap _integer_annotations_val; }; -typedef boost::variant AnnotationType; +using AnnotationType = boost::variant; class AnnotationValue { public: AnnotationValue(); - ~AnnotationValue(); + ~AnnotationValue() = default; int integer(); void setInteger(int i); double real(); @@ -257,7 +263,7 @@ class AnnotationValue { string plainStr(); void setPlainStr(string plain_str); - private: + protected: int _integer; double _real; string _str; @@ -267,14 +273,14 @@ class AnnotationValue { class EvalAnnotation : public AST_Expression_Fold { public: EvalAnnotation(); - ~EvalAnnotation() = default; + ~EvalAnnotation() override = default; private: void setBoolean(bool condition, AnnotationValue *e); - AnnotationValue foldTraverseElement(AST_Expression); - AnnotationValue foldTraverseElement(AnnotationValue, AnnotationValue, BinOpType); - AnnotationValue foldTraverseElementUMinus(AST_Expression); - map _tokens; + AnnotationValue foldTraverseElement(AST_Expression) override; + AnnotationValue foldTraverseElement(AnnotationValue, AnnotationValue, BinOpType) override; + AnnotationValue foldTraverseElementUMinus(AST_Expression) override; + std::vector _tokens; }; } // namespace IR } // namespace MicroModelica diff --git a/src/mmoc/ir/mmo_ir.cpp b/src/mmoc/ir/mmo_ir.cpp index 0afdd582..32564b2b 100644 --- a/src/mmoc/ir/mmo_ir.cpp +++ b/src/mmoc/ir/mmo_ir.cpp @@ -125,16 +125,17 @@ void MicroModelicaIR::visit(AST_Element x) Variable vi(newType_Integer(), tp, current_element(it)->modification(), nullptr, size, array); _class->insert(current_element(it)->name(), vi, t); } else { + Variable new_var; if ((tp & TP_PARAMETER) && c->isInteger()) { - Variable vi(newType_Integer(), tp, current_element(it)->modification(), nullptr, size, array); - _class->insert(current_element(it)->name(), vi, t); + new_var = Variable(newType_Integer(), tp, current_element(it)->modification(), nullptr, size, array); } else if (c->isString()) { - Variable vi(newType_String(), tp, current_element(it)->modification(), nullptr, size, array); - _class->insert(current_element(it)->name(), vi, t); + new_var = Variable(newType_String(), tp, current_element(it)->modification(), nullptr, size, array); + } else if ((tp & TP_DISCRETE) && c->isInteger()) { + new_var = Variable(newType_Integer(), tp, current_element(it)->modification(), nullptr, size, array); } else { - Variable vi(newType_Real(), tp, current_element(it)->modification(), nullptr, size, array); - _class->insert(current_element(it)->name(), vi, t); + new_var = Variable(newType_Real(), tp, current_element(it)->modification(), nullptr, size, array); } + _class->insert(current_element(it)->name(), new_var, t); } } } else if (e == ELCLASS) { diff --git a/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.c b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.c new file mode 100644 index 00000000..9bd85a4e --- /dev/null +++ b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include + +#include "allow_discrete_integer.h" +#include +#include +#include +#include +#include + +void MOD_settings(SD_simulationSettings settings) +{ + settings->debug = 0; + settings->parallel = FALSE; + settings->hybrid = TRUE; + settings->method = 0; +} + +void MOD_definition(int idx, double *x, double *d, double *a, double t, double *dx) +{ + int _d1; + int i; + if (_is_var_u(idx)) { + _get_u_idxs(idx); + _apply_usage_eq_1(_d1); + if ((i >= 1 && i <= 1000)) { + _der_u(i,0) = _time; + + + } + return; + } +} + +void MOD_zeroCrossing(int idx, double *x, double *d, double *a, double t, double *zc) +{ + switch(idx) { + case _eval_event_1: { + _zc(0) = _time-(0); + + + return; + } + } +} + +void MOD_handlerPos(int idx, double *x, double* q, double *d, double *a, double t) +{ + switch(idx) { + case _eval_event_1: { + _init_u((int)_d,0) = 0; + return; + } + } +} + +void MOD_handlerNeg(int idx, double *x, double* q, double *d, double *a, double t) +{ +} + +void MOD_output(int idx, double *x, double *d, double *a, double t, double *out) +{ +} + +void MOD_jacobian(double *x, double *d, double *a, double t, SD_jacMatrices dvdx, double *jac) +{ + int row, row_t, eq_var, c_row, c_row_g; + int col, col_g, col_t; + int x_ind; + double aux; + int _d1; + int _rg_d1; + int i; + SD_cleanJacMatrices(dvdx); + for(row = 1; row <= 1000; row++) { + c_row = _c_index(row); + _get_eq_1_var_idxs(row, eq_var); + _get_u_idxs(eq_var); + } + // Assign Jacobian Matrix values for equation: 0 + for (row = 0; row < 1000; row++) { + for (col = 0; col < dvdx->df_dx[0]->size[row]; col++) { + row_t = dvdx->df_dx[0]->index[row][col]; + _assign_jac(row_t, dvdx->df_dx[0]->value[row][col]); + } + } +} + +void MOD_dependencies(int idx, double *x, double *d, double *a, double t, double *dx, int *map) +{ +} + +void MOD_BDF_definition(double *x, double *d, double *a, double t, double *dx, int *BDFMap, int nBDF) +{ + int idx; + int __bdf_it; + for(__bdf_it = 0; __bdf_it < nBDF; __bdf_it++) { + idx = BDFMap[__bdf_it]; + int _d1; + int i; + if (_is_var_u(idx)) { + _get_u_idxs(idx); + _apply_usage_eq_1(_d1); + if ((i >= 1 && i <= 1000)) { + _eval_dep_u(i,1) = _time; + + + } + continue; + } + } +} + +void QSS_initializeDataStructs(QSS_simulator simulator) +{ + simulator->data = QSS_Data(1000,1,1,1000,0,1,0,"allow_discrete_integer"); + QSS_data modelData = simulator->data; + MODEL_DATA_ACCESS(modelData) + int* states = (int*) malloc(1000*sizeof(int)); + int* discretes = (int*) malloc(1*sizeof(int)); + int* events = (int*) malloc(1*sizeof(int)); + int row, eq_var, c_row; + int x_ind; + int _d1; + int _rg_d1; + int i; + for(row = 1; row <= 1000; row++) { + c_row = _c_index(row); + _get_eq_1_var_idxs(row, eq_var); + _get_u_idxs(eq_var); + } + modelData->event[_idx_event_1].nLHSSt++; + QSS_allocDataMatrix(modelData); + cleanVector(states, 0, 1000); + for(row = 1; row <= 1000; row++) { + c_row = _c_index(row); + _get_eq_1_var_idxs(row, eq_var); + _get_u_idxs(eq_var); + } + cleanVector(events, 0, 1); + modelData->event[_idx_event_1].LHSSt[events[_idx_event_1]++] = _idx_u(0,0); + modelData->event[_idx_event_1].direction = 1; + modelData->event[_idx_event_1].relation = 2; + SD_setupJacMatrices(modelData->jac_matrices); + simulator->time = QSS_Time(1000,1,1000,0,ST_Binary, NULL); + for(i = 1; i<=1000; i+=1) { + modelData->IT[_input_1(i)] = _idx_u(i,0); + } + simulator->output = SD_Output("allow_discrete_integer",0,1,1000,NULL,0,0,CI_Step,SD_Memory,NULL); + SD_output modelOutput = simulator->output; + simulator->model = QSS_Model(MOD_definition, MOD_dependencies, MOD_zeroCrossing, MOD_handlerPos, MOD_handlerNeg, MOD_jacobian, MOD_BDF_definition); + free(states); + free(discretes); + free(events); +} + +void CLC_initializeDataStructs(CLC_simulator simulator) +{ +} + diff --git a/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.h b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.h new file mode 100644 index 00000000..7dbedb9b --- /dev/null +++ b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.h @@ -0,0 +1,66 @@ +// Model data access macro. + +#define MODEL_DATA_ACCESS(m) \ + double* x = m->x; \ + double* d = m->d; + +// Coeff multipliers definition. + +#define COEFF_MULTIPLIER(c) COEFF_MULTIPLIER_##c +#define COEFF_MULTIPLIER_0 1 +#define COEFF_MULTIPLIER_1 1 + +// Model Variables Macros + +// Macros definition for variable: _event_1 +#define _idx_event_1 0 +#define _eval_event_1 0 + +// Macros definition for variable: d +#define _idx_d 0 +#define _d d[_idx_d] + +// Macros definition for variable: u +#define _idx_u(d1,coeff) ((d1-1)) +#define _state_idx_u(d1,coeff) ((d1-1))*2 + coeff +#define _u(d1,coeff) x[_state_idx_u(d1,coeff)] * COEFF_MULTIPLIER(coeff) +#define _init_u(d1,coeff) x[_state_idx_u(d1,coeff)] +#define _q_u(d1,coeff) q[_state_idx_u(d1,coeff)] * COEFF_MULTIPLIER(coeff) +#define _eval_u(d1,coeff) ((d1-1)) +#define _is_var_u(idx) idx >= 0 && idx < 1000 +#define _get_u_idxs(idx)\ + _d1 = (idx)+ 1; +#define _eval_dep_u(d1,coeff) dx[_state_idx_u(d1,coeff)] + + +// Derivative Equations Macros + +// Macros for equation: 1 +#define _apply_usage_eq_1(_d1) \ + i = _d1; +#define _get_eq_1_var_idxs(row, var)\ + _rg_d1 = 0 + (row-1)+ 1;\ + var = _idx_u(_rg_d1,0); + +// Event Macros + +// Macros for event: 1 + +#define _zc(coeff) zc[coeff] + +// Input Matrix Macros + +#define _input_1(i) ((i-1)) + +// Jacobian Macros definition. +#define _assign_jac(r, val) \ + col_t = dvdx->df_dx_t->size[r] + dvdx->df_dx_t->index[r][0]; \ + dvdx->df_dx_t->index[r][0]++; \ + jac[col_t] = val; +#define _c_index(i) (i-1) + +#define _time t + +// Derivative Macros definition. +// Derivative definition for variable: u +#define _der_u(d1,coeff) dx[coeff+1] diff --git a/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.ini b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.ini new file mode 100644 index 00000000..191278e7 --- /dev/null +++ b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.ini @@ -0,0 +1,15 @@ +minstep=1.00000e-14; +zchyst=1.00000e-12; +derdelta=1.00000e-08; +symdiff=1; +lps=0; +nodesize=10000; +jacobian=1; +it=0.00000e+00; +ft=1.00000e+01; +sol="QSS"; +dqmin=(1.00000e-03); +dqrel=(1.00000e-03); +bdf=0; +BDFPartitionDepth=1; +BDFMaxStep=0.00000e+00; diff --git a/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.mo b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.mo new file mode 100644 index 00000000..62609124 --- /dev/null +++ b/src/mmoc/tests/system/gt_data/allow_discrete_integer/allow_discrete_integer.mo @@ -0,0 +1,30 @@ +model allow_discrete_integer + constant Integer N=1000; + Real u[N]; + discrete Integer d; + +equation + for i in 1:N loop + der(u[i])=time; + end for; + +algorithm + when time > 0 then + reinit(u[d],0); + end when; + annotation( + experiment( + MMO_Description="Use time variable in initialization code.", + + MMO_Solver=QSS, + MMO_PartitionMethod=Metis, + Jacobian=Dense, + MMO_BDF_PDepth=1, + MMO_BDF_Max_Step=0, + MMO_RandomSeed=0, + StartTime=0, + StopTime=10, + Tolerance={1e-3}, + AbsTolerance={1e-3} + )); +end allow_discrete_integer; diff --git a/src/mmoc/tests/system/models_test.cpp b/src/mmoc/tests/system/models_test.cpp index 84b2f572..d358ba8e 100644 --- a/src/mmoc/tests/system/models_test.cpp +++ b/src/mmoc/tests/system/models_test.cpp @@ -57,13 +57,12 @@ TEST_P(IModelTests, GenerateCode) } const char* models[] = {"adr", "adr2D", "advection", "advection2D", "advection2D_LI", "advection_quoted", - "advectionFlux", "airconds", "aircont", "bball_downstairs", "boost", "BouncingBall", + "advectionFlux", "airconds", "aircont", "allow_discrete_integer", "bball_downstairs", "boost", "BouncingBall", "buck", "buckboost", "buck_circuit", "buck_term", "burgers", "cuk", "cuk2", "interleaved", "inverters", "lc_line", "lotka_volterra", "mliqss_adr", "mliqss_buck", "mliqss_test", "mliqss_TYSON", "NeuralNetwork1", "par_airconds", "par_airconds_cont", "rectifier", "rltest", "rltest_LI", "spikings", "testFor", "test_input", "TYSON", "VIRplanoS", "virus_replication"}; - INSTANTIATE_TEST_SUITE_P(Models, IModelTests, testing::ValuesIn(models)); /// @} diff --git a/src/mmoc/util/ast_util.cpp b/src/mmoc/util/ast_util.cpp index edafd44a..ca1b4c32 100644 --- a/src/mmoc/util/ast_util.cpp +++ b/src/mmoc/util/ast_util.cpp @@ -130,7 +130,7 @@ bool EqualExp::equalTraverseElement(AST_Expression a, AST_Expression b) case EXPCOMPREF: { AST_Expression_ComponentReference compRefA = a->getAsComponentReference(); Option varInfoA = ModelConfig::instance().lookup(CREF_NAME(compRefA)); - if (varInfoA && varInfoA->type()->getType() == TYARRAY) { + if (varInfoA && varInfoA->type()->getType() == SymbolType::TYARRAY) { return compareArrays(compRefA, b->getAsComponentReference()); } else { return CREF_NAME(a).compare(CREF_NAME(b)) == 0; diff --git a/src/mmoc/util/model_config.h b/src/mmoc/util/model_config.h index e9ceb94e..c1054ea6 100644 --- a/src/mmoc/util/model_config.h +++ b/src/mmoc/util/model_config.h @@ -85,6 +85,7 @@ class ModelConfig { inline void clearLocalSymbols() { _local_symbols.clear(); }; inline void setLocalInitSymbols() { _init_symbols = true; }; inline void unsetLocalInitSymbols() { _init_symbols = false; }; + inline void setEvents(IR::EventTable events) { _events = events; } inline IR::EventTable events() const { return _events; } inline bool functionOutputs() const { return _function_outputs; } diff --git a/src/mmoc/util/symbol_table.cpp b/src/mmoc/util/symbol_table.cpp index 775e727d..6ee60f23 100644 --- a/src/mmoc/util/symbol_table.cpp +++ b/src/mmoc/util/symbol_table.cpp @@ -37,7 +37,6 @@ namespace Util { Variable::Variable() : _unknown(false), - _discrete(false), _t(nullptr), _tp(TP_CONSTANT), _m(nullptr), @@ -59,7 +58,6 @@ Variable::Variable() Variable::Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c) : _unknown(false), - _discrete(false), _t(t), _tp(tp), _m(m), @@ -80,9 +78,8 @@ Variable::Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c) processModification(); } -Variable::Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c, vector s, bool array) +Variable::Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c, const vector &s, bool array) : _unknown(false), - _discrete(false), _t(t), _tp(tp), _m(m), @@ -105,7 +102,6 @@ Variable::Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c, Variable &Variable::operator=(const Variable &other) { - _discrete = other._discrete; _t = other._t; _tp = other._tp; _m = other._m; @@ -178,9 +174,8 @@ void Variable::setName(string name) { _name = name; } unsigned int Variable::size() { - vector::const_iterator it; unsigned int total = 1; - for (it = _size.begin(); it != _size.end(); it++) { + for (vector::const_iterator it = _size.begin(); it != _size.end(); it++) { total *= *it; } return total; @@ -208,6 +203,17 @@ string Variable::print() const return buffer.str(); } +bool Variable::isDiscreteInteger() const { return (_t->getType() == SymbolType::TYINTEGER) && isDiscrete(); } + +std::string Variable::castOperator() const +{ + string cast_operator; + if (isDiscreteInteger()) { + cast_operator = "(int)"; + } + return cast_operator; +} + ostream &operator<<(ostream &out, const Variable &v) { out << v.print(); @@ -234,7 +240,7 @@ string Variable::initialization() { stringstream buffer; if (hasAssignment() || hasStartModifier() || hasEachModifier()) { - Range range = Range(*this); + auto range = Range(*this); Expression ex(exp()); Expression var = Utils::instance().variableExpression(name(), range); if (hasEachModifier()) { @@ -299,7 +305,7 @@ void VarSymbolTable::insert(VarName name, Variable variable) } } -Option VarSymbolTable::lookup(string name) +Option VarSymbolTable::lookup(const string &name) const { std::map table = map(); Option var = table[name]; @@ -309,7 +315,7 @@ Option VarSymbolTable::lookup(string name) return Option(); } -unsigned int VarSymbolTable::maxDim() const { return _max_dims; } +unsigned long VarSymbolTable::maxDim() const { return _max_dims; } } // namespace Util } // namespace MicroModelica diff --git a/src/mmoc/util/symbol_table.h b/src/mmoc/util/symbol_table.h index 2181d945..b6feb5c0 100644 --- a/src/mmoc/util/symbol_table.h +++ b/src/mmoc/util/symbol_table.h @@ -42,7 +42,7 @@ class Variable { public: Variable(); Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c); - Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c, vector s, bool array); + Variable(Type t, AST_TypePrefix tp, AST_Modification m, AST_Comment c, const vector& s, bool array); Variable& operator=(const Variable& other); bool operator==(const Variable& other); bool operator!=(const Variable& other); @@ -50,7 +50,7 @@ class Variable { typedef enum { State, Algebraic, NotAssigned } RealType; inline void setRealType(RealType type) { _realType = type; }; - inline AST_TypePrefix typePrefix() { return _tp; }; + inline AST_TypePrefix typePrefix() const { return _tp; }; inline AST_Comment comment() { return _comm; }; inline void setComment(AST_Comment c) { _comm = c; }; inline AST_Modification modification() { return _m; }; @@ -67,13 +67,8 @@ class Variable { unsetStartEach(); }; inline bool isParameter() const { return _tp & TP_PARAMETER; }; - inline bool isDiscrete() const { return (_tp & TP_DISCRETE) || _discrete; }; + inline bool isDiscrete() const { return (_tp & TP_DISCRETE); }; inline bool builtIn() const { return _builtin; }; - inline void setDiscrete() - { - _discrete = true; - unsetAssignment(); - }; inline void setBuiltIn() { _builtin = true; }; inline bool isConstant() const { return _tp & TP_CONSTANT; }; inline bool isInput() const { return _tp & TP_INPUT; }; @@ -82,31 +77,31 @@ class Variable { inline bool isEqType() const { return _tp & TP_EQ; }; inline bool isLocal() const { return _tp & TP_LOCAL; }; inline bool isState() const { return _realType == State; }; - inline bool isString() const { return _t->getType() == TYSTRING; }; + inline bool isString() const { return _t->getType() == SymbolType::TYSTRING; }; inline void setState() { unsetAssignment(); }; - inline bool isUnknown() { return _unknown; }; + inline bool isUnknown() const { return _unknown; }; inline void setUnknown() { _unknown = true; }; - inline bool isTime() { return _name.compare("time") == 0; }; + inline bool isTime() const { return _name.compare("time") == 0; }; inline bool isAlgebraic() const { return _realType == Algebraic; }; inline void setValue(int val) { _value = val; }; - inline int value() { return _value; }; + inline int value() const { return _value; }; unsigned int size(); - inline bool hasAssignment() { return _hasAssigment; }; - inline bool hasStartModifier() { return _hasStart; }; - inline bool hasEachModifier() { return _hasEach; }; + inline bool hasAssignment() const { return _hasAssigment; }; + inline bool hasStartModifier() const { return _hasStart; }; + inline bool hasEachModifier() const { return _hasEach; }; inline void setEachModifier(bool each) { _hasEach = each; }; inline string name() const { return _name; }; void setName(string name); inline AST_Expression exp() { return _exp; }; inline bool isArray() const { return _isArray; }; - inline bool isScalar() { return !isArray(); }; + inline bool isScalar() const { return !isArray(); }; friend ostream& operator<<(ostream& os, const Variable& e); inline unsigned int size(int dim) const { return _size[dim]; }; unsigned int rowSize(unsigned int dim) const; - inline unsigned int dimensions() const { return _size.size(); }; + inline unsigned long dimensions() const { return _size.size(); }; std::string declaration(std::string prefix = ""); std::string initialization(); - inline bool hasOffset() { return _hasOffset; }; + inline bool hasOffset() const { return _hasOffset; }; inline void setOffset(int offset) { _offset = offset; @@ -115,9 +110,10 @@ class Variable { inline int offset() const { return _offset; }; inline bool isModelVar() const { return isState() || isDiscrete() || isAlgebraic() || isParameter() || isEqType() || isOutput(); }; std::string print() const; + std::string castOperator() const; friend std::ostream& operator<<(std::ostream& out, const Variable& v); - private: + protected: void processModification(); void unsetAssignment() { _hasAssigment = false; }; inline void unsetStartEach() @@ -125,9 +121,9 @@ class Variable { _hasEach = false; _hasStart = false; }; + bool isDiscreteInteger() const; bool _unknown; - bool _discrete; Type _t; AST_TypePrefix _tp; AST_Modification _m; @@ -157,16 +153,16 @@ class VarSymbolTable : public ModelTable { ~VarSymbolTable() = default; void initialize(TypeSymbolTable tst); void insert(VarName name, Variable variable); - inline bool parameters() { return _parameters; }; - Option lookup(std::string name); - unsigned int maxDim() const; + inline bool parameters() const { return _parameters; }; + Option lookup(const std::string& name) const; + unsigned long maxDim() const; private: bool _parameters; - unsigned int _max_dims; + unsigned long _max_dims; }; -typedef std::list VariableList; +using VariableList = std::list; } // namespace Util } // namespace MicroModelica diff --git a/src/mmoc/util/type.cpp b/src/mmoc/util/type.cpp index 065af537..377215fa 100644 --- a/src/mmoc/util/type.cpp +++ b/src/mmoc/util/type.cpp @@ -21,7 +21,7 @@ #include "type.h" -#include "../ast/ast_builder.h" +#include ostream &operator<<(ostream &os, const Type_ &e) { @@ -35,10 +35,6 @@ ostream &operator<<(ostream &os, const Type &e) return os; } -Type_Real_::Type_Real_() {} - -Type_Real_::~Type_Real_() {} - string Type_Real_::print() const { stringstream ret(stringstream::out); @@ -50,10 +46,6 @@ Type_Real newType_Real() { return new Type_Real_(); } void deleteType_Real(Type_Real m) { delete m; } -Type_Integer_::Type_Integer_() {} - -Type_Integer_::~Type_Integer_() {} - string Type_Integer_::print() const { stringstream ret(stringstream::out); @@ -72,8 +64,6 @@ string Type_Boolean_::print() const return ret.str(); } -Type_String_::~Type_String_() {} - string Type_String_::print() const { stringstream ret(stringstream::out); @@ -91,7 +81,7 @@ string Type_Array_::print() const AST_ExpressionList exls = newAST_ExpressionList(); Type tt = _t; AST_ListPrepend(exls, _dim); - while (tt->getType() == TYARRAY) { + while (tt->getType() == SymbolType::TYARRAY) { AST_ListPrepend(exls, tt->getAsArray()->dimension()); tt = tt->getAsArray()->arrayOf(); } @@ -107,8 +97,6 @@ string Type_Array_::print() const Type_Array_::Type_Array_(Type t, AST_Expression dim) : _t(t), _dim(dim){}; -Type_Array_::~Type_Array_() {} - Type Type_Array_::arrayOf() { return _t; } Type_Array Type_::getAsArray() { return dynamic_cast(this); } @@ -121,9 +109,9 @@ int operator==(Type_ &e1, Type_ &e2) { if (e1.getType() == e2.getType()) { switch (e1.getType()) { - case TYARRAY: + case SymbolType::TYARRAY: return *(e1.getAsArray()->arrayOf()) == e2.getAsArray()->arrayOf(); - case TYTUPLA: { + case SymbolType::TYTUPLA: { Type_Tupla t1 = e1.getAsTupla(), t2 = e2.getAsTupla(); if (t2->tupla()->size() != t1->tupla()->size()) return 0; TypeListIterator it1 = t1->tupla()->begin(), it2 = t1->tupla()->begin(); @@ -133,8 +121,7 @@ int operator==(Type_ &e1, Type_ &e2) } return 1; } - case TYFUNCTION: // No es necesario!! - { + case SymbolType::TYFUNCTION: { Type_Function f1 = e1.getAsFunction(), f2 = e2.getAsFunction(); return *(f1->output()) == f2->output(); } @@ -153,13 +140,12 @@ int operator!=(Type_ &e1, Type e2) { return !(e1 == *e2); } Type_Tupla_::Type_Tupla_(TypeList tyl) : _tyl(tyl){}; -Type_Tupla_::~Type_Tupla_() {} - string Type_Tupla_::print() const { stringstream ret(stringstream::out); TypeListIterator tyit; - int i = 0, s = _tyl->size(); + unsigned long i = 0; + unsigned long s = _tyl->size(); ret << "< "; foreach (tyit, _tyl) { i++; @@ -172,13 +158,12 @@ string Type_Tupla_::print() const Type_Function_::Type_Function_(Type o, TypeList i) : _input(i), _output(o){}; -Type_Function_::~Type_Function_() {} - string Type_Function_::print() const { stringstream ret(stringstream::out); TypeListIterator tyit; - int i = 0, s = _input->size(); + unsigned long i = 0; + unsigned long s = _input->size(); ret << _output << " function "; diff --git a/src/mmoc/util/type.h b/src/mmoc/util/type.h index 00d8df53..3a0a7dff 100644 --- a/src/mmoc/util/type.h +++ b/src/mmoc/util/type.h @@ -17,303 +17,91 @@ ******************************************************************************/ -#ifndef TYPE_H_ -#define TYPE_H_ +#pragma once #include #include #include -#include "../ast/ast_types.h" -#include "../ast/expression.h" -#include "macros.h" +#include +#include +#include -using namespace std; +enum class SymbolType { TYREAL, TYINTEGER, TYBOOLEAN, TYSTRING, TYARRAY, TYTUPLA, TYFUNCTION }; -/** - * - */ -enum TypesType { - TYREAL, //!< TYREAL - TYINTEGER, //!< TYINTEGER - TYBOOLEAN, //!< TYBOOLEAN - TYSTRING, //!< TYSTRING - TYARRAY, //!< TYARRAY - TYTUPLA, //!< TYTUPLA - TYFUNCTION //!< TYFUNCTION -}; - -/** - * - */ DEFINE_TYPE(Type); -/** - * - */ DEFINE_TYPE(Type_Real); -/** - * - */ DEFINE_TYPE(Type_Integer); -/** - * - */ DEFINE_TYPE(Type_Boolean); -/** - * - */ DEFINE_TYPE(Type_String); -/** - * - */ DEFINE_TYPE(Type_Array); -/** - * - */ DEFINE_TYPE(Type_Tupla); -/** - * - */ DEFINE_TYPE(Type_Function); -/** - * - */ DEFINE_LIST(Type); -/** - * - */ class Type_ { public: - /** - * - */ - virtual ~Type_(){}; - /** - * - * @return - */ - virtual TypesType getType() = 0; - /** - * - * @return - */ + virtual ~Type_() = default; + virtual SymbolType getType() = 0; virtual string print() const = 0; - /** - * - * @param os - * @param e - * @return - */ friend ostream &operator<<(ostream &os, const Type_ &e); - /** - * - * @param os - * @param e - * @return - */ friend ostream &operator<<(ostream &os, const Type &e); - /** - * - * @param e1 - * @param e2 - * @return - */ friend int operator==(Type_ &e1, Type_ &e2); - /** - * - * @param e1 - * @param e2 - * @return - */ friend int operator==(Type_ &e1, Type e2); - /** - * - * @param e1 - * @param e2 - * @return - */ friend int operator!=(Type_ &e1, Type_ &e2); - /** - * - * @param e1 - * @param e2 - * @return - */ friend int operator!=(Type_ &e1, Type e2); - /** - * - * @return - */ Type_Array getAsArray(); - /** - * - * @return - */ Type_Tupla getAsTupla(); - /** - * - * @return - */ Type_Function getAsFunction(); }; -/** - * - */ class Type_Real_ : public Type_ { public: - /** - * - */ - Type_Real_(); - /** - * - */ - virtual ~Type_Real_(); - /** - * - * @return - */ - TypesType getType() { return TYREAL; }; - /** - * - * @return - */ - string print() const; + Type_Real_() = default; + ~Type_Real_() override = default; + SymbolType getType() override { return SymbolType::TYREAL; }; + string print() const override; }; -/** - * - * @return - */ + Type_Real newType_Real(); -/** - * - * @param m - */ void deleteType_Real(Type_Real m); -/** - * - */ class Type_Integer_ : public Type_ { public: - /** - * - */ - Type_Integer_(); - /** - * - */ - virtual ~Type_Integer_(); - /** - * - * @return - */ - TypesType getType() { return TYINTEGER; }; - /** - * - * @return - */ - string print() const; + Type_Integer_() = default; + ~Type_Integer_() override = default; + SymbolType getType() override { return SymbolType::TYINTEGER; }; + string print() const override; }; -/** - * - * @return - */ + Type_Integer newType_Integer(); -/** - * - * @param m - */ void deleteType_Integer(Type_Integer m); -/** - * - */ class Type_Boolean_ : public Type_ { public: - /** - * - */ - virtual ~Type_Boolean_(){}; - /** - * - * @return - */ - TypesType getType() { return TYBOOLEAN; }; - /** - * - * @return - */ - string print() const; + ~Type_Boolean_() override = default; + ; + SymbolType getType() override { return SymbolType::TYBOOLEAN; }; + string print() const override; }; -/** - * - */ class Type_String_ : public Type_ { public: - /** - * - */ - virtual ~Type_String_(); - /** - * - * @return - */ - TypesType getType() { return TYSTRING; }; - /** - * - * @return - */ - string print() const; + ~Type_String_() override = default; + SymbolType getType() override { return SymbolType::TYSTRING; }; + string print() const override; }; -/** - * - * @return - */ + Type_String newType_String(); -/** - * - * @param m - */ void deleteType_String(Type_String m); -/** - * - */ class Type_Array_ : public Type_ { public: - /** - * - * @param t - * @param dim - */ Type_Array_(Type t, AST_Expression dim); - /** - * - */ - virtual ~Type_Array_(); - /** - * - * @return - */ - TypesType getType() { return TYARRAY; } - /** - * - * @return - */ - string print() const; - /** - * - * @return - */ + ~Type_Array_() override = default; + SymbolType getType() override { return SymbolType::TYARRAY; } + string print() const override; Type arrayOf(); - /** - * - * @return - */ AST_Expression dimension() { return _dim; }; private: @@ -321,79 +109,28 @@ class Type_Array_ : public Type_ { AST_Expression _dim; }; -/** - * - */ class Type_Tupla_ : public Type_ { public: - /** - * - * @param tyl - */ - Type_Tupla_(TypeList tyl); - /** - * - */ - virtual ~Type_Tupla_(); - /** - * - * @return - */ - string print() const; - /** - * - * @return - */ + explicit Type_Tupla_(TypeList tyl); + ~Type_Tupla_() override = default; + string print() const override; TypeList tupla() { return _tyl; }; - /** - * - * @return - */ - TypesType getType() { return TYTUPLA; } + SymbolType getType() override { return SymbolType::TYTUPLA; } private: TypeList _tyl; }; -/** - * - */ class Type_Function_ : public Type_ { public: - /** - * - * @param output - * @param input - */ Type_Function_(Type output, TypeList input); - /** - * - */ - virtual ~Type_Function_(); - /** - * - * @return - */ - string print() const; - /** - * - * @return - */ + ~Type_Function_() override = default; + string print() const override; TypeList input() { return _input; }; - /** - * - * @return - */ Type output() { return _output; }; - /** - * - * @return - */ - TypesType getType() { return TYFUNCTION; }; + SymbolType getType() override { return SymbolType::TYFUNCTION; }; private: TypeList _input; Type _output; }; - -#endif /* TYPE_H_ */ diff --git a/src/mmoc/util/visitors/expression_printer.cpp b/src/mmoc/util/visitors/expression_printer.cpp index 2e83a19e..7a2f2726 100644 --- a/src/mmoc/util/visitors/expression_printer.cpp +++ b/src/mmoc/util/visitors/expression_printer.cpp @@ -34,7 +34,7 @@ namespace MicroModelica { using namespace IR; namespace Util { -ExpressionPrinter::ExpressionPrinter(int order) : _order(order) {} +ExpressionPrinter::ExpressionPrinter(int order, bool array_index) : _order(order), _array_index(array_index) {} string ExpressionPrinter::foldTraverseElement(AST_Expression exp) { @@ -50,7 +50,7 @@ string ExpressionPrinter::foldTraverseElement(AST_Expression exp) case EXPBRACE: break; case EXPCALL: { - AST_Expression_Call call = exp->getAsCall(); + const AST_Expression_Call call = exp->getAsCall(); CompiledFunctionTable fs = Utils::instance().compiledFunctions(); Option f = fs[*call->name()]; if (!f) { @@ -87,7 +87,7 @@ string ExpressionPrinter::foldTraverseElement(AST_Expression exp) Error::instance().add(exp->lineNum(), EM_IR | EM_VARIABLE_NOT_FOUND, ER_Error, "expression_printer.cpp:80 %s", ref->name().c_str()); break; } - VariablePrinter var_printer(var.get(), ref, _order); + VariablePrinter var_printer(var.get(), ref, _order, _array_index); buffer << var_printer; break; } @@ -110,7 +110,8 @@ string ExpressionPrinter::foldTraverseElement(AST_Expression exp) case EXPOUTPUT: { AST_Expression_Output out = exp->getAsOutput(); AST_ExpressionListIterator it; - int size = out->expressionList()->size(), i = 0; + unsigned long size = out->expressionList()->size(); + unsigned long i = 0; buffer << "("; foreach (it, out->expressionList()) { buffer << apply(current_element(it)); @@ -188,14 +189,22 @@ string ExpressionPrinter::foldTraverseElementUMinus(AST_Expression exp) return buffer.str(); } -VariablePrinter::VariablePrinter(Variable var, AST_Expression_ComponentReference ref, int order) - : _var(var), _ref(ref), _order(order), _exp(), _begin_delimiter("("), _end_delimiter(")"), _begin_index_access(), _end_index_access() +VariablePrinter::VariablePrinter(const Variable& var, AST_Expression_ComponentReference ref, int order, bool array_index) + : _var(var), + _ref(ref), + _order(order), + _exp(), + _begin_delimiter("("), + _end_delimiter(")"), + _begin_index_access(), + _end_index_access(), + _cast() { - config(); + config(array_index); generate(); } -void VariablePrinter::config() +void VariablePrinter::config(bool array_index) { if (ModelConfig::instance().functionCode()) { _begin_delimiter = "["; @@ -203,6 +212,9 @@ void VariablePrinter::config() _begin_index_access = "("; _end_index_access = "-1)"; } + if (array_index) { + _cast = _var.castOperator(); + } } string VariablePrinter::access(bool array_access) const @@ -238,12 +250,14 @@ void VariablePrinter::generate() } else if (config.isQss() && config.algorithm() && !config.reinit() && _var.isState()) { buffer << "_q"; } - buffer << _var; + buffer << _cast << _var; if (HAS_INDEXES) { - ExpressionPrinter printer(_order); + const bool ARRAY_INDEX = true; + ExpressionPrinter printer(_order, ARRAY_INDEX); AST_ExpressionList indexes = _ref->firstIndex(); AST_ExpressionListIterator it; - int size = indexes->size(), i = 0; + unsigned long size = indexes->size(); + unsigned long i = 0; buffer << _begin_delimiter; foreach (it, indexes) { buffer << _begin_index_access << printer.apply(current_element(it)) << _end_index_access << (++i < size ? "," : ""); diff --git a/src/mmoc/util/visitors/expression_printer.h b/src/mmoc/util/visitors/expression_printer.h index 9ad82835..63bb8e07 100644 --- a/src/mmoc/util/visitors/expression_printer.h +++ b/src/mmoc/util/visitors/expression_printer.h @@ -27,27 +27,28 @@ namespace MicroModelica { namespace Util { class ExpressionPrinter : public AST_Expression_Visitor { public: - ExpressionPrinter(int order); - ~ExpressionPrinter() = default; + explicit ExpressionPrinter(int order, bool array_index = false); + ~ExpressionPrinter() override = default; private: - std::string foldTraverseElement(AST_Expression exp); - std::string foldTraverseElement(std::string l, std::string r, BinOpType bot); - std::string foldTraverseElementUMinus(AST_Expression exp); + std::string foldTraverseElement(AST_Expression exp) override; + std::string foldTraverseElement(std::string l, std::string r, BinOpType bot) override; + std::string foldTraverseElementUMinus(AST_Expression exp) override; IR::Expression _exp; int _order; + bool _array_index; }; class VariablePrinter { public: - VariablePrinter(Variable var, AST_Expression_ComponentReference ref, int order); + VariablePrinter(const Variable &var, AST_Expression_ComponentReference ref, int order, bool array_index = false); ~VariablePrinter() = default; friend std::ostream &operator<<(std::ostream &out, const VariablePrinter &var); protected: void generate(); - void config(); + void config(bool array_index); std::string access(bool arrray_access) const; private: @@ -59,6 +60,7 @@ class VariablePrinter { std::string _end_delimiter; std::string _begin_index_access; std::string _end_index_access; + std::string _cast; }; } // namespace Util