Skip to content

Commit

Permalink
Added methods to parse when equations and transform them into when st…
Browse files Browse the repository at this point in the history
…atements.
  • Loading branch information
joaquinffernandez committed Apr 20, 2023
1 parent f6c27c6 commit d126bac
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 20 deletions.
150 changes: 133 additions & 17 deletions src/mmoc/ir/mmo_ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@

#include <iterator>

#include "../ast/class.h"
#include "../ast/composition.h"
#include "../ast/element.h"
#include "../ast/equation.h"
#include "../ast/expression.h"
#include "../ast/modification.h"
#include "../ast/statement.h"
#include "../util/visitors/eval_init_exp.h"
#include "../util/visitors/array_use.h"
#include "../util/visitors/discrete_assignment.h"
#include "../util/error.h"
#include "../util/symbol_table.h"
#include "../util/type.h"
#include "class.h"
#include "expression.h"
#include "helpers.h"
#include "stored_definition.h"
#include <ast/class.h>
#include <ast/composition.h>
#include <ast/element.h>
#include <ast/equation.h>
#include <ast/expression.h>
#include <ast/modification.h>
#include <ast/statement.h>
#include <ir/class.h>
#include <ir/expression.h>
#include <ir/helpers.h>
#include <ir/stored_definition.h>
#include <util/visitors/eval_init_exp.h>
#include <util/visitors/array_use.h>
#include <util/visitors/discrete_assignment.h>
#include <util/error.h>
#include <util/symbol_table.h>
#include <util/type.h>

