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

Commit e4cfc38

Browse files
perostOpenModelica-Hudson
authored andcommitted
New instantiation improvements.
- Fixed scoping when instantiating inherited components. - Fixed userdefined types so they can be used more than once. - Fixed userdefined type which extends from userdefined type. - Added error message for combining extends of builtin type with other elements.
1 parent d7fc7be commit e4cfc38

File tree

8 files changed

+158
-66
lines changed

8 files changed

+158
-66
lines changed

Compiler/NFFrontEnd/NFComponent.mo

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,6 @@ uniontype Component
8484
InstNode node;
8585
end EXTENDS_NODE;
8686

87-
record COMPONENT_REF
88-
Integer node;
89-
Integer index;
90-
end COMPONENT_REF;
91-
9287
function isNamedComponent
9388
input Component component;
9489
output Boolean isNamed;
@@ -106,6 +101,7 @@ uniontype Component
106101
classInst := match component
107102
case UNTYPED_COMPONENT() then component.classInst;
108103
case TYPED_COMPONENT() then component.classInst;
104+
case EXTENDS_NODE() then component.node;
109105
end match;
110106
end classInstance;
111107

Compiler/NFFrontEnd/NFComponentNode.mo

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,6 @@ uniontype ComponentNode
7171
node := COMPONENT_NODE("", definition, c, EMPTY_NODE());
7272
end newExtends;
7373

74-
function newReference
75-
input output ComponentNode component;
76-
input Integer nodeIndex;
77-
input Integer componentIndex;
78-
algorithm
79-
component := replaceComponent(Component.COMPONENT_REF(nodeIndex, componentIndex), component);
80-
end newReference;
81-
8274
function name
8375
input ComponentNode node;
8476
output String name;
@@ -129,6 +121,23 @@ uniontype ComponentNode
129121
end match;
130122
end setParent;
131123

124+
function setOrphanParent
125+
"Sets the parent of a component node if the node lacks a parent, otherwise
126+
does nothing."
127+
input ComponentNode parent;
128+
input output ComponentNode node;
129+
algorithm
130+
() := match node
131+
case COMPONENT_NODE(parent = EMPTY_NODE())
132+
algorithm
133+
node.parent := parent;
134+
then
135+
();
136+
137+
else ();
138+
end match;
139+
end setOrphanParent;
140+
132141
function component
133142
input ComponentNode node;
134143
output Component component;

Compiler/NFFrontEnd/NFFlatten.mo

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,12 @@ algorithm
142142
then
143143
();
144144

145-
case Component.COMPONENT_REF() then ();
145+
else
146+
algorithm
147+
assert(true, "flattenComponent got unknown component");
148+
then
149+
fail();
150+
146151
end match;
147152
end flattenComponent;
148153

Compiler/NFFrontEnd/NFInst.mo

Lines changed: 116 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,11 @@ algorithm
319319
Integer idx;
320320
list<Equation> eq, ieq;
321321
list<list<Statement>> alg, ialg;
322-
Option<InstNode> special_ext;
323322
InstNode n;
324323
Modifier mod;
324+
list<ComponentNode> ext_nodes;
325+
Option<ComponentNode> builtin_ext;
326+
ComponentNode builtin_comp;
325327

326328
case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = ty, modifications = der_mod))
327329
algorithm
@@ -340,31 +342,26 @@ algorithm
340342
Instance.PARTIAL_CLASS(classes = scope, elements = elements, modifier = mod) :=
341343
InstNode.instance(node);
342344

343-
// Change the instance to an expanded instance, to avoid instantiation loops.
345+
// Change the instance to an empty expanded instance, to avoid instantiation loops.
344346
i := Instance.initExpandedClass(scope);
345347
node := InstNode.setInstance(i, node);
346348

