@@ -46,6 +46,7 @@ import NFInstNode.InstNode;
46
46
import NFLookupState.LookupState ;
47
47
import NFPrefix.Prefix ;
48
48
import Type = NFType ;
49
+ import NFMod.Modifier ;
49
50
50
51
type MatchType = enumeration(FOUND , NOT_FOUND , PARTIAL );
51
52
@@ -79,11 +80,12 @@ function lookupComponent
79
80
input SourceInfo info;
80
81
input Boolean allowTypename = false ;
81
82
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." ;
83
85
protected
84
86
LookupState state;
85
87
algorithm
86
- (foundComponent, prefix , state) := lookupCref(cref, scope, info);
88
+ (foundComponent, restNodes, foundScope , state) := lookupCref(cref, scope, info);
87
89
88
90
if allowTypename then
89
91
state := fixTypenameState(foundComponent, state);
@@ -114,48 +116,55 @@ function lookupFunctionName
114
116
input InstNode scope "The scope to look in." ;
115
117
input SourceInfo info;
116
118
output InstNode func ;
117
- output Prefix prefix ;
119
+ output InstNode foundScope ;
118
120
protected
119
121
LookupState state;
120
122
algorithm
121
- (func , prefix , state) := lookupCref(cref, scope, info);
123
+ (func , _, foundScope , state) := lookupCref(cref, scope, info);
122
124
LookupState . assertFunction(state, func , cref, info);
123
125
end lookupFunctionName;
124
126
125
127
function 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."
126
133
input Absyn . ComponentRef cref;
127
134
input InstNode scope "The scope to look in." ;
128
135
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." ;
131
139
output LookupState state;
132
140
protected
133
141
MatchType match_ty;
142
+ InstNode n;
134
143
algorithm
135
- (node, prefix , state, match_ty) := lookupBuiltinCref(cref, info);
144
+ (node, restNodes , state, match_ty) := lookupBuiltinCref(cref, info);
136
145
137
146
if match_ty == MatchType . NOT_FOUND then
138
147
match_ty := MatchType . FOUND ;
139
148
140
- (node, prefix , state) := matchcontinue cref
149
+ (node, restNodes, foundScope , state) := matchcontinue cref
141
150
local
142
151
Class . Element element;
143
152
InstNode found_scope;
144
153
145
154
case Absyn . ComponentRef . CREF_IDENT ()
146
155
algorithm
147
- (node, prefix ) := lookupSimpleCref(cref. name, scope);
156
+ (node, foundScope ) := lookupSimpleCref(cref. name, scope);
148
157
state := LookupState . nodeState(node);
149
158
then
150
- (node, prefix , state);
159
+ (node, {node}, foundScope , state);
151
160
152
161
case Absyn . ComponentRef . CREF_QUAL ()
153
162
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);
157
166
then
158
- (node, prefix , state);
167
+ (node, n :: restNodes, foundScope , state);
159
168
160
169
case Absyn . ComponentRef . CREF_FULLYQUALIFIED ()
161
170
then lookupCref(cref. componentRef, InstNode . topComponent(scope), info);
@@ -164,8 +173,10 @@ algorithm
164
173
algorithm
165
174
match_ty := MatchType . NOT_FOUND ;
166
175
then
167
- (InstNode . EMPTY_NODE (), Prefix . NO_PREFIX () , LookupState . STATE_BEGIN ());
176
+ (InstNode . EMPTY_NODE (), {}, scope , LookupState . STATE_BEGIN ());
168
177
end matchcontinue;
178
+ else
179
+ foundScope := scope;
169
180
end if ;
170
181
171
182
if match_ty <> MatchType . FOUND then
@@ -181,7 +192,7 @@ function lookupBuiltinCref
181
192
input Absyn . ComponentRef cref;
182
193
input SourceInfo info;
183
194
output InstNode node;
184
- output Prefix prefix = Prefix . NO_PREFIX () ;
195
+ output list < InstNode > restNodes ;
185
196
output LookupState state = LookupState . STATE_PREDEF_COMP ();
186
197
output MatchType matchType = MatchType . FOUND ;
187
198
protected
@@ -190,39 +201,62 @@ protected
190
201
algorithm
191
202
cr := Absyn . unqualifyCref(cref);
192
203
193
- node := match cr
194
- local
195
-
204
+ (node, restNodes) := match cr
196
205
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});
203
219
204
220
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 ();
217
245
end match;
218
246
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);
226
260
227
261
end match;
228
262
end lookupBuiltinCref;
@@ -385,9 +419,8 @@ function lookupSimpleCref
385
419
input String name;
386
420
input InstNode scope;
387
421
output InstNode node;
388
- output Prefix prefix ;
422
+ output InstNode foundScope = scope ;
389
423
protected
390
- InstNode foundScope = scope;
391
424
Class cls;
392
425
Class . Element e;
393
426
algorithm
@@ -400,14 +433,7 @@ algorithm
400
433
cls := InstNode . getClass(foundScope);
401
434
node := Class . lookupElement(name, cls);
402
435
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.
411
437
return ;
412
438
else
413
439
// Look in the next enclosing scope.
@@ -423,14 +449,20 @@ end lookupSimpleCref;
423
449
function lookupCrefInNode
424
450
input Absyn . ComponentRef cref;
425
451
input output InstNode node;
452
+ output list< InstNode > nodes;
426
453
input output LookupState state;
427
454
protected
428
455
Class scope;
456
+ InstNode n;
429
457
algorithm
430
458
if LookupState . isError(state) then
431
459
return ;
432
460
end if ;
433
461
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.
434
466
scope := match node
435
467
case InstNode . CLASS_NODE ()
436
468
then InstNode . getClass(Inst . expand(node));
@@ -439,20 +471,21 @@ algorithm
439
471
then InstNode . getClass(node);
440
472
end match;
441
473
442
- (node, state) := match cref
474
+ (node, nodes, state) := match cref
443
475
case Absyn . ComponentRef . CREF_IDENT ()
444
476
algorithm
445
477
node := Class . lookupElement(cref. name, scope);
446
478
state := LookupState . next(node, state);
447
479
then
448
- (node, state);
480
+ (node, {node}, state);
449
481
450
482
case Absyn . ComponentRef . CREF_QUAL ()
451
483
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);
454
487
then
455
- lookupCrefInNode(cref . componentRef, node , state);
488
+ (node, n :: nodes , state);
456
489
457
490
end match;
458
491
end lookupCrefInNode;
0 commit comments