Skip to content

Commit

Permalink
Initial support for for loops in NFInst
Browse files Browse the repository at this point in the history
- Implemented for loop statements with explicit range.
- Partially implemented for loop equations with explicit range
  (unrolling missing).
- Implemented initial typing of subscripts.
  • Loading branch information
perost authored and OpenModelica-Hudson committed Mar 14, 2017
1 parent 4124ebe commit 4d0d14f
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 107 deletions.
17 changes: 17 additions & 0 deletions Compiler/NFFrontEnd/NFBinding.mo
Expand Up @@ -121,6 +121,16 @@ public
end match;
end typedExp;

function variability
input Binding binding;
output DAE.Const var;
algorithm
var := match binding
case TYPED_BINDING() then binding.variability;
else DAE.Const.C_UNKNOWN();
end match;
end variability;

function getInfo
input Binding binding;
output SourceInfo info;
Expand All @@ -133,6 +143,13 @@ public
end match;
end getInfo;

function getType
input Binding binding;
output Type ty;
algorithm
TYPED_BINDING(bindingType = ty) := binding;
end getType;

function isEach
input Binding binding;
output Boolean isEach;
Expand Down
1 change: 1 addition & 0 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -63,6 +63,7 @@ algorithm
Expression exp1, exp2, exp3;
list<Expression> expl = {};
Call call;
Component comp;

case Expression.CREF(cref=ComponentRef.CREF(node=c as InstNode.COMPONENT_NODE()))
algorithm
Expand Down
23 changes: 23 additions & 0 deletions Compiler/NFFrontEnd/NFComponent.mo
Expand Up @@ -112,6 +112,11 @@ uniontype Component
Component.Attributes attributes;
end TYPED_COMPONENT;

record ITERATOR
Type ty;
Binding binding;
end ITERATOR;

function classInstance
input Component component;
output InstNode classInst;
Expand Down Expand Up @@ -175,6 +180,7 @@ uniontype Component
ty := match component
case TYPED_COMPONENT() then component.ty;
case UNTYPED_COMPONENT() then Class.getType(InstNode.getClass(component.classInst));
case ITERATOR() then component.ty;
else Type.UNKNOWN();
end match;
end getType;
Expand All @@ -192,6 +198,13 @@ uniontype Component
component.ty := ty;
then
component;

case ITERATOR()
algorithm
component.ty := ty;
then
component;

end match;
end setType;

Expand All @@ -201,6 +214,8 @@ uniontype Component
algorithm
isTyped := match component
case TYPED_COMPONENT() then true;
case ITERATOR(ty = Type.UNKNOWN()) then false;
case ITERATOR() then true;
else false;
end match;
end isTyped;
Expand All @@ -218,6 +233,12 @@ uniontype Component
then
();

case ITERATOR(ty = Type.ARRAY(elementType = ty))
algorithm
component.ty := ty;
then
();

else ();
end match;
end unliftType;
Expand All @@ -239,6 +260,7 @@ uniontype Component
b := match component
case UNTYPED_COMPONENT() then component.binding;
case TYPED_COMPONENT() then component.binding;
case ITERATOR() then component.binding;
end match;
end getBinding;

Expand Down Expand Up @@ -306,6 +328,7 @@ uniontype Component
variability := match component
case TYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
case UNTYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
case ITERATOR() then DAE.VarKind.CONST();
else fail();
end match;
end variability;
Expand Down
7 changes: 1 addition & 6 deletions Compiler/NFFrontEnd/NFComponentRef.mo
Expand Up @@ -83,16 +83,11 @@ public
function getVariability
input ComponentRef cref;
output DAE.Const var;
protected
DAE.VarKind var_kind;
algorithm
var := match cref
case CREF()
algorithm
Component.Attributes.ATTRIBUTES(variability = var_kind) :=
Component.getAttributes(InstNode.component(cref.node));
then
match var_kind
match Component.variability(InstNode.component(cref.node))
case DAE.VarKind.VARIABLE() then DAE.Const.C_VAR();
case DAE.VarKind.DISCRETE() then DAE.Const.C_VAR();
case DAE.VarKind.PARAM() then DAE.Const.C_PARAM();
Expand Down
6 changes: 2 additions & 4 deletions Compiler/NFFrontEnd/NFEquation.mo
Expand Up @@ -34,6 +34,7 @@ encapsulated package NFEquation
import Absyn;
import Expression = NFExpression;
import Type = NFType;
import NFInstNode.InstNode;

public uniontype Equation
record EQUALITY
Expand All @@ -55,10 +56,7 @@ public uniontype Equation
end CONNECT;

record FOR
String name "The name of the iterator variable.";
Integer index "The index of the iterator variable.";
Type indexType "The type of the index/iterator variable.";
Option<Expression> range "The range expression to loop over.";
InstNode iterator;
list<Equation> body "The body of the for loop.";
SourceInfo info;
end FOR;
Expand Down
91 changes: 54 additions & 37 deletions Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -530,32 +530,32 @@ 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
// // 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.WHEN()
algorithm
Expand Down Expand Up @@ -747,16 +747,9 @@ algorithm

case Statement.FOR()
algorithm
// flatten the list of statements
(sts, funcs) := flattenStatements(alg.body, {}, funcs);
if isSome(alg.range) then
SOME(e) := alg.range;
de := Expression.toDAE(e);
else
de := DAE.SCONST("NO RANGE GIVEN TODO FIXME");
end if;
(stmt, funcs) := flattenForStatement(alg, funcs);
then
DAE.STMT_FOR(Type.toDAE(alg.indexType), false, alg.name, alg.index, de, sts, ElementSource.createElementSource(alg.info)) :: stmts;
stmt :: stmts;