namespace MicroModelica {
using namespace Util;
Expand Down Expand Up @@ -162,8 +162,124 @@ void MicroModelicaIR::leave(AST_Modification x)

void MicroModelicaIR::visit(AST_Comment x) {}

AST_StatementList MicroModelicaIR::getStatementList(AST_EquationList eqs)
{
AST_StatementList stms = newAST_StatementList();
AST_EquationListIterator eqs_it;
foreach (eqs_it, eqs) {
AST_Statement stm = transformEquation(current_element(eqs_it));
if (stm) {
stms = AST_ListAppend(stms, stm);
}
}
return stms;
}

bool MicroModelicaIR::checkForEquation(AST_Equation_For for_eq)
{
AST_EquationList for_eqs = for_eq->equationList();
AST_EquationListIterator eqs_it;
AST_StatementList when_stms = newAST_StatementList();
AST_EquationList split_for_eqs = newAST_EquationList();
foreach (eqs_it, for_eqs) {
if (current_element(eqs_it)->equationType() == EQWHEN) {
when_stms = AST_ListAppend(when_stms, transformWhenEquation(current_element(eqs_it)->getAsWhen()));
} else {
split_for_eqs = AST_ListAppend(split_for_eqs, current_element(eqs_it));
}
}
if (!when_stms->empty()) {
AST_Statement stm = newAST_Statement_For(for_eq->forIndexList(), when_stms);
visit(stm);
}
if (!split_for_eqs->empty()) {
AST_ForIndexList fil = for_eq->forIndexList();
AST_ForIndexListIterator it;
foreach (it, fil) {
visit(current_element(it));
}
AST_Equation eq = newAST_Equation_For(for_eq->forIndexList(), split_for_eqs);
_class->insert(eq);
}
return when_stms->empty();
}

AST_Statement MicroModelicaIR::transformWhenEquation(AST_Equation_When when_eq)
{
AST_StatementList true_stms = getStatementList(when_eq->equationList());
AST_Statement_ElseList else_when_stms = newAST_Statement_ElseList();
AST_Equation_ElseList else_when_eqs = when_eq->equationElseWhen();
AST_Equation_ElseListIterator else_when_eqs_it;
foreach (else_when_eqs_it, else_when_eqs) {
AST_Equation_Else eq_else_when = current_element(else_when_eqs_it);
AST_StatementList current_else_when_stms = getStatementList(eq_else_when->equations());
AST_Statement_Else add_stm_else = newAST_Statement_Else(eq_else_when->condition(), current_else_when_stms);
else_when_stms = AST_ListAppend(else_when_stms, add_stm_else);
}
return newAST_Statement_When(when_eq->condition(), true_stms, else_when_stms, when_eq->comment());
}

bool MicroModelicaIR::checkWhenEquation(AST_Equation eq)
{
AST_Statement stm = nullptr;
if (eq->equationType() == EQFOR) {
return checkForEquation(eq->getAsFor());
} else if (eq->equationType() == EQWHEN) {
stm = transformWhenEquation(eq->getAsWhen());
visit(stm);
return true;
}
return false;
}

AST_Statement MicroModelicaIR::transformEquation(AST_Equation x)
{
AST_Statement stm = nullptr;
if (x->equationType() == EQEQUALITY) {
AST_Equation_Equality eqe = x->getAsEquality();
AST_Expression_ComponentReference lhs = eqe->left()->getAsComponentReference();
stm = newAST_Statement_Assign(lhs, eqe->right());
} else if (x->equationType() == EQCALL) {
AST_Equation_Call eq_call = x->getAsCall();
AST_Expression call = eq_call->call();
if (call->expressionType() == EXPCALL) {
AST_Expression_Call exp_call = call->getAsCall();
AST_Expression_ComponentReference output_name = newAST_Expression_ComponentReference();
AST_ExpressionList l = newAST_ExpressionList();
output_name = AST_Expression_ComponentReference_Add(output_name, newAST_String(exp_call->name()), l);
stm = newAST_Statement_OutputAssign(exp_call->outputArguments(), output_name, exp_call->arguments());
}
} else if (x->equationType() == EQFOR) {
AST_Equation_For for_eq = x->getAsFor();
AST_StatementList stms = getStatementList(for_eq->equationList());
stm = newAST_Statement_For(for_eq->forIndexList(), stms);
} else if (x->equationType() == EQIF) {
AST_Equation_If if_eq = x->getAsIf();
AST_StatementList true_stms = getStatementList(if_eq->equationList());
AST_StatementList else_stms = getStatementList(if_eq->equationElseList());
AST_Statement_ElseList else_if_stms = newAST_Statement_ElseList();
AST_Equation_ElseList else_if_eqs = if_eq->equationElseIf();
AST_Equation_ElseListIterator else_if_eqs_it;
foreach (else_if_eqs_it, else_if_eqs) {
AST_Equation_Else eq_else_if = current_element(else_if_eqs_it);
AST_StatementList current_else_if_stms = getStatementList(eq_else_if->equations());
AST_Statement_Else add_stm_else = newAST_Statement_Else(eq_else_if->condition(), current_else_if_stms);
else_if_stms = AST_ListAppend(else_if_stms, add_stm_else);
}
stm = newAST_Statement_If(if_eq->condition(), true_stms, else_if_stms, else_stms);
}
return stm;
}

void MicroModelicaIR::visit(AST_Equation x)
{
if (_initialCode) {
visit(transformEquation(x));
return;
}
if (checkWhenEquation(x)) {
return;
}
if (x->equationType() == EQFOR) {
AST_ForIndexList fil = x->getAsFor()->forIndexList();
AST_ForIndexListIterator it;
Expand Down
11 changes: 8 additions & 3 deletions src/mmoc/ir/mmo_ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#include <list>
#include <string>

#include "../ast/ast_types.h"
#include "../util/ast_util.h"
#include "../ir/stored_definition.h"
#include <ast/ast_types.h>
#include <util/ast_util.h>
#include <ir/stored_definition.h>

namespace MicroModelica {
namespace IR {
Expand Down Expand Up @@ -63,6 +63,11 @@ class MicroModelicaIR : public AST_Visitor {

protected:
void visitForStms(AST_Statement_For for_stm);
AST_Statement transformEquation(AST_Equation eq);
AST_StatementList getStatementList(AST_EquationList eqs);
bool checkForEquation(AST_Equation_For for_eq);
bool checkWhenEquation(AST_Equation eq);
AST_Statement transformWhenEquation(AST_Equation_When when_eq);

private:
StoredDefinition _std;
Expand Down

0 comments on commit d126bac

Please sign in to comment.