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

Commit 2e978c5

Browse files
adrpoOpenModelica-Hudson
authored andcommitted
[NF] Expandable Connectors [ticket:5015]
- partial implementation - during lookup create virtual crefs - during typing, type virtual crefs Short on what remains: Not sure how/when to add the virtual crefs as components in the ClassTree. We need to collect all connects, do the union of expandable connectors and then add all the virtual components to the FLAT_TREE before we do the flattening. Belonging to [master]: - #2608
1 parent 5698726 commit 2e978c5

File tree

6 files changed

+219
-7
lines changed

6 files changed

+219
-7
lines changed

Compiler/NFFrontEnd/NFClass.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ uniontype Class
469469
output Boolean isConnector = Restriction.isConnector(restriction(cls));
470470
end isConnectorClass;
471471

472+
function isExpandableConnectorClass
473+
input Class cls;
474+
output Boolean isConnector = Restriction.isExpandableConnector(restriction(cls));
475+
end isExpandableConnectorClass;
476+
472477
function isExternalObject
473478
input Class cls;
474479
output Boolean isExternalObject = Restriction.isExternalObject(restriction(cls));

Compiler/NFFrontEnd/NFComponent.mo

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,12 @@ uniontype Component
659659
Class.isConnectorClass(InstNode.getDerivedClass(classInstance(component)));
660660
end isConnector;
661661

662+
function isExpandableConnector
663+
input Component component;
664+
output Boolean isExpandableConnector =
665+
Class.isExpandableConnectorClass(InstNode.getDerivedClass(classInstance(component)));
666+
end isExpandableConnector;
667+
662668
function isIdentical
663669
input Component comp1;
664670
input Component comp2;

Compiler/NFFrontEnd/NFInstNode.mo

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,34 @@ uniontype InstNode
398398
end match;
399399
end isConnector;
400400

401+
function isExpandableConnector
402+
input InstNode node;
403+
output Boolean isConnector;
404+
algorithm
405+
isConnector := match node
406+
case COMPONENT_NODE() then Component.isExpandableConnector(component(node));
407+
else false;
408+
end match;
409+
end isExpandableConnector;
410+
411+
function hasParentExpandableConnector
412+
"@author: adrpo
413+
returns true if itself or any of the parents are expandable connectors"
414+
input InstNode node;
415+
output Boolean b = isExpandableConnector(node);
416+
protected
417+
InstNode p;
418+
algorithm
419+
p := node;
420+
while not isEmpty(p) loop
421+
p := parent(p);
422+
b := boolOr(b, isExpandableConnector(p));
423+
if b then
424+
break;
425+
end if;
426+
end while;
427+
end hasParentExpandableConnector;
428+
401429
function name
402430
input InstNode node;
403431
output String name;

Compiler/NFFrontEnd/NFLookup.mo

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ encapsulated package NFLookup
3636
"
3737

3838
import Absyn;
39+
import SCode;
3940
import Dump;
4041
import Error;
4142
import Global;
@@ -261,8 +262,18 @@ algorithm
261262
algorithm
262263
(node, foundCref, foundScope, state) :=
263264
lookupSimpleCref(cref.name, cref.subscripts, scope);
265+
if InstNode.isExpandableConnector(ComponentRef.node(foundCref)) then
266+
try // it migth not be there!
267+
(foundCref, foundScope, state) := lookupCrefInNode(cref.componentRef, node, foundCref, foundScope, state);
268+
else
269+
// add it if is not there, fake crefs
270+
(foundCref, foundScope, state) := createVirtualCrefs(cref.componentRef, node, foundCref, foundScope, state);
271+
end try;
272+
else
273+
(foundCref, foundScope, state) := lookupCrefInNode(cref.componentRef, node, foundCref, foundScope, state);
274+
end if;
264275
then
265-
lookupCrefInNode(cref.componentRef, node, foundCref, foundScope, state);
276+
(foundCref, foundScope, state);
266277

267278
case Absyn.ComponentRef.CREF_FULLYQUALIFIED()
268279
then lookupCref(cref.componentRef, InstNode.topScope(scope));
@@ -275,6 +286,58 @@ algorithm
275286
end match;
276287
end lookupCref;
277288