case Statement.IF()
algorithm
Expand Down Expand Up @@ -918,14 +911,13 @@ protected
list<tuple<Expression, list<Statement>>> rest;
Option<DAE.Statement> owhenStatement = NONE();
algorithm

head :: rest := whenBranches;
cond1 := Expression.toDAE(Util.tuple21(head));
(stmts1, funcs) := flattenStatements(Util.tuple22(head), {}, funcs);
rest := listReverse(rest);

for b in rest loop
cond2 := Expression.toDAE(Util.tuple21(b));
cond2 := Expression.toDAE(Util.tuple21(b));
(stmts2, funcs) := flattenStatements(Util.tuple22(b), {}, funcs);
whenStatement := DAE.STMT_WHEN(cond2, {}, false, stmts2, owhenStatement, ElementSource.createElementSource(info));
owhenStatement := SOME(whenStatement);
Expand All @@ -934,6 +926,31 @@ algorithm
whenStatement := DAE.STMT_WHEN(cond1, {}, false, stmts1, owhenStatement, ElementSource.createElementSource(info));
end flattenWhenStatement;

function flattenForStatement
input Statement forStmt;
output DAE.Statement forDAE;
input output DAE.FunctionTree funcs;
protected
InstNode iterator;
Type ty;
Binding binding;
Expression range;
list<Statement> body;
list<DAE.Statement> dbody;
SourceInfo info;
algorithm
Statement.FOR(iterator = iterator, body = body, info = info) := forStmt;

(dbody, funcs) := flattenStatements(body, {}, funcs);

Component.ITERATOR(ty = ty, binding = binding) := InstNode.component(iterator);
SOME(range) := Binding.typedExp(binding);

forDAE := DAE.STMT_FOR(Type.toDAE(ty), Type.isArray(ty),
InstNode.name(iterator), 0, Expression.toDAE(range), dbody,
ElementSource.createElementSource(info));
end flattenForStatement;

function applyExpPrefix
input ComponentRef prefix;
input output Expression exp;
Expand Down
43 changes: 36 additions & 7 deletions Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -107,7 +107,7 @@ algorithm
// Instantiate component bindings. This is done as a separate step after
// instantiation to make sure that lookup is able to find the correct nodes.
instExpressions(inst_cls);
execStat("NFInst.instBindings("+ name +")");
execStat("NFInst.instExpressions("+ name +")");

// Type the class.
Typing.typeClass(inst_cls);
Expand Down Expand Up @@ -1373,6 +1373,8 @@ algorithm
list<Equation> eql;
list<tuple<Expression, list<Equation>>> branches;
SourceInfo info;
Binding binding;
InstNode for_scope, iter;

case SCode.EEquation.EQ_EQUALS(info = info)
algorithm
Expand All @@ -1390,10 +1392,13 @@ algorithm

case SCode.EEquation.EQ_FOR(info = info)
algorithm
oexp := instExpOpt(scodeEq.range, scope, info);
eql := instEEquations(scodeEq.eEquationLst, scope);
binding := Binding.fromAbsyn(scodeEq.range, SCode.NOT_EACH(), 0, scope, info);
binding := instBinding(binding);

(for_scope, iter) := addIteratorToScope(scodeEq.index, binding, info, scope);
eql := instEEquations(scodeEq.eEquationLst, for_scope);
then
Equation.FOR(scodeEq.index, 0, Type.UNKNOWN(), oexp, eql, info);
Equation.FOR(iter, eql, info);

case SCode.EEquation.EQ_IF(info = info)
algorithm
Expand Down Expand Up @@ -1503,6 +1508,8 @@ algorithm
list<Statement> stmtl;
list<tuple<Expression, list<Statement>>> branches;
SourceInfo info;
Binding binding;
InstNode for_scope, iter;

case SCode.Statement.ALG_ASSIGN(info = info)
algorithm
Expand All @@ -1513,10 +1520,13 @@ algorithm

case SCode.Statement.ALG_FOR(info = info)
algorithm
oexp := instExpOpt(scodeStmt.range, scope, info);
stmtl := instStatements(scodeStmt.forBody, scope);
binding := Binding.fromAbsyn(scodeStmt.range, SCode.NOT_EACH(), 0, scope, info);
binding := instBinding(binding);

(for_scope, iter) := addIteratorToScope(scodeStmt.index, binding, info, scope);
stmtl := instStatements(scodeStmt.forBody, for_scope);
then
Statement.FOR(scodeStmt.index, 0, Type.UNKNOWN(), oexp, stmtl, info);
Statement.FOR(iter, stmtl, info);

case SCode.Statement.ALG_IF(info = info)
algorithm
Expand Down Expand Up @@ -1595,5 +1605,24 @@ algorithm
end match;
end instStatement;

function addIteratorToScope
input String name;
input Binding binding;
input SourceInfo info;
input output InstNode scope;
output InstNode iterator;
protected
Component iter_comp;
SCode.Element elem;
algorithm
scope := InstNode.openImplicitScope(scope);
elem := SCode.Element.COMPONENT(name, SCode.defaultPrefixes,
SCode.defaultVarAttr, Absyn.TypeSpec.TPATH(Absyn.Path.IDENT("$dummy"), NONE()),
SCode.NOMOD(), SCode.noComment, NONE(), info);
iter_comp := Component.ITERATOR(Type.UNKNOWN(), binding);
iterator := InstNode.fromComponent(name, iter_comp, elem, scope);
scope := InstNode.addIterator(iterator, scope);
end addIteratorToScope;

annotation(__OpenModelica_Interface="frontend");
end NFInst;

0 comments on commit 4d0d14f

Please sign in to comment.