347349
// Expand all the extends clauses.
348-
(components, scope, special_ext) := expandExtends(elements, def.name, node, scope);
349-
350-
if isSome(special_ext) then
351-
SOME(n) := special_ext;
352-
i := InstNode.instance(n);
353-
mod := Modifier.merge(Instance.getModifier(i), mod);
354-
i := Instance.setModifier(mod, i);
355-
_ := InstNode.setInstance(i, node);
356-
node := InstNode.setInstance(i, n);
350+
(components, scope, ext_nodes, builtin_ext) :=
351+
expandExtends(elements, def.name, node, scope);
352+
353+
if isSome(builtin_ext) then
354+
SOME(builtin_comp) := builtin_ext;
355+
node := expandBuiltinExtends(builtin_comp, ext_nodes, components, scope, mod, node);
357356
else
358357
// Add component ID:s to the scope.
359358
idx := 1;
360359
for c in components loop
361-
if Component.isNamedComponent(ComponentNode.component(c)) then
362-
// TODO: Handle components with the same name.
363-
// TODO: If duplicate components should be handled here, also
364-
// remove them from the list of components.
365-
scope := ClassTree.add(scope, ComponentNode.name(c),
366-
ClassTree.Entry.COMPONENT(idx), ClassTree.addConflictReplace);
367-
end if;
360+
// // TODO: Handle components with the same name.
361+
// // TODO: If duplicate components should be handled here, also
362+
// // remove them from the list of components.
363+
scope := ClassTree.add(scope, ComponentNode.name(c),
364+
ClassTree.Entry.COMPONENT(idx), ClassTree.addConflictReplace);
368365

369366
idx := idx + 1;
370367
end for;
@@ -374,7 +371,7 @@ algorithm
374371
alg := instAlgorithmSections(cdef.normalAlgorithmLst, node);
375372
ialg := instAlgorithmSections(cdef.initialAlgorithmLst, node);
376373

377-
i := Instance.EXPANDED_CLASS(scope, listArray(components), mod, eq, ieq, alg, ialg);
374+
i := Instance.EXPANDED_CLASS(scope, ext_nodes, listArray(components), mod, eq, ieq, alg, ialg);
378375
node := InstNode.setInstance(i, node);
379376
end if;
380377
then
@@ -401,13 +398,15 @@ function expandExtends
401398
input InstNode currentScope;
402399
output list<ComponentNode> components = {};
403400
input output ClassTree.Tree scope;
404-
output Option<InstNode> specialExtends = NONE();
401+
output list<ComponentNode> extendsNodes = {};
402+
output Option<ComponentNode> builtinExtends = NONE();
405403
protected
406404
InstNode ext_node;
407405
Instance ext_inst;
408406
Modifier mod;
409407
ModifierScope mod_scope;
410-
Boolean is_builtin;
408+
Boolean is_builtin, builtin_ext;
409+
ComponentNode ext_comp;
411410
algorithm
412411
for e in elements loop
413412
() := match e
@@ -431,17 +430,23 @@ algorithm
431430
mod_scope := ModifierScope.EXTENDS_SCOPE(e.baseClassPath);
432431
mod := Modifier.create(e.modifications, "", mod_scope, currentScope);
433432

434-
// Apply the modifier to the expanded instance of the extended class.
433+
// Apply the modifier from the extends clause to the expanded instance.
435434
ext_inst := InstNode.instance(ext_node);
436435
ext_inst := applyModifier(mod, ext_inst, mod_scope);
437436
ext_node := InstNode.setInstance(ext_inst, ext_node);
438437

439-
if not is_builtin then
440-
components := addInheritedComponentRefs(ext_inst, components);
438+
ext_comp := ComponentNode.newExtends(ext_node, e);
439+
ext_inst := InstNode.instance(ext_node);
440+
builtin_ext := isBuiltinExtends(ext_inst);
441+
442+
if not builtin_ext then
443+
components := addInheritedComponentRefs(ext_inst, components, ext_comp);
441444
scope := addInheritedClasses(ext_inst, scope);
442445
else
443-
specialExtends := SOME(ext_node);
446+
builtinExtends := SOME(ext_comp);
444447
end if;
448+
449+
extendsNodes := ext_comp :: extendsNodes;
445450
then
446451
();
447452

@@ -462,6 +467,52 @@ algorithm
462467
end for;
463468
end expandExtends;
464469

