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

Commit 8cf7496

Browse files
perostOpenModelica-Hudson
authored andcommitted
NFInst improvements.
- Implemented handling of array classes. - Improved typing of dimensions, including detection of dependency loops and inferring unknown dimensions from bindings. - Improved type matching of arrays and component bindings. - Improved typing of size expressions.
1 parent df2b0b4 commit 8cf7496

File tree

10 files changed

+546
-94
lines changed

10 files changed

+546
-94
lines changed

Compiler/NFFrontEnd/NFCeval.mo

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ uniontype EvalTarget
6161
end RANGE;
6262

6363
record IGNORE_ERRORS end IGNORE_ERRORS;
64+
65+
function isRange
66+
input EvalTarget target;
67+
output Boolean isRange;
68+
algorithm
69+
isRange := match target
70+
case RANGE() then true;
71+
else false;
72+
end match;
73+
end isRange;
6474
end EvalTarget;
6575

6676
function evalExp
@@ -76,13 +86,15 @@ algorithm
7686
Call call;
7787
Component comp;
7888
Option<Expression> oexp;
89+
ComponentRef cref;
7990

80-
case Expression.CREF(cref=ComponentRef.CREF(node = c as InstNode.COMPONENT_NODE()))
91+
case Expression.CREF(cref = cref as ComponentRef.CREF(node = c as InstNode.COMPONENT_NODE()))
8192
algorithm
8293
Typing.typeComponentBinding(c);
8394
binding := Component.getBinding(InstNode.component(c));
95+
exp1 := evalBinding(binding, exp, target);
8496
then
85-
evalBinding(binding, exp, target);
97+
Expression.subscript(exp1, cref.subscripts);
8698

8799
case Expression.TYPENAME()
88100
then evalTypename(exp.ty, exp, target);
@@ -231,23 +243,29 @@ function evalTypename
231243
protected
232244
list<Expression> lits;
233245
algorithm
234-
exp := match ty
235-
case Type.ARRAY(elementType = Type.BOOLEAN())
236-
then Expression.ARRAY(ty, {Expression.BOOLEAN(false), Expression.BOOLEAN(true)});
237-
238-
case Type.ARRAY(elementType = Type.ENUMERATION())
239-
algorithm
240-
lits := Expression.makeEnumLiterals(ty.elementType);
241-
then
242-
Expression.ARRAY(ty, lits);
243-
244-
else
245-
algorithm
246-
assert(false, getInstanceName() + " got invalid typename");
247-
then
248-
fail();
249-
250-
end match;
246+
// Only expand the typename into an array if it's used as a range, and keep
247+
// them as typenames when used as e.g. dimensions.
248+
if not EvalTarget.isRange(target) then
249+
exp := originExp;
250+
else
251+
exp := match ty
252+
case Type.ARRAY(elementType = Type.BOOLEAN())
253+
then Expression.ARRAY(ty, {Expression.BOOLEAN(false), Expression.BOOLEAN(true)});
254+
255+
case Type.ARRAY(elementType = Type.ENUMERATION())
256+
algorithm
257+
lits := Expression.makeEnumLiterals(ty.elementType);
258+
then
259+
Expression.ARRAY(ty, lits);
260+
261+
else
262+
algorithm
263+
assert(false, getInstanceName() + " got invalid typename");
264+
then
265+
fail();
266+
267+
end match;
268+
end if;
251269
end evalTypename;
252270

253271
annotation(__OpenModelica_Interface="frontend");

Compiler/NFFrontEnd/NFClass.mo

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,18 @@ uniontype Class
268268
else true;
269269
end match;
270270
end isIdentical;
271+
272+
function getDimensions
273+
input Class cls;
274+
output list<Dimension> dims;
275+
algorithm
276+
dims := match cls
277+
case DERIVED_CLASS()
278+
then listAppend(cls.dims, getDimensions(InstNode.getClass(cls.baseClass)));
279+
else {};
280+
end match;
281+
end getDimensions;
282+
271283
end Class;
272284

273285
annotation(__OpenModelica_Interface="frontend");

Compiler/NFFrontEnd/NFComponent.mo

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ uniontype Component
457457
else false;
458458
end match;
459459
end isRedeclare;
460-
461460
end Component;
462461

463462
annotation(__OpenModelica_Interface="frontend");

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public
115115
() := match cref
116116
case CREF()
117117
algorithm
118-
cref.subscripts := subscript :: cref.subscripts;
118+
cref.subscripts := listAppend(cref.subscripts, {subscript});
119119
then
120120
();
121121
end match;

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,5 +711,21 @@ public
711711
end match;
712712
end toDAE;
713713

714+
function dimensionCount
715+
input Expression exp;
716+
output Integer dimCount;
717+
algorithm
718+
dimCount := match exp
719+
case ARRAY(ty = Type.UNKNOWN())
720+
then 1 + dimensionCount(listHead(exp.elements));
721+
case ARRAY() then Type.dimensionCount(exp.ty);
722+
case RANGE() then Type.dimensionCount(exp.ty);
723+
case SIZE(dimIndex = NONE()) then dimensionCount(exp.exp);
724+
case CAST() then dimensionCount(exp.exp);
725+
// TODO: Add more expressions.
726+
else 0;
727+
end match;
728+
end dimensionCount;
729+
714730
annotation(__OpenModelica_Interface="frontend");
715731
end NFExpression;

