Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
Improved support for for loop equations in NFInst.
Browse files Browse the repository at this point in the history
- Implemented support for for loop equations with constant integer or
  array range.
  • Loading branch information
perost authored and OpenModelica-Hudson committed Mar 14, 2017
1 parent 4d0d14f commit cfa55d7
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 26 deletions.
66 changes: 40 additions & 26 deletions Compiler/NFFrontEnd/NFFlatten.mo
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ protected
import DAEUtil;
import NFCall.Call;
import NFFunction.Function;
import RangeIterator = NFRangeIterator;

public
partial function ExpandScalarFunc<ElementT>
Expand Down Expand Up @@ -530,32 +531,11 @@ algorithm
then
el :: elements;

// case Equation.FOR()
// algorithm
// // flatten the equations
// (els1, funcs) := flattenEquations(eq.body, prefix, {}, funcs);
//
// // deal with the range
// if isSome(eq.range) then
// SOME(e) := eq.range;
// SOME(de) := DAEUtil.evaluateExp(Expression.toDAE(e), elements);
// range := match (de)
// case DAE.ARRAY(array = range) then range;
// case DAE.RANGE(_, DAE.ICONST(is), SOME(DAE.ICONST(step)), DAE.ICONST(ie))
// then List.map(ExpressionSimplify.simplifyRange(is, step, ie), DAEExpression.makeIntegerExp);
// case DAE.RANGE(_, DAE.ICONST(is), _, DAE.ICONST(ie))
// then if is <= ie
// then List.map(ExpressionSimplify.simplifyRange(is, 1, ie), DAEExpression.makeIntegerExp)
// else List.map(ExpressionSimplify.simplifyRange(is, -1, ie), DAEExpression.makeIntegerExp);
// end match;
// // replace index in elements
// for i in range loop
// els := DAEUtil.replaceCrefInDAEElements(els1, DAE.CREF_IDENT(eq.name, Type.toDAE(eq.indexType), {}), i);
// elements := listAppend(els, elements);
// end for;
// end if;
// then
// elements;
case Equation.FOR()
algorithm
(elements, funcs) := flattenForEquation(eq, prefix, elements, funcs);
then
elements;

case Equation.WHEN()
algorithm
Expand Down Expand Up @@ -642,6 +622,40 @@ algorithm
end for;
end flattenInitialEquations;

function flattenForEquation
input Equation forEq;
input ComponentRef prefix;
input output list<DAE.Element> elements;
input output DAE.FunctionTree funcs;
protected
InstNode iterator;
Type ty;
Binding binding;
Expression range;
list<Equation> body;
list<DAE.Element> dbody, dbody_unrolled;
SourceInfo info;
RangeIterator range_iter;
Expression exp;
DAE.ComponentRef iter_cr;
Boolean b;
algorithm
Equation.FOR(iterator = iterator, body = body, info = info) := forEq;

(dbody, funcs) := flattenEquations(body, prefix, {}, funcs);

Component.ITERATOR(ty = ty, binding = binding) := InstNode.component(iterator);
SOME(range) := Binding.typedExp(binding);
iter_cr := DAE.CREF_IDENT(InstNode.name(iterator), Type.toDAE(ty), {});

range_iter := RangeIterator.new(range);
while RangeIterator.hasNext(range_iter) loop
(range_iter, exp) := RangeIterator.next(range_iter);
dbody_unrolled := DAEUtil.replaceCrefInDAEElements(dbody, iter_cr, Expression.toDAE(exp));
elements := listAppend(dbody_unrolled, elements);
end while;
end flattenForEquation;

function flattenIfEquation
input list<tuple<Expression, list<Equation>>> ifBranches;
input ComponentRef prefix;
Expand Down
133 changes: 133 additions & 0 deletions Compiler/NFFrontEnd/NFRangeIterator.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from OSMC, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

encapsulated uniontype NFRangeIterator
protected
import RangeIterator = NFRangeIterator;

public
import Expression = NFExpression;

record INT_RANGE
Integer current;
Integer stepsize;
Integer last;
end INT_RANGE;

record REAL_RANGE
Real start;
Real stepsize;
Real stop;
end REAL_RANGE;

record ENUM_RANGE

end ENUM_RANGE;

record ARRAY
list<Expression> values;
end ARRAY;

function new
input Expression exp;
output RangeIterator iterator;
algorithm
iterator := match exp
local
Integer istart, istep, istop;
Real rstart, rstep, rstop;

case Expression.ARRAY() then ARRAY(exp.elements);

case Expression.RANGE(start = Expression.INTEGER(istart),
step = SOME(Expression.INTEGER(istep)),
stop = Expression.INTEGER(istop))
then INT_RANGE(istart, istep, istop);

case Expression.RANGE(start = Expression.INTEGER(istart),
step = NONE(),
stop = Expression.INTEGER(istop))
then INT_RANGE(istart, 1, istop);

case Expression.RANGE(start = Expression.REAL(rstart),
step = SOME(Expression.REAL(rstep)),
stop = Expression.REAL(rstop))
then REAL_RANGE(rstart, rstep, rstop);

case Expression.RANGE(start = Expression.REAL(rstart),
step = NONE(),
stop = Expression.REAL(rstop))
then REAL_RANGE(rstart, 1.0, rstop);

else
algorithm
assert(false, getInstanceName() + " got unknown range");
then
fail();

end match;
end new;

function next
input output RangeIterator iterator;
output Expression nextExp;
algorithm
nextExp := match iterator
case INT_RANGE()
algorithm
nextExp := Expression.INTEGER(iterator.current);
iterator.current := iterator.current + iterator.stepsize;
then
nextExp;

case ARRAY()
algorithm
nextExp := listHead(iterator.values);
iterator.values := listRest(iterator.values);
then
nextExp;

end match;
end next;

function hasNext
input RangeIterator iterator;
output Boolean hasNext;
algorithm
hasNext := match iterator
case INT_RANGE() then iterator.current <= iterator.last;
case ARRAY({}) then false;
case ARRAY() then true;
end match;
end hasNext;

annotation(__OpenModelica_Interface="frontend");
end NFRangeIterator;
1 change: 1 addition & 0 deletions Compiler/boot/LoadCompilerSources.mos
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ if true then /* Suppress output */
"../NFFrontEnd/NFLookupState.mo",
"../NFFrontEnd/NFMod.mo",
"../NFFrontEnd/NFOperator.mo",
"../NFFrontEnd/NFRangeIterator.mo",
"../NFFrontEnd/NFRecord.mo",
"../NFFrontEnd/NFSimplifyExp.mo",
"../NFFrontEnd/NFStatement.mo",
Expand Down

0 comments on commit cfa55d7

Please sign in to comment.