470+
function isBuiltinExtends
471+
"Checks if an extends is extending a builtin type."
472+
input Instance instance;
473+
output Boolean isBuiltinExtends;
474+
algorithm
475+
isBuiltinExtends := match instance
476+
case Instance.PARTIAL_BUILTIN() then true;
477+
else false;
478+
end match;
479+
end isBuiltinExtends;
480+
481+
function expandBuiltinExtends
482+
"This function handles the case where a class extends from a builtin type."
483+
input ComponentNode builtinExtends;
484+
input list<ComponentNode> extendsNodes;
485+
input list<ComponentNode> components;
486+
input ClassTree.Tree scope;
487+
input Modifier modifier;
488+
input output InstNode node;
489+
protected
490+
InstNode n;
491+
Instance i;
492+
Modifier mod;
493+
algorithm
494+
Component.EXTENDS_NODE(node = n) := ComponentNode.component(builtinExtends);
495+
496+
// A class extending from a builtin type may not have any other elements.
497+
if listLength(extendsNodes) <> 1 or listLength(components) > 0 or
498+
not ClassTree.isEmpty(scope) then
499+
Error.addSourceMessage(Error.BUILTIN_EXTENDS_INVALID_ELEMENTS,
500+
{InstNode.name(n)},
501+
SCode.elementInfo(ComponentNode.definition(builtinExtends)));
502+
fail();
503+
end if;
504+
505+
// Fetch the instance of the builtin type.
506+
i := InstNode.instance(n);
507+
508+
// Apply the given modifier to the instance.
509+
mod := Modifier.merge(Instance.getModifier(i), modifier);
510+
i := Instance.setModifier(mod, i);
511+
512+
// Replace the instance of the class we're expanding with the builtin type's instance.
513+
node := InstNode.setInstance(i, node);
514+
end expandBuiltinExtends;
515+
465516
function applyModifier
466517
"Takes a modifier and applies the submodifiers in it to an instance."
467518
input Modifier modifier;
@@ -474,6 +525,7 @@ algorithm
474525
ClassTree.Tree elements;
475526
array<ComponentNode> components;
476527
ClassTree.Entry entry;
528+
InstNode node;
477529

478530
case Instance.EXPANDED_CLASS(elements = elements, components = components)
479531
algorithm
@@ -503,11 +555,26 @@ algorithm
503555

504556
case ClassTree.Entry.CLASS()
505557
algorithm
506-
// If a class is modified it's probably going to be used, so we
507-
// might as well partially instantiate it now to simplify the
508-
// modifier handling a bit.
509-
entry.node := partialInstClass(entry.node);
510-
InstNode.apply(entry.node, Instance.setModifier, m);
558+
_ := match m
559+
case Modifier.MODIFIER()
560+
algorithm
561+
// If a class is modified it's probably going to be used, so we
562+
// might as well partially instantiate it now to simplify the
563+
// modifier handling a bit.
564+
entry.node := partialInstClass(entry.node);
565+
InstNode.apply(entry.node, Instance.setModifier, m);
566+
then
567+
();
568+
569+
case Modifier.REDECLARE()
570+
algorithm
571+
node := InstNode.new(SCode.elementName(m.element), m.element, m.scope);
572+
elements := ClassTree.add(elements, InstNode.name(node),
573+
ClassTree.Entry.CLASS(node), ClassTree.addConflictReplace);
574+
then
575+
();
576+
577+
end match;
511578
then
512579
();
513580

@@ -529,6 +596,7 @@ end applyModifier;
529596
function addInheritedComponentRefs
530597
input Instance extendsInstance;
531598
input output list<ComponentNode> components;
599+
input ComponentNode parent;
532600
protected
533601
ComponentNode cn;
534602
algorithm
@@ -539,9 +607,10 @@ algorithm
539607
cn := arrayGet(extendsInstance.components, i);
540608

541609
components := match ComponentNode.component(cn)
610+
// Collect all the component definitions.
542611
case Component.COMPONENT_DEF() then cn :: components;
543-
case Component.EXTENDS_NODE() then components;
544612