Compiler/NFFrontEnd/NFInst.mo

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ algorithm
300300

301301
// Fetch the needed information from the class definition and construct a DERIVED_CLASS.
302302
prefs := instClassPrefixes(def);
303-
dims := list(Dimension.RAW_DIM(d) for d in cdef.attributes.arrayDims);
303+
dims := list(Dimension.RAW_DIM(d) for d in Absyn.typeSpecDimensions(ty));
304304
mod := Class.getModifier(InstNode.getClass(node));
305305
c := Class.DERIVED_CLASS(ext_node, mod, dims, prefs, cdef.attributes.direction);
306306
node := InstNode.updateClass(c, node);
@@ -516,6 +516,7 @@ protected
516516
ClassTree cls_tree;
517517
Modifier cls_mod, mod;
518518
list<Modifier> type_attr;
519+
list<Dimension> dims;
519520
algorithm
520521
cls := InstNode.getClass(node);
521522
cls_mod := Class.getModifier(cls);
@@ -568,7 +569,8 @@ algorithm
568569
algorithm
569570
mod := Modifier.fromElement(InstNode.definition(node), InstNode.parent(node));
570571
mod := Modifier.merge(cls_mod, mod);
571-
node := instClass(cls.baseClass, mod, parent);
572+
cls.baseClass := instClass(cls.baseClass, mod, parent);
573+
node := InstNode.replaceClass(cls, node);
572574
then
573575
();
574576

@@ -923,6 +925,18 @@ algorithm
923925
then
924926
();
925927

928+
case Class.DERIVED_CLASS()
929+
algorithm
930+
sections := instExpressions(cls.baseClass, scope, sections);
931+
932+
if not listEmpty(cls.dims) then
933+
cls.dims := list(instDimension(d, InstNode.parent(node), InstNode.info(node))
934+
for d in cls.dims);
935+
InstNode.updateClass(cls, node);
936+
end if;
937+
then
938+
();
939+
926940
case Class.INSTANCED_BUILTIN()
927941
algorithm
928942
cls.attributes := list(instBuiltinAttribute(a) for a in cls.attributes);
@@ -958,18 +972,45 @@ function instComponentExpressions
958972
input InstNode scope;
959973
protected
960974
Component c = InstNode.component(component);
961-
array<Dimension> dims;
975+
array<Dimension> dims, all_dims;
976+
list<Dimension> cls_dims;
977+
Integer len;
962978
algorithm
963979
() := match c
964980
case Component.UNTYPED_COMPONENT(dimensions = dims)
965981
algorithm
966982
c.binding := instBinding(c.binding);
983+
instExpressions(c.classInst, component);
967984

968-
for i in 1:arrayLength(dims) loop
969-
dims[i] := instDimension(dims[i], scope, c.info);
970-
end for;
985+
cls_dims := Class.getDimensions(InstNode.getClass(c.classInst));
986+
len := arrayLength(dims);
987+
988+
if listEmpty(cls_dims) then
989+
// If we have no type dimensions, simply instantiate the component's dimensions.
990+
for i in 1:len loop
991+
dims[i] := instDimension(dims[i], scope, c.info);
992+
end for;
993+
else
994+
// If we have type dimensions, allocate space for them and add them to
995+
// the component's dimensions.
996+
all_dims := Dangerous.arrayCreateNoInit(len + listLength(cls_dims), Dimension.UNKNOWN());
997+
998+
// Instantiate the component's dimensions.
999+
for i in 1:len loop
1000+
all_dims[i] := instDimension(dims[i], scope, c.info);
1001+
end for;
1002+
1003+
// Add the already instantiated dimensions from the type.
1004+
len := len + 1;
1005+
for e in cls_dims loop
1006+
all_dims[len] := e;
1007+
len := len + 1;
1008+
end for;
1009+
1010+
// Update the dimensions in the component.
1011+
c.dimensions := all_dims;
1012+
end if;
9711013

972-
instExpressions(c.classInst, component);
9731014
InstNode.updateComponent(c, component);
9741015
then
9751016
();

Compiler/NFFrontEnd/NFType.mo

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,17 @@ public
335335
end try;
336336
end getTypeDims;
337337

338+
function nthDimension
339+
input Type ty;
340+
input Integer index;
341+
output Dimension dim;
342+
algorithm
343+
dim := match ty
344+
case ARRAY() then listGet(ty.dimensions, index);
345+
case FUNCTION() then nthDimension(ty.resultType, index);
346+
end match;
347+
end nthDimension;
348+
338349
function dimensionCount
339350
input Type ty;
340351
output Integer dimCount;
@@ -370,7 +381,7 @@ public
370381
case Type.REAL() then "Real";
371382
case Type.STRING() then "String";
372383
case Type.BOOLEAN() then "Boolean";
373-
case Type.ENUMERATION() then "enumeration()";
384+
case Type.ENUMERATION() then "enumeration(" + stringDelimitList(ty.literals, ", ") + ")";
374385
case Type.ENUMERATION_ANY() then "enumeration(:)";
375386
case Type.CLOCK() then "Clock";
376387
case Type.ARRAY() then toString(ty.elementType) + "[" + stringDelimitList(List.map(ty.dimensions, Dimension.toString), ", ") + "]";

0 commit comments

Comments
 (0)