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

Commit d9899db

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Support for records in NFEvalFunction.
Belonging to [master]: - #2415 - OpenModelica/OpenModelica-testsuite#941
1 parent a1911e7 commit d9899db

File tree

4 files changed

+219
-18
lines changed

4 files changed

+219
-18
lines changed

Compiler/NFFrontEnd/NFClassTree.mo

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,15 @@ public
830830
end try;
831831
end lookupElementsPtr;
832832

833+
function lookupComponentIndex
834+
input String name;
835+
input ClassTree tree;
836+
output Integer index;
837+
algorithm
838+
LookupTree.Entry.COMPONENT(index = index) :=
839+
LookupTree.get(lookupTree(tree), name);
840+
end lookupComponentIndex;
841+
833842
function mapClasses
834843
input ClassTree tree;
835844
input FuncT func;

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,5 +728,17 @@ public
728728
end match;
729729
end isFromCref;
730730

731+
function toListReverse
732+
input ComponentRef cref;
733+
input list<ComponentRef> accum = {};
734+
output list<ComponentRef> crefs;
735+
algorithm
736+
crefs := match cref
737+
case CREF(origin = Origin.CREF)
738+
then toListReverse(cref.restCref, cref :: accum);
739+
else accum;
740+
end match;
741+
end toListReverse;
742+
731743
annotation(__OpenModelica_Interface="frontend");
732744
end NFComponentRef;

Compiler/NFFrontEnd/NFEvalFunction.mo

Lines changed: 133 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ algorithm
237237
Expression.RECORD(InstNode.scopePath(cls_node), cls.ty, bindings);
238238

239239
case Class.TYPED_DERIVED() then buildRecordBinding(cls.baseClass);
240-
else Expression.EMPTY();
240+
else Expression.makeMutable(Expression.EMPTY());
241241
end match;
242242
end buildRecordBinding;
243243

@@ -272,17 +272,56 @@ algorithm
272272
then
273273
fail();
274274

275-
case Expression.CREF() guard not ComponentRef.isIterator(exp.cref)
276-
algorithm
277-
// TODO: Handle subscripting.
278-
repl_exp := ReplTree.getOpt(repl, ComponentRef.toString(exp.cref));
279-
then
280-
if isSome(repl_exp) then Util.getOption(repl_exp) else exp;
281-
275+
case Expression.CREF() then applyReplacementCref(repl, exp.cref, exp);
282276
else exp;
283277
end match;
284278
end applyReplacements2;
285279

280+
function applyReplacementCref
281+
input ReplTree.Tree repl;
282+
input ComponentRef cref;
283+
input Expression exp;
284+
output Expression outExp;
285+
protected
286+
list<ComponentRef> cref_parts;
287+
Option<Expression> repl_exp;
288+
InstNode parent, node;
289+
algorithm
290+
// Explode the cref into a list of parts in reverse order.
291+
cref_parts := ComponentRef.toListReverse(cref);
292+
293+
// If the list is empty it's probably an iterator or _, which shouldn't be replaced.
294+
if listEmpty(cref_parts) then
295+
outExp := exp;
296+
else
297+
// Look up the replacement for the first part in the replacement tree.
298+
parent := ComponentRef.node(listHead(cref_parts));
299+
repl_exp := ReplTree.getOpt(repl, InstNode.name(parent));
300+
301+
if isSome(repl_exp) then
302+
SOME(outExp) := repl_exp;
303+
else
304+
outExp := exp;
305+
return;
306+
end if;
307+
308+
if not listEmpty(cref_parts) then
309+
try
310+
// If the cref consists of more than one identifier we need to look up
311+
// the corresponding record field in the expression.
312+
for cr in listRest(cref_parts) loop
313+
node := ComponentRef.node(cr);
314+
outExp := Expression.makeImmutable(outExp);
315+
outExp := Expression.lookupRecordField(InstNode.name(node), outExp);
316+
end for;
317+
else
318+
Error.assertion(false, getInstanceName() + " could not find replacement for " +
319+
ComponentRef.toString(cref), sourceInfo());
320+
end try;
321+
end if;
322+
end if;
323+
end applyReplacementCref;
324+
286325
function createResult
287326
input ReplTree.Tree repl;
288327
input list<InstNode> outputs;
@@ -293,14 +332,14 @@ protected
293332
Expression e;
294333
algorithm
295334
if listLength(outputs) == 1 then
296-
exp := Expression.makeImmutable(ReplTree.get(repl, InstNode.name(listHead(outputs))));
335+
exp := Ceval.evalExp(ReplTree.get(repl, InstNode.name(listHead(outputs))));
297336
assertAssignedOutput(listHead(outputs), exp);
298337
else
299338
expl := {};
300339
types := {};
301340

