Skip to content

Commit 4d0d14f

Browse files
perostOpenModelica-Hudson
authored andcommitted
Initial support for for loops in NFInst
- Implemented for loop statements with explicit range. - Partially implemented for loop equations with explicit range (unrolling missing). - Implemented initial typing of subscripts.
1 parent 4124ebe commit 4d0d14f

File tree

12 files changed

+316
-107
lines changed

12 files changed

+316
-107
lines changed

Compiler/NFFrontEnd/NFBinding.mo

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ public
121121
end match;
122122
end typedExp;
123123

124+
function variability
125+
input Binding binding;
126+
output DAE.Const var;
127+
algorithm
128+
var := match binding
129+
case TYPED_BINDING() then binding.variability;
130+
else DAE.Const.C_UNKNOWN();
131+
end match;
132+
end variability;
133+
124134
function getInfo
125135
input Binding binding;
126136
output SourceInfo info;
@@ -133,6 +143,13 @@ public
133143
end match;
134144
end getInfo;
135145

146+
function getType
147+
input Binding binding;
148+
output Type ty;
149+
algorithm
150+
TYPED_BINDING(bindingType = ty) := binding;
151+
end getType;
152+
136153
function isEach
137154
input Binding binding;
138155
output Boolean isEach;

Compiler/NFFrontEnd/NFCeval.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ algorithm
6363
Expression exp1, exp2, exp3;
6464
list<Expression> expl = {};
6565
Call call;
66+
Component comp;
6667

6768
case Expression.CREF(cref=ComponentRef.CREF(node=c as InstNode.COMPONENT_NODE()))
6869
algorithm

Compiler/NFFrontEnd/NFComponent.mo

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ uniontype Component
112112
Component.Attributes attributes;
113113
end TYPED_COMPONENT;
114114

115+
record ITERATOR
116+
Type ty;
117+
Binding binding;
118+
end ITERATOR;
119+
115120
function classInstance
116121
input Component component;
117122
output InstNode classInst;
@@ -175,6 +180,7 @@ uniontype Component
175180
ty := match component
176181
case TYPED_COMPONENT() then component.ty;
177182
case UNTYPED_COMPONENT() then Class.getType(InstNode.getClass(component.classInst));
183+
case ITERATOR() then component.ty;
178184
else Type.UNKNOWN();
179185
end match;
180186
end getType;
@@ -192,6 +198,13 @@ uniontype Component
192198
component.ty := ty;
193199
then
194200
component;
201+
202+
case ITERATOR()
203+
algorithm
204+
component.ty := ty;
205+
then
206+
component;
207+
195208
end match;
196209
end setType;
197210

@@ -201,6 +214,8 @@ uniontype Component
201214
algorithm
202215
isTyped := match component
203216
case TYPED_COMPONENT() then true;
217+
case ITERATOR(ty = Type.UNKNOWN()) then false;
218+
case ITERATOR() then true;
204219
else false;
205220
end match;
206221
end isTyped;
@@ -218,6 +233,12 @@ uniontype Component
218233
then
219234
();
220235

236+
case ITERATOR(ty = Type.ARRAY(elementType = ty))
237+
algorithm
238+
component.ty := ty;
239+
then
240+
();
241+
221242
else ();
222243
end match;
223244
end unliftType;
@@ -239,6 +260,7 @@ uniontype Component
239260
b := match component
240261
case UNTYPED_COMPONENT() then component.binding;
241262
case TYPED_COMPONENT() then component.binding;
263+
case ITERATOR() then component.binding;
242264
end match;
243265
end getBinding;
244266

@@ -306,6 +328,7 @@ uniontype Component
306328
variability := match component
307329
case TYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
308330
case UNTYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
331+
case ITERATOR() then DAE.VarKind.CONST();
309332
else fail();
310333
end match;
311334
end variability;

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,11 @@ public
8383
function getVariability
8484
input ComponentRef cref;
8585
output DAE.Const var;
86-
protected
87-
DAE.VarKind var_kind;
8886
algorithm
8987
var := match cref
9088
case CREF()
91-
algorithm
92-
Component.Attributes.ATTRIBUTES(variability = var_kind) :=
93-
Component.getAttributes(InstNode.component(cref.node));
9489
then
95-
match var_kind
90+
match Component.variability(InstNode.component(cref.node))
9691
case DAE.VarKind.VARIABLE() then DAE.Const.C_VAR();
9792
case DAE.VarKind.DISCRETE() then DAE.Const.C_VAR();
9893
case DAE.VarKind.PARAM() then DAE.Const.C_PARAM();

Compiler/NFFrontEnd/NFEquation.mo

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ encapsulated package NFEquation
3434
import Absyn;
3535
import Expression = NFExpression;
3636
import Type = NFType;
37+
import NFInstNode.InstNode;
3738

3839
public uniontype Equation
3940
record EQUALITY
@@ -55,10 +56,7 @@ public uniontype Equation
5556
end CONNECT;
5657

