@@ -46,6 +46,7 @@ import NFInstNode.InstNode;
4646import NFLookupState.LookupState ;
4747import NFPrefix.Prefix ;
4848import Type = NFType ;
49+ import NFMod.Modifier ;
4950
5051type MatchType = enumeration(FOUND , NOT_FOUND , PARTIAL );
5152
@@ -79,11 +80,12 @@ function lookupComponent
7980 input SourceInfo info;
8081 input Boolean allowTypename = false ;
8182 output InstNode foundComponent "The component the cref resolves to." ;
82- output Prefix prefix;
83+ output list< InstNode > restNodes "The rest of the found nodes." ;
84+ output InstNode foundScope "The scope the first part of the cref was found in." ;
8385protected
8486 LookupState state;
8587algorithm
86- (foundComponent, prefix , state) := lookupCref(cref, scope, info);
88+ (foundComponent, restNodes, foundScope , state) := lookupCref(cref, scope, info);
8789
8890 if allowTypename then
8991 state := fixTypenameState(foundComponent, state);
@@ -114,48 +116,55 @@ function lookupFunctionName
114116 input InstNode scope "The scope to look in." ;
115117 input SourceInfo info;
116118 output InstNode func ;
117- output Prefix prefix ;
119+ output InstNode foundScope ;
118120protected
119121 LookupState state;
120122algorithm
121- (func , prefix , state) := lookupCref(cref, scope, info);
123+ (func , _, foundScope , state) := lookupCref(cref, scope, info);
122124 LookupState . assertFunction(state, func , cref, info);
123125end lookupFunctionName;
124126
125127function lookupCref
128+ "This function will look up a component reference in the given scope, and
129+ return a list of nodes that correspond to the parts of the cref in reverse
130+ order. I.e. when looking up the cref a.b.c, the list of nodes {c, b, a} will
131+ be returned. The scope where the first part of the cref was found will also
132+ be returned."
126133 input Absyn . ComponentRef cref;
127134 input InstNode scope "The scope to look in." ;
128135 input SourceInfo info;
129- output InstNode node;
130- output Prefix prefix;
136+ output InstNode node "The node the cref refers to." ;
137+ output list< InstNode > restNodes "The rest of the found nodes." ;
138+ output InstNode foundScope "The scope where the first part of the cref was found." ;
131139 output LookupState state;
132140protected
133141 MatchType match_ty;
142+ InstNode n;
134143algorithm
135- (node, prefix , state, match_ty) := lookupBuiltinCref(cref, info);
144+ (node, restNodes , state, match_ty) := lookupBuiltinCref(cref, info);
136145
137146 if match_ty == MatchType . NOT_FOUND then
138147 match_ty := MatchType . FOUND ;
139148
140- (node, prefix , state) := matchcontinue cref
149+ (node, restNodes, foundScope , state) := matchcontinue cref
141150 local
142151 Class . Element element;
143152 InstNode found_scope;
144153
145154 case Absyn . ComponentRef . CREF_IDENT ()
146155 algorithm
147- (node, prefix ) := lookupSimpleCref(cref. name, scope);
156+ (node, foundScope ) := lookupSimpleCref(cref. name, scope);
148157 state := LookupState . nodeState(node);
149158 then
150- (node, prefix , state);
159+ (node, {node}, foundScope , state);
151160
152161 case Absyn . ComponentRef . CREF_QUAL ()
153162 algorithm
154- (node, prefix ) := lookupSimpleCref(cref. name, scope);
155- state := LookupState . nodeState(node );
156- (node, state) := lookupCrefInNode(cref. componentRef, node , state);
163+ (n, foundScope ) := lookupSimpleCref(cref. name, scope);
164+ state := LookupState . nodeState(n );
165+ (node, restNodes, state) := lookupCrefInNode(cref. componentRef, n , state);
157166 then
158- (node, prefix , state);
167+ (node, n :: restNodes, foundScope , state);
159168
160169 case Absyn . ComponentRef . CREF_FULLYQUALIFIED ()
161170 then lookupCref(cref. componentRef, InstNode . topComponent(scope), info);
@@ -164,8 +173,10 @@ algorithm
164173 algorithm
165174 match_ty := MatchType . NOT_FOUND ;
166175 then
167- (InstNode . EMPTY_NODE (), Prefix . NO_PREFIX () , LookupState . STATE_BEGIN ());
176+ (InstNode . EMPTY_NODE (), {}, scope , LookupState . STATE_BEGIN ());
168177 end matchcontinue;
178+ else
179+ foundScope := scope;
169180 end if ;
170181
171182 if match_ty <> MatchType . FOUND then
@@ -181,7 +192,7 @@ function lookupBuiltinCref
181192 input Absyn . ComponentRef cref;
182193 input SourceInfo info;
183194 output InstNode node;
184- output Prefix prefix = Prefix . NO_PREFIX () ;
195+ output list < InstNode > restNodes ;
185196 output LookupState state = LookupState . STATE_PREDEF_COMP ();
186197 output MatchType matchType = MatchType . FOUND ;
187198protected
@@ -190,39 +201,62 @@ protected
190201algorithm
191202 cr := Absyn . unqualifyCref(cref);
192203
193- node := match cr
194- local
195-
204+ (node, restNodes) := match cr
196205 case Absyn . ComponentRef . CREF_IDENT ()
197- then match cr. name
198- case "time" then NFBuiltin . TIME ;
199- case "Boolean" then NFBuiltin . BOOLEAN_TYPE ;
200- case "StateSelect" then NFBuiltin . STATESELECT_TYPE ;
201- else algorithm matchType := MatchType . NOT_FOUND ; then InstNode . EMPTY_NODE ();
202- end match;
206+ algorithm
207+ node := match cr. name
208+ case "time" then NFBuiltin . TIME ;
209+ case "Boolean" then NFBuiltin . BOOLEAN_TYPE ;
210+ case "StateSelect" then NFBuiltin . STATESELECT_TYPE ;
211+ else
212+ algorithm
213+ matchType := MatchType . NOT_FOUND ;
214+ then
215+ InstNode . EMPTY_NODE ();
216+ end match;
217+ then
218+ (node, {node});
203219
204220 case Absyn . ComponentRef . CREF_QUAL ()
205- then match cr. name
206- case "StateSelect"
207- then match cr. componentRef
208- case Absyn . CREF_IDENT (name = id)
209- then match id
210- case "never" then NFBuiltin . STATESELECT_NEVER ;
211- case "avoid" then NFBuiltin . STATESELECT_AVOID ;
212- case "default" then NFBuiltin . STATESELECT_DEFAULT ;
213- case "prefer" then NFBuiltin . STATESELECT_PREFER ;
214- case "always" then NFBuiltin . STATESELECT_ALWAYS ;
215- // Invalid StateSelect member.
216- else algorithm matchType := MatchType . PARTIAL ; then InstNode . EMPTY_NODE ();
221+ algorithm
222+ node := match cr. name
223+ case "StateSelect"
224+ algorithm
225+ node := match cr. componentRef
226+ case Absyn . CREF_IDENT (name = id)
227+ then match id
228+ case "never" then NFBuiltin . STATESELECT_NEVER ;
229+ case "avoid" then NFBuiltin . STATESELECT_AVOID ;
230+ case "default" then NFBuiltin . STATESELECT_DEFAULT ;
231+ case "prefer" then NFBuiltin . STATESELECT_PREFER ;
232+ case "always" then NFBuiltin . STATESELECT_ALWAYS ;
233+ else // Invalid StateSelect member.
234+ algorithm
235+ matchType := MatchType . PARTIAL ;
236+ then
237+ InstNode . EMPTY_NODE ();
238+ end match;
239+
240+ else // Invalid StateSelect form.
241+ algorithm
242+ matchType := MatchType . PARTIAL ;
243+ then
244+ InstNode . EMPTY_NODE ();
217245 end match;
218246
219- // Invalid StateSelect form.
220- else algorithm matchType := MatchType . PARTIAL ; then InstNode . EMPTY_NODE ();
221- end match;
222-
223- // Qualified name that's not a builtin name.
224- else algorithm matchType := MatchType . NOT_FOUND ; then InstNode . EMPTY_NODE ();
225- end match;
247+ restNodes := {NFBuiltin . STATESELECT_TYPE , node};
248+ then
249+ node;
250+
251+ else // Qualified name that's not a builtin name.
252+ algorithm
253+ matchType := MatchType . NOT_FOUND ;
254+ restNodes := {};
255+ then
256+ InstNode . EMPTY_NODE ();
257+ end match;
258+ then
259+ (node, restNodes);
226260
227261 end match;
228262end lookupBuiltinCref;
@@ -385,9 +419,8 @@ function lookupSimpleCref
385419 input String name;
386420 input InstNode scope;
387421 output InstNode node;
388- output Prefix prefix ;
422+ output InstNode foundScope = scope ;
389423protected
390- InstNode foundScope = scope;
391424 Class cls;
392425 Class . Element e;
393426algorithm
@@ -400,14 +433,7 @@ algorithm
400433 cls := InstNode . getClass(foundScope);
401434 node := Class . lookupElement(name, cls);
402435
403- // We found it, build the prefix for the found cref.
404- if i == 1 then
405- prefix := InstNode . prefix(scope);
406- else
407- prefix := InstNode . prefix(foundScope);
408- end if ;
409-
410- // We're done here.
436+ // We found a node, return it.
411437 return ;
412438 else
413439 // Look in the next enclosing scope.
@@ -423,14 +449,20 @@ end lookupSimpleCref;
423449function lookupCrefInNode
424450 input Absyn . ComponentRef cref;
425451 input output InstNode node;
452+ output list< InstNode > nodes;
426453 input output LookupState state;
427454protected
428455 Class scope;
456+ InstNode n;
429457algorithm
430458 if LookupState . isError(state) then
431459 return ;
432460 end if ;
433461
462+ // TODO: If the node is a package and the cref is qualified, then we should
463+ // fully instantiate the node and not just expand it. Otherwise we can't look
464+ // up something like P.a.b where P is a package and a is a package constant,
465+ // since a will not be instantiated and thus we will fail when looking for b.
434466 scope := match node
435467 case InstNode . CLASS_NODE ()
436468 then InstNode . getClass(Inst . expand(node));
@@ -439,20 +471,21 @@ algorithm
439471 then InstNode . getClass(node);
440472 end match;
441473
442- (node, state) := match cref
474+ (node, nodes, state) := match cref
443475 case Absyn . ComponentRef . CREF_IDENT ()
444476 algorithm
445477 node := Class . lookupElement(cref. name, scope);
446478 state := LookupState . next(node, state);
447479 then
448- (node, state);
480+ (node, {node}, state);
449481
450482 case Absyn . ComponentRef . CREF_QUAL ()
451483 algorithm
452- node := Class . lookupElement(cref. name, scope);
453- state := LookupState . next(node, state);
484+ n := Class . lookupElement(cref. name, scope);
485+ state := LookupState . next(n, state);
486+ (node, nodes, state) := lookupCrefInNode(cref. componentRef, n, state);
454487 then
455- lookupCrefInNode(cref . componentRef, node , state);
488+ (node, n :: nodes , state);
456489
457490 end match;
458491end lookupCrefInNode;
0 commit comments