Skip to content

Commit

Permalink
[NF] Support for records in NFEvalFunction.
Browse files Browse the repository at this point in the history
  • Loading branch information
perost authored and OpenModelica-Hudson committed May 7, 2018
1 parent a1911e7 commit d9899db
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 18 deletions.
9 changes: 9 additions & 0 deletions Compiler/NFFrontEnd/NFClassTree.mo
Expand Up @@ -830,6 +830,15 @@ public
end try;
end lookupElementsPtr;

function lookupComponentIndex
input String name;
input ClassTree tree;
output Integer index;
algorithm
LookupTree.Entry.COMPONENT(index = index) :=
LookupTree.get(lookupTree(tree), name);
end lookupComponentIndex;

function mapClasses
input ClassTree tree;
input FuncT func;
Expand Down
12 changes: 12 additions & 0 deletions Compiler/NFFrontEnd/NFComponentRef.mo
Expand Up @@ -728,5 +728,17 @@ public
end match;
end isFromCref;

function toListReverse
input ComponentRef cref;
input list<ComponentRef> accum = {};
output list<ComponentRef> crefs;
algorithm
crefs := match cref
case CREF(origin = Origin.CREF)
then toListReverse(cref.restCref, cref :: accum);
else accum;
end match;
end toListReverse;

annotation(__OpenModelica_Interface="frontend");
end NFComponentRef;
151 changes: 133 additions & 18 deletions Compiler/NFFrontEnd/NFEvalFunction.mo
Expand Up @@ -237,7 +237,7 @@ algorithm
Expression.RECORD(InstNode.scopePath(cls_node), cls.ty, bindings);

case Class.TYPED_DERIVED() then buildRecordBinding(cls.baseClass);
else Expression.EMPTY();
else Expression.makeMutable(Expression.EMPTY());
end match;
end buildRecordBinding;

Expand Down Expand Up @@ -272,17 +272,56 @@ algorithm
then
fail();

case Expression.CREF() guard not ComponentRef.isIterator(exp.cref)
algorithm
// TODO: Handle subscripting.
repl_exp := ReplTree.getOpt(repl, ComponentRef.toString(exp.cref));
then
if isSome(repl_exp) then Util.getOption(repl_exp) else exp;

case Expression.CREF() then applyReplacementCref(repl, exp.cref, exp);
else exp;
end match;
end applyReplacements2;

function applyReplacementCref
input ReplTree.Tree repl;
input ComponentRef cref;
input Expression exp;
output Expression outExp;
protected
list<ComponentRef> cref_parts;
Option<Expression> repl_exp;
InstNode parent, node;
algorithm
// Explode the cref into a list of parts in reverse order.
cref_parts := ComponentRef.toListReverse(cref);

// If the list is empty it's probably an iterator or _, which shouldn't be replaced.
if listEmpty(cref_parts) then
outExp := exp;
else
// Look up the replacement for the first part in the replacement tree.
parent := ComponentRef.node(listHead(cref_parts));
repl_exp := ReplTree.getOpt(repl, InstNode.name(parent));

if isSome(repl_exp) then
SOME(outExp) := repl_exp;
else
outExp := exp;
return;
end if;

if not listEmpty(cref_parts) then
try
// If the cref consists of more than one identifier we need to look up
// the corresponding record field in the expression.
for cr in listRest(cref_parts) loop
node := ComponentRef.node(cr);
outExp := Expression.makeImmutable(outExp);
outExp := Expression.lookupRecordField(InstNode.name(node), outExp);
end for;
else
Error.assertion(false, getInstanceName() + " could not find replacement for " +
ComponentRef.toString(cref), sourceInfo());
end try;
end if;
end if;
end applyReplacementCref;

function createResult
input ReplTree.Tree repl;
input list<InstNode> outputs;
Expand All @@ -293,14 +332,14 @@ protected
Expression e;
algorithm
if listLength(outputs) == 1 then
exp := Expression.makeImmutable(ReplTree.get(repl, InstNode.name(listHead(outputs))));
exp := Ceval.evalExp(ReplTree.get(repl, InstNode.name(listHead(outputs))));
assertAssignedOutput(listHead(outputs), exp);
else
expl := {};
types := {};

for o in outputs loop
e := Expression.makeImmutable(ReplTree.get(repl, InstNode.name(o)));
e := Ceval.evalExp(ReplTree.get(repl, InstNode.name(o)));
assertAssignedOutput(o, e);
expl := e :: expl;
end for;
Expand Down Expand Up @@ -371,27 +410,103 @@ function evaluateAssignment
input Expression lhsExp;
input Expression rhsExp;
output FlowControl ctrl = FlowControl.NEXT;
protected
Expression rhs;
algorithm
rhs := Ceval.evalExp(rhsExp);
assignVariable(lhsExp, Ceval.evalExp(rhsExp));
end evaluateAssignment;

function assignVariable
input Expression variable;
input Expression value;
algorithm
() := match (variable, value)
local
Expression val;
list<Expression> vals;