302341
for o in outputs loop
303-
e := Expression.makeImmutable(ReplTree.get(repl, InstNode.name(o)));
342+
e := Ceval.evalExp(ReplTree.get(repl, InstNode.name(o)));
304343
assertAssignedOutput(o, e);
305344
expl := e :: expl;
306345
end for;
@@ -371,27 +410,103 @@ function evaluateAssignment
371410
input Expression lhsExp;
372411
input Expression rhsExp;
373412
output FlowControl ctrl = FlowControl.NEXT;
374-
protected
375-
Expression rhs;
376413
algorithm
377-
rhs := Ceval.evalExp(rhsExp);
414+
assignVariable(lhsExp, Ceval.evalExp(rhsExp));
415+
end evaluateAssignment;
416+
417+
function assignVariable
418+
input Expression variable;
419+
input Expression value;
420+
algorithm
421+
() := match (variable, value)
422+
local
423+
Expression val;
424+
list<Expression> vals;
425+
426+
case (Expression.MUTABLE(), _)
427+
algorithm
428+
Mutable.update(variable.exp, assignExp(Mutable.access(variable.exp), value));
429+
then
430+
();
378431

379-
() := match lhsExp
380-
case Expression.MUTABLE()
432+
case (Expression.TUPLE(), Expression.TUPLE(elements = vals))
381433
algorithm
382-
Mutable.update(lhsExp.exp, rhs);
434+
for var in variable.elements loop
435+
val :: vals := vals;
436+
assignVariable(var, val);
437+
end for;
383438
then
384439
();
385440

386441
else
387442
algorithm
388443
Error.assertion(false, getInstanceName() + " failed on " +
389-
Expression.toString(lhsExp) + " := " + Expression.toString(rhsExp), sourceInfo());
444+
Expression.toString(variable) + " := " + Expression.toString(value), sourceInfo());
390445
then
391446
fail();
392447

393448
end match;
394-
end evaluateAssignment;
449+
end assignVariable;
450+
451+
function assignExp
452+
input Expression lhs;
453+
input Expression rhs;
454+
output Expression result;
455+
algorithm
456+
result := match lhs
457+
case Expression.RECORD()
458+
then assignRecord(lhs, rhs);
459+
460+
// TODO: Handle arrays.
461+
462+
else rhs;
463+
end match;
464+
end assignExp;
465+
466+
function assignRecord
467+
input Expression lhs;
468+
input Expression rhs;
469+
output Expression result;
470+
algorithm
471+
result := match rhs
472+
local
473+
list<Expression> elems;
474+
Expression e, val;
475+
ClassTree cls_tree;
476+
array<InstNode> comps;
477+
Option<Expression> binding_exp;
478+
Type ty;
479+
480+
case Expression.RECORD()
481+
algorithm
482+
Expression.RECORD(elements = elems) := lhs;
483+
484+
for v in rhs.elements loop
485+
e :: elems := elems;
486+
assignVariable(e, v);
487+
end for;
488+
then
489+
lhs;
490+
491+
case Expression.CREF()
492+
algorithm
493+
Expression.RECORD(elements = elems) := lhs;
494+
cls_tree := Class.classTree(InstNode.getClass(ComponentRef.node(rhs.cref)));
495+
comps := ClassTree.getComponents(cls_tree);
496+
497+
for c in comps loop
498+
e :: elems := elems;
499+
ty := InstNode.getType(c);
500+
val := Expression.CREF(Type.liftArrayLeftList(ty, Type.arrayDims(rhs.ty)),
501+
ComponentRef.prefixCref(c, ty, {}, rhs.cref));
502+
assignVariable(e, val);
503+
end for;
504+
then
505+
lhs;
506+
507+
else rhs;
508+
end match;
509+
end assignRecord;
395510