289+
function createVirtualCrefs
290+
"This function will create virtual crefs for the expandable connectors"
291+
input Absyn.ComponentRef cref;
292+
input InstNode node;
293+
input output ComponentRef foundCref;
294+
input output InstNode foundScope;
295+
input output LookupState state;
296+
protected
297+
SCode.Element definition;
298+
InstNode crefNode;
299+
algorithm
300+
(foundCref, foundScope, state) := match cref
301+
case Absyn.ComponentRef.CREF_IDENT()
302+
algorithm
303+
definition :=
304+
SCode.COMPONENT(
305+
cref.name,
306+
SCode.defaultPrefixes,
307+
SCode.defaultVarAttr,
308+
Absyn.TPATH(Absyn.IDENT("Any"), NONE()),
309+
SCode.NOMOD(),
310+
SCode.COMMENT(NONE(), SOME("virtual expandable component")),
311+
NONE(),
312+
Absyn.dummyInfo);
313+
crefNode := InstNode.newComponent(definition, node);
314+
foundCref := ComponentRef.fromAbsyn(crefNode, cref.subscripts, foundCref);
315+
state := LookupState.nodeState(crefNode);
316+
then
317+
(foundCref, foundScope, state);
318+
319+
case Absyn.ComponentRef.CREF_QUAL()
320+
algorithm
321+
definition :=
322+
SCode.COMPONENT(
323+
cref.name,
324+
SCode.defaultPrefixes,
325+
SCode.defaultVarAttr,
326+
Absyn.TPATH(Absyn.IDENT("Any"), NONE()),
327+
SCode.NOMOD(),
328+
SCode.COMMENT(NONE(), SOME("virtual expandable component")),
329+
NONE(),
330+
Absyn.dummyInfo);
331+
crefNode := InstNode.newComponent(definition, node);
332+
foundCref := ComponentRef.fromAbsyn(crefNode, cref.subscripts, foundCref);
333+
state := LookupState.nodeState(crefNode);
334+
(foundCref, foundScope, state) :=
335+
createVirtualCrefs(cref.componentRef, node, foundCref, foundScope, state);
336+
then
337+
(foundCref, foundScope, state);
338+
end match;
339+
end createVirtualCrefs;
340+
278341
function lookupLocalCref
279342
"Looks up a cref in the local scope without going into any enclosing scopes."
280343
input Absyn.ComponentRef cref;

Compiler/NFFrontEnd/NFRestriction.mo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ public
103103
end match;
104104
end isConnector;
105105

106+
function isExpandableConnector
107+
input Restriction res;
108+
output Boolean isConnector;
109+
algorithm
110+
isConnector := match res
111+
case CONNECTOR() then res.isExpandable;
112+
else false;
113+
end match;
114+
end isExpandableConnector;
115+
106116
function isExternalObject
107117
input Restriction res;
108118
output Boolean isExternalObject;

Compiler/NFFrontEnd/NFTyping.mo

Lines changed: 106 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import Direction = NFPrefixes.Direction;
8787
import ElementSource;
8888
import StringUtil;
8989
import NFOCConnectionGraph;
90+
import System;
9091

9192
uniontype TypingError
9293
record NO_ERROR end NO_ERROR;
@@ -2006,6 +2007,14 @@ algorithm
20062007
typeComponentSections(InstNode.resolveOuter(c), origin);
20072008
end for;
20082009

2010+
// we need to update the ClassTree and add the expandable virtual components from the connects
2011+
if System.getHasExpandableConnectors() then
2012+
// collect the expandable virtual components from the connect equations
2013+
2014+
// create the components inside the existing expandable connectors
2015+
end if;
2016+
2017+
20092018
InstNode.updateClass(typed_cls, classNode);
20102019
then
20112020
();
@@ -2378,8 +2387,18 @@ algorithm
23782387
end if;
23792388

23802389
next_origin := intBitOr(origin, ExpOrigin.CONNECT);
2381-
(lhs, lhs_ty, lhs_var) := typeExp(lhsConn, next_origin, info, replaceConstants = false);
2382-
(rhs, rhs_ty, rhs_var) := typeExp(rhsConn, next_origin, info, replaceConstants = false);
2390+
2391+
try // try the normal stuff first!
2392+
(lhs, lhs_ty, lhs_var) := typeExp(lhsConn, next_origin, info, replaceConstants = false);
2393+
(rhs, rhs_ty, rhs_var) := typeExp(rhsConn, next_origin, info, replaceConstants = false);
2394+
else // either is an error or there are expandable connectors in there
2395+
// check if any of them are expandable connectors!
2396+
if InstNode.hasParentExpandableConnector(ComponentRef.node(Expression.toCref(lhsConn))) or
2397+
InstNode.hasParentExpandableConnector(ComponentRef.node(Expression.toCref(rhsConn)))
2398+
then // handle expandable
2399+
(lhs, rhs, lhs_ty, lhs_var, rhs_ty, rhs_var) := typeExpandableConnectors(lhsConn, rhsConn, next_origin, info, replaceConstants = false);
2400+
end if;
2401+
end try;
23832402