613+
// Any other component shouldn't show up here.
545614
else
546615
algorithm
547616
Error.addInternalError("NFInst.addInheritedComponentRefs got unknown component.",
@@ -591,7 +660,9 @@ protected
591660
Modifier type_mod, mod;
592661
list<Modifier> type_mods, inst_type_mods;
593662
Binding binding;
594-
InstNode cur_scope;
663+
InstNode n, cur_scope;
664+
list<ComponentNode> ext_nodes;
665+
Component c;
595666
algorithm
596667
i := InstNode.instance(node);
597668

@@ -607,7 +678,17 @@ algorithm
607678
i_mod := applyModifier(modifier, i,
608679
ModifierScope.CLASS_SCOPE(InstNode.name(node)));
609680

610-
// Instantiate all the components.
681+
// Instantiate all the extends nodes first.
682+
Instance.EXPANDED_CLASS(extendsNodes = ext_nodes) := i_mod;
683+
for ext in ext_nodes loop
684+
Component.EXTENDS_NODE(node = n) := ComponentNode.component(ext);
685+
// No modifier, the modifier on the extends clause has already been
686+
// applied in expandExtends.
687+
instClass(n, Modifier.NOMOD(), ext);
688+
end for;
689+
690+
// Instantiate all local components. This will skip inherited
691+
// components, since those have already been instantiated.
611692
components := Array.map(Instance.components(i_mod),
612693
function instComponent(parent = parent, scope = node));
613694

@@ -648,7 +729,7 @@ algorithm
648729
end for;
649730
end if;
650731

651-
i_mod := Instance.INSTANCED_BUILTIN(inst_type_mods);
732+
i_mod := Instance.INSTANCED_BUILTIN(i.name, inst_type_mods);
652733
node := InstNode.setInstance(i_mod, node);
653734
then
654735
();
@@ -687,7 +768,7 @@ algorithm
687768
algorithm
688769
name := ComponentNode.name(node);
689770
node := ComponentNode.clone(node);
690-
node := ComponentNode.setParent(parent, node);
771+
node := ComponentNode.setOrphanParent(parent, node);
691772

692773
// Merge the modifier from the component.
693774
comp_mod := Modifier.create(comp.modifications, name,
@@ -712,14 +793,6 @@ algorithm
712793
then
713794
();
714795

715-
case Component.EXTENDS_NODE()
716-
algorithm
717-
cls := instClass(component.node, Modifier.NOMOD(), parent);
718-
component.node := cls;
719-
node := ComponentNode.updateComponent(component, node);
720-
then
721-
();
722-
723796
else ();
724797
end match;
725798
end instComponent;

Compiler/NFFrontEnd/NFInstance.mo

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ uniontype Instance
9191

9292
record EXPANDED_CLASS
9393
ClassTree.Tree elements;
94+
list<ComponentNode> extendsNodes;
9495
array<ComponentNode> components;
9596
Modifier modifier;
9697
list<Equation> equations;
@@ -109,10 +110,12 @@ uniontype Instance
109110
end INSTANCED_CLASS;
110111

111112
record PARTIAL_BUILTIN
113+
String name;
112114
Modifier modifier;
113115
end PARTIAL_BUILTIN;
114116

115117
record INSTANCED_BUILTIN
118+
String name;
116119
list<Modifier> attributes;
117120
end INSTANCED_BUILTIN;
118121

@@ -128,7 +131,7 @@ uniontype Instance
128131
input ClassTree.Tree classes;
129132
output Instance instance;
130133
algorithm
131-
instance := EXPANDED_CLASS(classes, listArray({}), Modifier.NOMOD(), {}, {}, {}, {});
134+
instance := EXPANDED_CLASS(classes, {}, listArray({}), Modifier.NOMOD(), {}, {}, {}, {});
132135
end initExpandedClass;
133136

134137
function components
@@ -188,7 +191,7 @@ uniontype Instance
188191
algorithm
189192
instance := match instance
190193
case EXPANDED_CLASS()
191-
then EXPANDED_CLASS(instance.elements, instance.components,
194+
then EXPANDED_CLASS(instance.elements, instance.extendsNodes, instance.components,
192195
instance.modifier, equations, initialEquations, algorithms, initialAlgorithms);
193196

194197
case INSTANCED_CLASS()

0 commit comments

Comments
 (0)