5758
record FOR
58-
String name "The name of the iterator variable.";
59-
Integer index "The index of the iterator variable.";
60-
Type indexType "The type of the index/iterator variable.";
61-
Option<Expression> range "The range expression to loop over.";
59+
InstNode iterator;
6260
list<Equation> body "The body of the for loop.";
6361
SourceInfo info;
6462
end FOR;

Compiler/NFFrontEnd/NFFlatten.mo

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -530,32 +530,32 @@ algorithm
530530
then
531531
el :: elements;
532532

533-
case Equation.FOR()
534-
algorithm
535-
// flatten the equations
536-
(els1, funcs) := flattenEquations(eq.body, prefix, {}, funcs);
537-
538-
// deal with the range
539-
if isSome(eq.range) then
540-
SOME(e) := eq.range;
541-
SOME(de) := DAEUtil.evaluateExp(Expression.toDAE(e), elements);
542-
range := match (de)
543-
case DAE.ARRAY(array = range) then range;
544-
case DAE.RANGE(_, DAE.ICONST(is), SOME(DAE.ICONST(step)), DAE.ICONST(ie))
545-
then List.map(ExpressionSimplify.simplifyRange(is, step, ie), DAEExpression.makeIntegerExp);
546-
case DAE.RANGE(_, DAE.ICONST(is), _, DAE.ICONST(ie))
547-
then if is <= ie
548-
then List.map(ExpressionSimplify.simplifyRange(is, 1, ie), DAEExpression.makeIntegerExp)
549-
else List.map(ExpressionSimplify.simplifyRange(is, -1, ie), DAEExpression.makeIntegerExp);
550-
end match;
551-
// replace index in elements
552-
for i in range loop
553-
els := DAEUtil.replaceCrefInDAEElements(els1, DAE.CREF_IDENT(eq.name, Type.toDAE(eq.indexType), {}), i);
554-
elements := listAppend(els, elements);
555-
end for;
556-
end if;
557-
then
558-
elements;
533+
// case Equation.FOR()
534+
// algorithm
535+
// // flatten the equations
536+
// (els1, funcs) := flattenEquations(eq.body, prefix, {}, funcs);
537+
//
538+
// // deal with the range
539+
// if isSome(eq.range) then
540+
// SOME(e) := eq.range;
541+
// SOME(de) := DAEUtil.evaluateExp(Expression.toDAE(e), elements);
542+
// range := match (de)
543+
// case DAE.ARRAY(array = range) then range;
544+
// case DAE.RANGE(_, DAE.ICONST(is), SOME(DAE.ICONST(step)), DAE.ICONST(ie))
545+
// then List.map(ExpressionSimplify.simplifyRange(is, step, ie), DAEExpression.makeIntegerExp);
546+
// case DAE.RANGE(_, DAE.ICONST(is), _, DAE.ICONST(ie))
547+
// then if is <= ie
548+
// then List.map(ExpressionSimplify.simplifyRange(is, 1, ie), DAEExpression.makeIntegerExp)
549+
// else List.map(ExpressionSimplify.simplifyRange(is, -1, ie), DAEExpression.makeIntegerExp);
550+
// end match;
551+
// // replace index in elements
552+
// for i in range loop
553+
// els := DAEUtil.replaceCrefInDAEElements(els1, DAE.CREF_IDENT(eq.name, Type.toDAE(eq.indexType), {}), i);
554+
// elements := listAppend(els, elements);
555+
// end for;
556+
// end if;
557+
// then
558+
// elements;
559559

560560
case Equation.WHEN()
561561
algorithm
@@ -747,16 +747,9 @@ algorithm
747747

748748
case Statement.FOR()
749749
algorithm
750-
// flatten the list of statements
751-
(sts, funcs) := flattenStatements(alg.body, {}, funcs);
752-
if isSome(alg.range) then
753-
SOME(e) := alg.range;
754-
de := Expression.toDAE(e);
755-
else
756-
de := DAE.SCONST("NO RANGE GIVEN TODO FIXME");
757-
end if;
750+
(stmt, funcs) := flattenForStatement(alg, funcs);
758751
then
759-
DAE.STMT_FOR(Type.toDAE(alg.indexType), false, alg.name, alg.index, de, sts, ElementSource.createElementSource(alg.info)) :: stmts;
752+
stmt :: stmts;
760753

761754
case Statement.IF()
762755
algorithm
@@ -918,14 +911,13 @@ protected
918911
list<tuple<Expression, list<Statement>>> rest;
919912
Option<DAE.Statement> owhenStatement = NONE();
920913
algorithm
921-
922914
head :: rest := whenBranches;
923915
cond1 := Expression.toDAE(Util.tuple21(head));
924916
(stmts1, funcs) := flattenStatements(Util.tuple22(head), {}, funcs);
925917
rest := listReverse(rest);
926918

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