23842403
checkConnector(lhs, info);
23852404
checkConnector(rhs, info);
@@ -2416,6 +2435,82 @@ algorithm
24162435
connEq := Equation.CONNECT(lhs, rhs, eql, source);
24172436
end typeConnect;
24182437

2438+
function typeExpandableConnectors
2439+
input output Expression lhs;
2440+
input output Expression rhs;
2441+
input ExpOrigin.Type origin;
2442+
input SourceInfo info;
2443+
input Boolean replaceConstants = true;
2444+
output Type tyLHS;
2445+
output Variability variabilityLHS;
2446+
output Type tyRHS;
2447+
output Variability variabilityRHS;
2448+
algorithm
2449+
// first, try to type both of them, they might already exist
2450+
try
2451+
(lhs, tyLHS, variabilityLHS) := typeExp(lhs, origin, info, replaceConstants = false);
2452+
(rhs, tyRHS, variabilityRHS) := typeExp(rhs, origin, info, replaceConstants = false);
2453+
return;
2454+
else
2455+
// do nothing, continue
2456+
end try;
2457+
2458+
// lhs existing, type it and use it!
2459+
if InstNode.isConnector(ComponentRef.node(Expression.toCref(lhs))) then
2460+
(lhs, tyLHS, variabilityLHS) := typeExp(lhs, origin, info, replaceConstants = false);
2461+
tyRHS := tyLHS;
2462+
variabilityRHS := variabilityLHS;
2463+
rhs := updateVirtualCrefExp(rhs, lhs, tyLHS, variabilityLHS);
2464+
return;
2465+
end if;
2466+
2467+
// rhs existing, reuse the case above
2468+
(rhs, lhs, tyRHS, variabilityRHS, tyLHS, variabilityLHS) := typeExpandableConnectors(rhs, lhs, origin, info, replaceConstants = false);
2469+
2470+
if InstNode.hasParentExpandableConnector(ComponentRef.node(Expression.toCref(rhs))) or
2471+
InstNode.hasParentExpandableConnector(ComponentRef.node(Expression.toCref(rhs)))
2472+
then
2473+
// error, we don't handle this case yet!
2474+
end if;
2475+
end typeExpandableConnectors;
2476+
2477+
function updateVirtualCrefExp
2478+
input output Expression virtual;
2479+
input Expression existing;
2480+
input Type ty;
2481+
input Variability var;
2482+
protected
2483+
ComponentRef v, e;
2484+
algorithm
2485+
virtual := match(virtual, existing)
2486+
case (Expression.CREF(_, v), Expression.CREF(_, e)) then Expression.CREF(ty, updateVirtualCref(v, e, ty, var));
2487+
end match;
2488+
end updateVirtualCrefExp;
2489+
2490+
function updateVirtualCref
2491+
input output ComponentRef virtual;
2492+
input ComponentRef existing;
2493+
input Type ty;
2494+
input Variability var;
2495+
protected
2496+
InstNode e;
2497+
algorithm
2498+
virtual := match (virtual, existing)
2499+
case (ComponentRef.CREF(), ComponentRef.CREF())
2500+
algorithm
2501+
virtual.ty := existing.ty;
2502+
// set the correct parrent
2503+
e := InstNode.setParent(existing.node, ComponentRef.node(virtual.restCref));
2504+
// change the name!
2505+
e := InstNode.rename(InstNode.name(virtual.node), e);
2506+
virtual.node := e;
2507+
virtual.origin := existing.origin;
2508+
then
2509+
virtual;
2510+
2511+
end match;
2512+
end updateVirtualCref;
2513+
24192514
function checkConnector
24202515
input Expression connExp;
24212516
input SourceInfo info;
@@ -2426,12 +2521,17 @@ algorithm
24262521
case Expression.CREF(cref = cr as ComponentRef.CREF(origin = Origin.CREF))
24272522
algorithm
24282523
if not InstNode.isConnector(cr.node) then
2429-
Error.addSourceMessage(Error.INVALID_CONNECTOR_TYPE,
2430-
{ComponentRef.toString(cr)}, info);
2431-
fail();
2524+
if not InstNode.hasParentExpandableConnector(cr.node) then
2525+
Error.addSourceMessage(Error.INVALID_CONNECTOR_TYPE,
2526+
{ComponentRef.toString(cr)}, info);
2527+
fail();
2528+
end if;
24322529
end if;
24332530

2434-
checkConnectorForm(cr, info);
2531+
// expandable connectors can have the form eC.C.m, eC.m
2532+
if not InstNode.hasParentExpandableConnector(cr.node) then
2533+
checkConnectorForm(cr, info);
2534+
end if;
24352535
then
24362536
();
24372537

0 commit comments

Comments
 (0)