case (Expression.MUTABLE(), _)
algorithm
Mutable.update(variable.exp, assignExp(Mutable.access(variable.exp), value));
then
();

() := match lhsExp
case Expression.MUTABLE()
case (Expression.TUPLE(), Expression.TUPLE(elements = vals))
algorithm
Mutable.update(lhsExp.exp, rhs);
for var in variable.elements loop
val :: vals := vals;
assignVariable(var, val);
end for;
then
();

else
algorithm
Error.assertion(false, getInstanceName() + " failed on " +
Expression.toString(lhsExp) + " := " + Expression.toString(rhsExp), sourceInfo());
Expression.toString(variable) + " := " + Expression.toString(value), sourceInfo());
then
fail();

end match;
end evaluateAssignment;
end assignVariable;

function assignExp
input Expression lhs;
input Expression rhs;
output Expression result;
algorithm
result := match lhs
case Expression.RECORD()
then assignRecord(lhs, rhs);

// TODO: Handle arrays.

else rhs;
end match;
end assignExp;

function assignRecord
input Expression lhs;
input Expression rhs;
output Expression result;
algorithm
result := match rhs
local
list<Expression> elems;
Expression e, val;
ClassTree cls_tree;
array<InstNode> comps;
Option<Expression> binding_exp;
Type ty;

case Expression.RECORD()
algorithm
Expression.RECORD(elements = elems) := lhs;

for v in rhs.elements loop
e :: elems := elems;
assignVariable(e, v);
end for;
then
lhs;

case Expression.CREF()
algorithm
Expression.RECORD(elements = elems) := lhs;
cls_tree := Class.classTree(InstNode.getClass(ComponentRef.node(rhs.cref)));
comps := ClassTree.getComponents(cls_tree);

for c in comps loop
e :: elems := elems;
ty := InstNode.getType(c);
val := Expression.CREF(Type.liftArrayLeftList(ty, Type.arrayDims(rhs.ty)),
ComponentRef.prefixCref(c, ty, {}, rhs.cref));
assignVariable(e, val);
end for;
then
lhs;

else rhs;
end match;
end assignRecord;

function evaluateFor
input InstNode iterator;
Expand Down
65 changes: 65 additions & 0 deletions Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -56,6 +56,8 @@ public
import NFCall.Call;
import Binding = NFBinding;
import NFComponent.Component;
import NFClassTree.ClassTree;
import NFClass.Class;

record INTEGER
Integer value;
Expand Down Expand Up @@ -1275,6 +1277,12 @@ public
then
if referenceEq(exp.exp, e1) then exp else BOX(e1);

case MUTABLE()
algorithm
Mutable.update(exp.exp, map(Mutable.access(exp.exp), func));
then
exp;

else exp;
end match;

Expand Down Expand Up @@ -1563,6 +1571,12 @@ public
then
if referenceEq(exp.exp, e1) then exp else BOX(e1);

case MUTABLE()
algorithm
Mutable.update(exp.exp, func(Mutable.access(exp.exp)));
then
exp;

else exp;
end match;
end mapShallow;
Expand Down Expand Up @@ -1832,6 +1846,7 @@ public

case TUPLE_ELEMENT() then fold(exp.tupleExp, func, arg);
case BOX() then fold(exp.exp, func, arg);
case MUTABLE() then fold(Mutable.access(exp.exp), func, arg);
else arg;
end match;

Expand Down Expand Up @@ -2095,6 +2110,13 @@ public
then
if referenceEq(exp.tupleExp, e1) then exp else TUPLE_ELEMENT(e1, exp.index, exp.ty);

case MUTABLE()
algorithm
(e1, arg) := mapFold(Mutable.access(exp.exp), func, arg);
Mutable.update(exp.exp, e1);
then
exp;

else exp;
end match;

Expand Down Expand Up @@ -3426,5 +3448,48 @@ public
end match;
end makeImmutable;

function isMutable
input Expression exp;
output Boolean isMutable;
algorithm
isMutable := match exp
case MUTABLE() then true;
else false;
end match;
end isMutable;

function lookupRecordField
input String name;
input Expression exp;
output Expression fieldExp;
algorithm
fieldExp := match exp
local
InstNode node;
Integer index;
ClassTree cls_tree;
ComponentRef cref;
Type ty;

case RECORD(ty = Type.COMPLEX(cls = node))
algorithm
cls_tree := Class.classTree(InstNode.getClass(node));
index := ClassTree.lookupComponentIndex(name, cls_tree);
then
listGet(exp.elements, index);

case CREF(ty = Type.COMPLEX(cls = node))
algorithm
cls_tree := Class.classTree(InstNode.getClass(node));
(node, false) := ClassTree.lookupElement(name, cls_tree);
ty := InstNode.getType(node);
cref := ComponentRef.prefixCref(node, ty, {}, exp.cref);
ty := Type.liftArrayLeftList(ty, Type.arrayDims(exp.ty));
then
CREF(ty, cref);

end match;
end lookupRecordField;

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

0 comments on commit d9899db

Please sign in to comment.