929+
function flattenForStatement
930+
input Statement forStmt;
931+
output DAE.Statement forDAE;
932+
input output DAE.FunctionTree funcs;
933+
protected
934+
InstNode iterator;
935+
Type ty;
936+
Binding binding;
937+
Expression range;
938+
list<Statement> body;
939+
list<DAE.Statement> dbody;
940+
SourceInfo info;
941+
algorithm
942+
Statement.FOR(iterator = iterator, body = body, info = info) := forStmt;
943+
944+
(dbody, funcs) := flattenStatements(body, {}, funcs);
945+
946+
Component.ITERATOR(ty = ty, binding = binding) := InstNode.component(iterator);
947+
SOME(range) := Binding.typedExp(binding);
948+
949+
forDAE := DAE.STMT_FOR(Type.toDAE(ty), Type.isArray(ty),
950+
InstNode.name(iterator), 0, Expression.toDAE(range), dbody,
951+
ElementSource.createElementSource(info));
952+
end flattenForStatement;
953+
937954
function applyExpPrefix
938955
input ComponentRef prefix;
939956
input output Expression exp;

Compiler/NFFrontEnd/NFInst.mo

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ algorithm
107107
// Instantiate component bindings. This is done as a separate step after
108108
// instantiation to make sure that lookup is able to find the correct nodes.
109109
instExpressions(inst_cls);
110-
execStat("NFInst.instBindings("+ name +")");
110+
execStat("NFInst.instExpressions("+ name +")");
111111

112112
// Type the class.
113113
Typing.typeClass(inst_cls);
@@ -1373,6 +1373,8 @@ algorithm
13731373
list<Equation> eql;
13741374
list<tuple<Expression, list<Equation>>> branches;
13751375
SourceInfo info;
1376+
Binding binding;
1377+
InstNode for_scope, iter;
13761378

13771379
case SCode.EEquation.EQ_EQUALS(info = info)
13781380
algorithm
@@ -1390,10 +1392,13 @@ algorithm
13901392

13911393
case SCode.EEquation.EQ_FOR(info = info)
13921394
algorithm
1393-
oexp := instExpOpt(scodeEq.range, scope, info);
1394-
eql := instEEquations(scodeEq.eEquationLst, scope);
1395+
binding := Binding.fromAbsyn(scodeEq.range, SCode.NOT_EACH(), 0, scope, info);
1396+
binding := instBinding(binding);
1397+
1398+
(for_scope, iter) := addIteratorToScope(scodeEq.index, binding, info, scope);
1399+
eql := instEEquations(scodeEq.eEquationLst, for_scope);
13951400
then
1396-
Equation.FOR(scodeEq.index, 0, Type.UNKNOWN(), oexp, eql, info);
1401+
Equation.FOR(iter, eql, info);
13971402

13981403
case SCode.EEquation.EQ_IF(info = info)
13991404
algorithm
@@ -1503,6 +1508,8 @@ algorithm
15031508
list<Statement> stmtl;
15041509
list<tuple<Expression, list<Statement>>> branches;
15051510
SourceInfo info;
1511+
Binding binding;
1512+
InstNode for_scope, iter;
15061513

15071514
case SCode.Statement.ALG_ASSIGN(info = info)
15081515
algorithm
@@ -1513,10 +1520,13 @@ algorithm
15131520

15141521
case SCode.Statement.ALG_FOR(info = info)
15151522
algorithm
1516-
oexp := instExpOpt(scodeStmt.range, scope, info);
1517-
stmtl := instStatements(scodeStmt.forBody, scope);
1523+
binding := Binding.fromAbsyn(scodeStmt.range, SCode.NOT_EACH(), 0, scope, info);
1524+
binding := instBinding(binding);
1525+
1526+
(for_scope, iter) := addIteratorToScope(scodeStmt.index, binding, info, scope);
1527+
stmtl := instStatements(scodeStmt.forBody, for_scope);
15181528
then
1519-
Statement.FOR(scodeStmt.index, 0, Type.UNKNOWN(), oexp, stmtl, info);
1529+
Statement.FOR(iter, stmtl, info);
15201530

15211531
case SCode.Statement.ALG_IF(info = info)
15221532
algorithm
@@ -1595,5 +1605,24 @@ algorithm
15951605
end match;
15961606
end instStatement;
15971607

1608+
function addIteratorToScope
1609+
input String name;
1610+
input Binding binding;
1611+
input SourceInfo info;
1612+
input output InstNode scope;
1613+
output InstNode iterator;
1614+
protected
1615+
Component iter_comp;
1616+
SCode.Element elem;
1617+
algorithm
1618+
scope := InstNode.openImplicitScope(scope);
1619+
elem := SCode.Element.COMPONENT(name, SCode.defaultPrefixes,
1620+
SCode.defaultVarAttr, Absyn.TypeSpec.TPATH(Absyn.Path.IDENT("$dummy"), NONE()),
1621+
SCode.NOMOD(), SCode.noComment, NONE(), info);
1622+
iter_comp := Component.ITERATOR(Type.UNKNOWN(), binding);
1623+
iterator := InstNode.fromComponent(name, iter_comp, elem, scope);
1624+
scope := InstNode.addIterator(iterator, scope);
1625+
end addIteratorToScope;
1626+
15981627
annotation(__OpenModelica_Interface="frontend");
15991628
end NFInst;

0 commit comments

Comments
 (0)