396511
function evaluateFor
397512
input InstNode iterator;

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public
5656
import NFCall.Call;
5757
import Binding = NFBinding;
5858
import NFComponent.Component;
59+
import NFClassTree.ClassTree;
60+
import NFClass.Class;
5961

6062
record INTEGER
6163
Integer value;
@@ -1275,6 +1277,12 @@ public
12751277
then
12761278
if referenceEq(exp.exp, e1) then exp else BOX(e1);
12771279

1280+
case MUTABLE()
1281+
algorithm
1282+
Mutable.update(exp.exp, map(Mutable.access(exp.exp), func));
1283+
then
1284+
exp;
1285+
12781286
else exp;
12791287
end match;
12801288

@@ -1563,6 +1571,12 @@ public
15631571
then
15641572
if referenceEq(exp.exp, e1) then exp else BOX(e1);
15651573

1574+
case MUTABLE()
1575+
algorithm
1576+
Mutable.update(exp.exp, func(Mutable.access(exp.exp)));
1577+
then
1578+
exp;
1579+
15661580
else exp;
15671581
end match;
15681582
end mapShallow;
@@ -1832,6 +1846,7 @@ public
18321846

18331847
case TUPLE_ELEMENT() then fold(exp.tupleExp, func, arg);
18341848
case BOX() then fold(exp.exp, func, arg);
1849+
case MUTABLE() then fold(Mutable.access(exp.exp), func, arg);
18351850
else arg;
18361851
end match;
18371852

@@ -2095,6 +2110,13 @@ public
20952110
then
20962111
if referenceEq(exp.tupleExp, e1) then exp else TUPLE_ELEMENT(e1, exp.index, exp.ty);
20972112

2113+
case MUTABLE()
2114+
algorithm
2115+
(e1, arg) := mapFold(Mutable.access(exp.exp), func, arg);
2116+
Mutable.update(exp.exp, e1);
2117+
then
2118+
exp;
2119+
20982120
else exp;
20992121
end match;
21002122

@@ -3426,5 +3448,48 @@ public
34263448
end match;
34273449
end makeImmutable;
34283450

3451+
function isMutable
3452+
input Expression exp;
3453+
output Boolean isMutable;
3454+
algorithm
3455+
isMutable := match exp
3456+
case MUTABLE() then true;
3457+
else false;
3458+
end match;
3459+
end isMutable;
3460+
3461+
function lookupRecordField
3462+
input String name;
3463+
input Expression exp;
3464+
output Expression fieldExp;
3465+
algorithm
3466+
fieldExp := match exp
3467+
local
3468+
InstNode node;
3469+
Integer index;
3470+
ClassTree cls_tree;
3471+
ComponentRef cref;
3472+
Type ty;
3473+
3474+
case RECORD(ty = Type.COMPLEX(cls = node))
3475+
algorithm
3476+
cls_tree := Class.classTree(InstNode.getClass(node));
3477+
index := ClassTree.lookupComponentIndex(name, cls_tree);
3478+
then
3479+
listGet(exp.elements, index);
3480+
3481+
case CREF(ty = Type.COMPLEX(cls = node))
3482+
algorithm
3483+
cls_tree := Class.classTree(InstNode.getClass(node));
3484+
(node, false) := ClassTree.lookupElement(name, cls_tree);
3485+
ty := InstNode.getType(node);
3486+
cref := ComponentRef.prefixCref(node, ty, {}, exp.cref);
3487+
ty := Type.liftArrayLeftList(ty, Type.arrayDims(exp.ty));
3488+
then
3489+
CREF(ty, cref);
3490+
3491+
end match;
3492+
end lookupRecordField;
3493+
34293494
annotation(__OpenModelica_Interface="frontend");
34303495
end NFExpression;

0 commit comments

Comments
 (0)