Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 59.5% 150 / 0 / 252
Functions: -% 0 / 1 / 1
Branches: 48.9% 22 / 0 / 45

OMCompiler/Compiler/FrontEnd/PrefixUtil.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package PrefixUtil
37 " file: PrefixUtil.mo
38 package: PrefixUtil
39 description: PrefixUtil management
40
41
42 When instantiating an expression, there is a prefix that
43 has to be added to each variable name to be able to use it in the
44 flattened equation set.
45
46 A prefix for a variable x could be for example a.b.c so that the
47 fully qualified name is a.b.c.x."
48
49
50 public import Absyn;
51 public import AbsynUtil;
52 public import DAE;
53 public import File;
54 public import FCore;
55 public import FGraph;
56 public import Lookup;
57 public import SCode;
58 public import InnerOuter;
59 public import ClassInf;
60
61 protected
62
63 type InstanceHierarchy = InnerOuter.InstHierarchy "an instance hierarchy";
64
65 import ComponentReference;
66 protected import ComponentReferenceBasics;
67 import Config;
68 import Error;
69 import Expression;
70 protected import ExpressionBasics;
71 import ExpressionDump;
72 import Flags;
73 import List;
74 import Print;
75 //import Util;
76 import System;
77 import Types;
78 import MetaModelica.Dangerous;
79
80 public function printComponentPrefixStr "Prints a Prefix to a string. Rather slow..."
81 input DAE.ComponentPrefix pre;
82 output String outString;
83 algorithm
84 outString := match pre
85 local
86
87 case DAE.NOCOMPPRE() then "<Prefix.NOCOMPPRE()>";
88 ✗ case DAE.PRE(next=DAE.NOCOMPPRE(), subscripts={}) then pre.prefix;
89 ✗ case DAE.PRE(next=DAE.NOCOMPPRE()) then pre.prefix + "[" + ExpressionDump.printSubscriptLstStr(pre.subscripts) + "]";
90 ✗ case DAE.PRE(subscripts={}) then printComponentPrefixStr(pre.next)+"."+pre.prefix;
91 ✗ case DAE.PRE() then printComponentPrefixStr(pre.next)+"."+pre.prefix + "[" + ExpressionDump.printSubscriptLstStr(pre.subscripts) + "]";
92 end match;
93 end printComponentPrefixStr;
94
95 public function printPrefixStr "Prints a Prefix to a string."
96 input DAE.Prefix inPrefix;
97 output String outString;
98 algorithm
99 outString := matchcontinue inPrefix
100 local
101 String str,s,rest_1,s_1,s_2;
102 DAE.ComponentPrefix rest;
103 DAE.ClassPrefix cp;
104 list<DAE.Subscript> ss;
105
106 case DAE.NOPRE() then "<Prefix.NOPRE()>";
107 case DAE.PREFIX(DAE.NOCOMPPRE(),_) then "<Prefix.PREFIX(DAE.NOCOMPPRE())>";
108 case DAE.PREFIX(DAE.PRE(str,_,{},DAE.NOCOMPPRE(),_,_),_) then str;
109 case DAE.PREFIX(DAE.PRE(str,_,ss,DAE.NOCOMPPRE(),_,_),_)
110 algorithm
111 1 s := stringAppend(str, "[" + stringDelimitList(
112 List.map(ss, ExpressionDump.subscriptString), ", ") + "]");
113 then
114 s;
115 case DAE.PREFIX(DAE.PRE(str,_,{},rest,_,_),cp)
116 algorithm
117 2 rest_1 := printPrefixStr(DAE.PREFIX(rest,cp));
118 2 s := stringAppend(rest_1, ".");
119 2 s_1 := stringAppend(s, str);
120 then
121 s_1;
122 case DAE.PREFIX(DAE.PRE(str,_,ss,rest,_,_),cp)
123 algorithm
124 ✗ rest_1 := printPrefixStr(DAE.PREFIX(rest,cp));
125 ✗ s := stringAppend(rest_1, ".");
126 ✗ s_1 := stringAppend(s, str);
127 ✗ s_2 := stringAppend(s_1, "[" + stringDelimitList(
128 List.map(ss, ExpressionDump.subscriptString), ", ") + "]");
129 then
130 s_2;
131 end matchcontinue;
132 end printPrefixStr;
133
134 public function printPrefixStr2 "Prints a Prefix to a string. Designed to be used in Error messages to produce qualified component names"
135 input DAE.Prefix inPrefix;
136 output String outString;
137 algorithm
138 outString := match inPrefix
139 local
140 DAE.Prefix p;
141 case DAE.NOPRE() then "";
142 case DAE.PREFIX(DAE.NOCOMPPRE(),_) then "";
143 1 case p then printPrefixStr(p)+".";
144 end match;
145 end printPrefixStr2;
146
147 public function printPrefixStr3 "Prints a Prefix to a string as a component name. Designed to be used in Error messages"
148 input DAE.Prefix inPrefix;
149 output String outString;
150 algorithm
151 outString := match inPrefix
152 local
153 DAE.Prefix p;
154 case DAE.NOPRE() then "<NO COMPONENT>";
155 case DAE.PREFIX(DAE.NOCOMPPRE(),_) then "<NO COMPONENT>";
156 14 case p then printPrefixStr(p);
157 end match;
158 end printPrefixStr3;
159
160 public function printPrefixStrIgnoreNoPre "Prints a Prefix to a string as a component name. Designed to be used in Error messages"
161 input DAE.Prefix inPrefix;
162 output String outString;
163 algorithm
164 outString := match inPrefix
165 local
166 DAE.Prefix p;
167 case DAE.NOPRE() then "";
168 case DAE.PREFIX(DAE.NOCOMPPRE(),_) then "";
169 26 case p then printPrefixStr(p);
170 end match;
171 end printPrefixStrIgnoreNoPre;
172
173 public function printPrefix "Prints a prefix to the Print buffer."
174 input DAE.Prefix p;
175 protected
176 String s;
177 algorithm
178 ✗ s := printPrefixStr(p);
179 ✗ Print.printBuf(s);
180 end printPrefix;
181
182 public function prefixAdd "This function is used to extend a prefix with another level. If
183 the prefix `a.b{10}.c\' is extended with `d\' and an empty subscript
184 list, the resulting prefix is `a.b{10}.c.d\'. Remember that
185 prefixes components are stored in the opposite order from the
186 normal order used when displaying them."
187 input String inIdent;
188 input list<DAE.Dimension> inType;
189 input list<DAE.Subscript> inIntegerLst;
190 input DAE.Prefix inPrefix;
191 input SCode.Variability vt;
192 input ClassInf.State ci_state;
193 input SourceInfo inInfo;
194 output DAE.Prefix outPrefix;
195 algorithm
196 outPrefix := match (inIdent, inIntegerLst, inPrefix)
197 local
198 String i;
199 list<DAE.Subscript> s;
200 DAE.ComponentPrefix p;
201
202 case (i, s, DAE.PREFIX(p,_))
203 403699 then DAE.PREFIX(DAE.PRE(i,inType,s,p,ci_state,inInfo),DAE.CLASSPRE(vt));
204
205 case(i, s, DAE.NOPRE())
206 361989 then DAE.PREFIX(DAE.PRE(i,inType,s,DAE.NOCOMPPRE(),ci_state,inInfo),DAE.CLASSPRE(vt));
207 end match;
208 end prefixAdd;
209
210 public function prefixFirst
211 input DAE.Prefix inPrefix;
212 output DAE.Prefix outPrefix;
213 algorithm
214 outPrefix := match inPrefix
215 local
216 String a;
217 list<DAE.Subscript> b;
218 DAE.ClassPrefix cp;
219 ClassInf.State ci_state;
220 list<DAE.Dimension> pdims;
221 SourceInfo info;
222
223 case DAE.PREFIX(DAE.PRE(prefix = a, dimensions = pdims, subscripts = b,ci_state=ci_state, info = info),cp)
224 ✗ then DAE.PREFIX(DAE.PRE(a,pdims,b,DAE.NOCOMPPRE(),ci_state,info),cp);
225 end match;
226 end prefixFirst;
227
228 public function prefixFirstCref
229 "Returns the first cref in the prefix."
230 input DAE.Prefix inPrefix;
231 output DAE.ComponentRef outCref;
232 protected
233 String name;
234 list<DAE.Subscript> subs;
235 algorithm
236
3/4
✓ Branch 0 taken 379752 times.
✓ Branch 1 taken 544025 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 544025 times.
923777 DAE.PREFIX(compPre = DAE.PRE(prefix = name, subscripts = subs)) := inPrefix;
237 544025 outCref := DAE.CREF_IDENT(name, DAE.T_UNKNOWN_DEFAULT, subs);
238 end prefixFirstCref;
239
240 public function prefixLast "Returns the last NONPRE Prefix of a prefix"
241 input DAE.Prefix inPrefix;
242 output DAE.Prefix outPrefix;
243 algorithm
244 outPrefix := match inPrefix
245 local
246 DAE.ComponentPrefix p;
247 DAE.Prefix res;
248 DAE.ClassPrefix cp;
249
250 case res as DAE.PREFIX(DAE.PRE(next = DAE.NOCOMPPRE()),_) then res;
251
252 case DAE.PREFIX(DAE.PRE(next = p),cp)
253 algorithm
254 ✗ res := prefixLast(DAE.PREFIX(p,cp));
255 then
256 res;
257 end match;
258 end prefixLast;
259
260 public function prefixStripLast
261 "@author: adrpo
262 remove the last prefix from the component prefix"
263 input DAE.Prefix inPrefix;
264 output DAE.Prefix outPrefix;
265 algorithm
266 outPrefix := match inPrefix
267 local
268 DAE.ClassPrefix cp;
269 DAE.ComponentPrefix compPre;
270 // we can't remove what it isn't there!
271 case DAE.NOPRE() then DAE.NOPRE();
272 // if there isn't any next prefix, return DAE.NOPRE!
273 case DAE.PREFIX(compPre,cp)
274 algorithm
275 1681 compPre := compPreStripLast(compPre);
276 1681 then DAE.PREFIX(compPre,cp);
277 end match;
278 end prefixStripLast;
279
280 protected function compPreStripLast
281 "@author: adrpo
282 remove the last prefix from the component prefix"
283 input DAE.ComponentPrefix inCompPrefix;
284 output DAE.ComponentPrefix outCompPrefix;
285 algorithm
286 outCompPrefix := match inCompPrefix
287 local
288 DAE.ComponentPrefix next;
289
290 // nothing to remove!
291 case DAE.NOCOMPPRE() then DAE.NOCOMPPRE();
292 // we have something
293 case DAE.PRE(next = next) then next;
294 end match;
295 end compPreStripLast;
296
297 public function prefixPath "Prefix a Path variable by adding the supplied
298 prefix to it and returning a new Path."
299 input Absyn.Path inPath;
300 input DAE.Prefix inPrefix;
301 output Absyn.Path outPath;
302 algorithm
303 outPath := match (inPath,inPrefix)
304 local
305 Absyn.Path p,p_1;
306 String s;
307 DAE.ComponentPrefix ss;
308 DAE.ClassPrefix cp;
309
310 case (p,DAE.NOPRE()) then p;
311 case (p,DAE.PREFIX(DAE.PRE(prefix = s,next = DAE.NOCOMPPRE()),_))
312 algorithm
313 13 p_1 := Absyn.QUALIFIED(s,p);
314 then p_1;
315 case (p,DAE.PREFIX(DAE.PRE(prefix = s,next = ss),cp))
316 algorithm
317 7 p_1 := prefixPath(Absyn.QUALIFIED(s,p), DAE.PREFIX(ss,cp));
318 then p_1;
319 end match;
320 end prefixPath;
321
322 public function prefixToPath "Convert a Prefix to a Path"
323 input DAE.Prefix inPrefix;
324 output Absyn.Path outPath;
325 algorithm
326 outPath := match inPrefix
327 local
328 DAE.ComponentPrefix ss;
329 768228 case DAE.PREFIX(ss,_) then componentPrefixToPath(ss);
330 end match;
331 end prefixToPath;
332
333 public function identAndPrefixToPath "Convert a Ident/Prefix to a String"
334 input String ident;
335 input DAE.Prefix inPrefix;
336 output String str;
337 algorithm
338 20 str := AbsynUtil.pathString(PrefixUtil.prefixPath(Absyn.IDENT(ident),inPrefix));
339 end identAndPrefixToPath;
340
341 public function componentPrefixToPath "Convert a Prefix to a Path"
342 input DAE.ComponentPrefix pre;
343 output Absyn.Path path;
344 algorithm
345 path := match pre
346 local
347 String s;
348 DAE.ComponentPrefix ss;
349 case DAE.PRE(prefix = s,next = DAE.NOCOMPPRE())
350 768228 then Absyn.IDENT(s);
351 case DAE.PRE(prefix = s,next = ss)
352 888175 then Absyn.QUALIFIED(s,componentPrefixToPath(ss));
353 end match;
354 end componentPrefixToPath;
355
356 public function prefixCref "Prefix a ComponentRef variable by adding the supplied prefix to
357 it and returning a new ComponentRef.
358 LS: Changed to call prefixToCref which is more general now"
359 input FCore.Cache cache;
360 input FCore.Graph env;
361 input InnerOuter.InstHierarchy inIH;
362 input DAE.Prefix pre;
363 input DAE.ComponentRef cref;
364 output FCore.Cache outCache;
365 output DAE.ComponentRef cref_1;
366 algorithm
367 2938870 (outCache,cref_1) := prefixToCref2(cache,env,inIH,pre, SOME(cref));
368 end prefixCref;
369
370 public function prefixCrefNoContext "Prefix a ComponentRef variable by adding the supplied prefix to
371 it and returning a new ComponentRef.
372 LS: Changed to call prefixToCref which is more general now"
373 input DAE.Prefix inPre;
374 input DAE.ComponentRef inCref;
375 output DAE.ComponentRef outCref;
376 algorithm
377 169 (_, outCref) := prefixToCref2(FCore.noCache(), FGraph.empty(), InnerOuter.emptyInstHierarchy, inPre, SOME(inCref));
378 end prefixCrefNoContext;
379
380 public function prefixToCref "Convert a prefix to a component reference."
381 input DAE.Prefix pre;
382 output DAE.ComponentRef cref_1;
383 algorithm
384 25 (_,cref_1) := prefixToCref2(FCore.noCache(), FGraph.empty(), InnerOuter.emptyInstHierarchy, pre, NONE());
385 end prefixToCref;
386
387 protected function prefixToCref2 "Convert a prefix to a component reference. Converting DAE.NOPRE with no
388 component reference is an error because a component reference cannot be
389 empty"
390 input FCore.Cache inCache;
391 input FCore.Graph inEnv;
392 input InstanceHierarchy inIH;
393 input DAE.Prefix inPrefix;
394 input Option<DAE.ComponentRef> inExpComponentRefOption;
395 output FCore.Cache outCache;
396 output DAE.ComponentRef outComponentRef;
397 algorithm
398 (outCache,outComponentRef) := match (inCache, inEnv, inPrefix, inExpComponentRefOption)
399 local
400 DAE.ComponentRef cref,cref_1,cref_2,cref_;
401 String i;
402 list<DAE.Subscript> s;
403 list<DAE.Dimension> ds;
404 DAE.Type ident_ty;
405 DAE.ComponentPrefix xs;
406 DAE.ClassPrefix cp;
407 ClassInf.State ci_state;
408 FCore.Cache cache;
409 FCore.Graph env;
410
411 ✗ case (_, _, DAE.NOPRE(), NONE()) then fail();
412 ✗ case (_, _, DAE.PREFIX(DAE.NOCOMPPRE(),_), NONE()) then fail();
413
414 case (cache, _, DAE.NOPRE(), SOME(cref)) then (cache,cref);
415 case (cache, _, DAE.PREFIX(DAE.NOCOMPPRE(),_), SOME(cref)) then (cache,cref);
416 case (cache, env, DAE.PREFIX(DAE.PRE(prefix = i,dimensions=ds,subscripts = s,next = xs,ci_state=ci_state),cp), NONE())
417 algorithm
418 25 ident_ty := Expression.liftArrayLeftList(DAE.T_COMPLEX(ci_state, {}, NONE(), false), ds);
419 25 cref_ := ComponentReferenceBasics.makeCrefIdent(i,ident_ty,s);
420 1891037 (cache,cref_1) := prefixToCref2(cache,env,inIH,DAE.PREFIX(xs,cp), SOME(cref_));
421 then
422 (cache,cref_1);
423 case (cache, env, DAE.PREFIX(DAE.PRE(prefix = i,dimensions=ds,subscripts = s,next = xs,ci_state=ci_state),cp), SOME(cref))
424 algorithm
425 1890987 (cache,cref) := prefixSubscriptsInCref(cache,env,inIH,inPrefix,cref);
426 1890987 ident_ty := Expression.liftArrayLeftList(DAE.T_COMPLEX(ci_state, {}, NONE(), false), ds);
427 1890987 cref_2 := ComponentReferenceBasics.makeCrefQual(i,ident_ty,s,cref);
428 3781974 (cache,cref_1) := prefixToCref2(cache,env,inIH,DAE.PREFIX(xs,cp), SOME(cref_2));
429 then
430 (cache,cref_1);
431 end match;
432 end prefixToCref2;
433
434 public function prefixToCrefOpt "Convert a prefix to an optional component reference."
435 input DAE.Prefix pre;
436 output Option<DAE.ComponentRef> cref_1;
437 algorithm
438 ✗ cref_1 := prefixToCrefOpt2(pre, NONE());
439 end prefixToCrefOpt;
440
441 public function prefixToCrefOpt2 "Convert a prefix to a component reference. Converting DAE.NOPRE with no
442 component reference gives a NONE"
443 input DAE.Prefix inPrefix;
444 input Option<DAE.ComponentRef> inExpComponentRefOption;
445 output Option<DAE.ComponentRef> outComponentRefOpt;
446 algorithm
447 outComponentRefOpt := match (inPrefix,inExpComponentRefOption)
448 local
449 Option<DAE.ComponentRef> cref_1;
450 DAE.ComponentRef cref,cref_;
451 String i;
452 list<DAE.Subscript> s;
453 DAE.ComponentPrefix xs;
454 DAE.ClassPrefix cp;
455
456 case (DAE.NOPRE(),NONE()) then NONE();
457 case (DAE.NOPRE(),SOME(cref)) then SOME(cref);
458 case (DAE.PREFIX(DAE.NOCOMPPRE(),_),SOME(cref)) then SOME(cref);
459 case (DAE.PREFIX(DAE.PRE(prefix = i,subscripts = s,next = xs),cp),NONE())
460 algorithm
461 ✗ cref_ := ComponentReferenceBasics.makeCrefIdent(i,DAE.T_COMPLEX(ClassInf.UNKNOWN(Absyn.IDENT("")), {}, NONE(), false),s);
462 ✗ cref_1 := prefixToCrefOpt2(DAE.PREFIX(xs,cp), SOME(cref_));
463 then
464 cref_1;
465 case (DAE.PREFIX(DAE.PRE(prefix = i,subscripts = s,next = xs),cp),SOME(cref))
466 algorithm
467 ✗ cref_ := ComponentReferenceBasics.makeCrefQual(i,DAE.T_COMPLEX(ClassInf.UNKNOWN(Absyn.IDENT("")), {}, NONE(), false),s,cref);
468 ✗ cref_1 := prefixToCrefOpt2(DAE.PREFIX(xs,cp), SOME(cref_));
469 then
470 cref_1;
471 end match;
472 end prefixToCrefOpt2;
473
474 public function makeCrefFromPrefixNoFail
475 "@author:adrpo
476 Similar to prefixToCref but it doesn't fail for NOPRE or NOCOMPPRE,
477 it will just create an empty cref in these cases"
478 input DAE.Prefix pre;
479 output DAE.ComponentRef cref;
480 algorithm
481 cref := match pre
482 local
483 DAE.ComponentRef c;
484
485 case DAE.NOPRE()
486 algorithm
487 ✗ c := ComponentReferenceBasics.makeCrefIdent("", DAE.T_UNKNOWN_DEFAULT, {});
488 then
489 c;
490
491 case DAE.PREFIX(DAE.NOCOMPPRE(), _)
492 algorithm
493 ✗ c := ComponentReferenceBasics.makeCrefIdent("", DAE.T_UNKNOWN_DEFAULT, {});
494 then
495 c;
496
497 case _
498 algorithm
499 ✗ c := prefixToCref(pre);
500 then
501 c;
502 end match;
503 end makeCrefFromPrefixNoFail;
504
505 protected function prefixSubscriptsInCref "help function to prefixToCrefOpt2, deals with prefixing expressions in subscripts"
506 input FCore.Cache inCache;
507 input FCore.Graph inEnv;
508 input InstanceHierarchy inIH;
509 input DAE.Prefix pre;
510 input DAE.ComponentRef inCr;
511 output FCore.Cache outCache;
512 output DAE.ComponentRef outCr;
513 algorithm
514 1891318 (outCache,outCr) := prefixSubscriptsInCrefWork(inCache,inEnv,inIH,pre,inCr,{});
515 end prefixSubscriptsInCref;
516
517 protected function prefixSubscriptsInCrefWork "help function to prefixToCrefOpt2, deals with prefixing expressions in subscripts"
518 input FCore.Cache inCache;
519 input FCore.Graph inEnv;
520 input InstanceHierarchy inIH;
521 input DAE.Prefix pre;
522 input DAE.ComponentRef inCr;
523 input list<DAE.ComponentRef> acc;
524 output FCore.Cache outCache;
525 output DAE.ComponentRef outCr;
526 algorithm
527 (outCache,outCr) := match (inCache, inEnv, inCr)
528 local
529 DAE.Ident id;
530 DAE.Type tp;
531 list<DAE.Subscript> subs;
532 FCore.Cache cache;
533 FCore.Graph env;
534 DAE.ComponentRef cr,crid;
535 case(cache, env, DAE.CREF_IDENT(id,tp,subs))
536 algorithm
537 1891318 (cache,subs) := prefixSubscripts(cache,env,inIH,pre,subs);
538 1891318 cr := ComponentReferenceBasics.makeCrefIdent(id,tp,subs);
539 1891318 then (cache,ComponentReference.implode_reverse(cr::acc));
540 case(cache, env, DAE.CREF_QUAL(id,tp,subs,cr))
541 algorithm
542 1238490 (cache,subs) := prefixSubscripts(cache,env,inIH,pre,subs);
543 1238490 crid := ComponentReferenceBasics.makeCrefIdent(id,tp,subs);
544 1238490 (cache,cr) := prefixSubscriptsInCrefWork(cache,env,inIH,pre,cr,crid::acc);
545 then (cache,cr);
546 case(cache, _, DAE.WILD()) then (cache,DAE.WILD());
547 end match;
548 end prefixSubscriptsInCrefWork;
549
550 protected function prefixSubscripts "help function to prefixSubscriptsInCref, adds prefix to subscripts"
551 input FCore.Cache inCache;
552 input FCore.Graph inEnv;
553 input InstanceHierarchy inIH;
554 input DAE.Prefix pre;
555 input list<DAE.Subscript> inSubs;
556 output FCore.Cache outCache;
557 output list<DAE.Subscript> outSubs;
558 algorithm
559 (outCache,outSubs) := match(inCache, inEnv, inSubs)
560 local
561 DAE.Subscript sub;
562 FCore.Cache cache;
563 FCore.Graph env;
564 list<DAE.Subscript> subs;
565
566 case (cache, _, {}) then (cache,{});
567
568 case (cache, env, sub::subs)
569 algorithm
570 851696 (cache,sub) := prefixSubscript(cache,env,inIH,pre,sub);
571 851696 (cache,subs) := prefixSubscripts(cache,env,inIH,pre,subs);
572 851696 then (cache,sub::subs);
573 end match;
574 end prefixSubscripts;
575
576 protected function prefixSubscript "help function to prefixSubscripts, adds prefix to one subscript, if it is an expression"
577 input FCore.Cache inCache;
578 input FCore.Graph inEnv;
579 input InstanceHierarchy inIH;
580 input DAE.Prefix pre;
581 input DAE.Subscript sub;
582 output FCore.Cache outCache;
583 output DAE.Subscript outSub;
584 algorithm
585 (outCache,outSub) := match(inCache, inEnv, sub)
586 local
587 DAE.Exp exp;
588 FCore.Cache cache;
589 FCore.Graph env;
590
591 case(cache, _, DAE.WHOLEDIM()) then (cache,DAE.WHOLEDIM());
592
593 case(cache, env, DAE.SLICE(exp)) algorithm
594 ✗ (cache,exp) := prefixExpWork(cache,env,inIH,exp,pre);
595 ✗ then (cache,DAE.SLICE(exp));
596
597 case(cache, env, DAE.WHOLE_NONEXP(exp)) algorithm
598 ✗ (cache,exp) := prefixExpWork(cache,env,inIH,exp,pre);
599 ✗ then (cache,DAE.WHOLE_NONEXP(exp));
600
601 case(cache, env, DAE.INDEX(exp)) algorithm
602 851633 (cache,exp) := prefixExpWork(cache,env,inIH,exp,pre);
603 851633 then (cache,DAE.INDEX(exp));
604
605 end match;
606 end prefixSubscript;
607
608 public function prefixCrefInnerOuter "Search for the prefix of the inner when the cref is
609 an outer and add that instead of the given prefix!
610 If the cref is an inner, prefix it normally."
611 input FCore.Cache inCache;
612 input FCore.Graph inEnv;
613 input InnerOuter.InstHierarchy inIH;
614 input DAE.ComponentRef inCref;
615 input DAE.Prefix inPrefix;
616 output FCore.Cache outCache;
617 output DAE.ComponentRef outCref;
618 algorithm
619 (outCache,outCref) := match (inCache, inIH, inCref, inPrefix)
620 local
621 FCore.Cache cache;
622 InstanceHierarchy ih;
623 DAE.Prefix pre;
624 DAE.ComponentRef cref, newCref;
625
626
627 case (cache, ih, cref, pre)
628 algorithm
629 32939 newCref := InnerOuter.prefixOuterCrefWithTheInnerPrefix(ih, cref, pre);
630 then
631 (cache,newCref);
632
633 /*
634 // adrpo: prefix normally if we have an inner outer variable!
635 case (cache,env,ih,cref,pre)
636 algorithm
637 (cache,DAE.ATTR(innerOuter = io),_,_,_,_) = Lookup.lookupVarLocal(cache, env, cref);
638 // fprintln(Flags.INNER_OUTER, printPrefixStr(inPrefix) + "/" + ComponentReferenceBasics.printComponentRefStr(cref) +
639 // if_(AbsynUtil.isOuter(io), " [outer] ", " ") +
640 // if_(AbsynUtil.isInner(io), " [inner] ", " "));
641 true = AbsynUtil.isInner(io);
642 false = AbsynUtil.isOuter(io);
643 // prefix normally
644 newCref = prefixCref(pre, cref);
645 // fprintln(Flags.INNER_OUTER, "INNER normally prefixed: " + ComponentReferenceBasics.printComponentRefStr(newCref));
646 then
647 (cache,newCref);
648
649 // adrpo: prefix with *CORRECT* prefix from inner if we have an outer variable!
650 case (cache,env,ih,cref as DAE.CREF_IDENT(ident=_),pre)
651 algorithm
652 (cache,DAE.ATTR(innerOuter = io),_,_,_,_) = Lookup.lookupVarLocal(cache, env, cref);
653 // fprintln(Flags.INNER_OUTER, printPrefixStr(inPrefix) + "/" + ComponentReferenceBasics.printComponentRefStr(cref) +
654 // if_(AbsynUtil.isOuter(io), " [outer] ", " ") +
655 // if_(AbsynUtil.isInner(io), " [inner] ", " "));
656 true = AbsynUtil.isOuter(io);
657 n = ComponentReferenceBasics.crefLastIdent(cref);
658 lastCref = Expression.crefIdent(cref);
659 // search in the instance hierarchy for the *CORRECT* prefix for this outer variable!
660 InnerOuter.INST_INNER(innerPrefix=innerPrefix, instResult=SOME(_)) =
661 InnerOuter.lookupInnerVar(cache, env, ih, pre, n, io);
662 // prefix the cref with the prefix of the INNER!
663
664 newCref = prefixCref(innerPrefix, lastCref);
665
666 // fprintln(Flags.INNER_OUTER, "OUTER IDENT prefixed INNER : " + ComponentReferenceBasics.printComponentRefStr(newCref));
667 then
668 (cache,newCref);
669
670 // adrpo: we have a qualified cref, search for the prefix!
671 // bar2/world.someCrap
672 case (cache,env,ih,cref as DAE.CREF_QUAL(ident=_),pre)
673 algorithm
674 (cache,DAE.ATTR(innerOuter = io),_,_,_,_) = Lookup.lookupVarLocal(cache, env, cref);
675 true = AbsynUtil.isOuter(io);
676 (cache,innerPrefix) = searchForInnerPrefix(cache,env,ih,cref,pre,io);
677 newCref = prefixCref(innerPrefix, cref);
678 // fprintln(Flags.INNER_OUTER, "OUTER QUAL prefixed INNER: " + ComponentReferenceBasics.printComponentRefStr(newCref));
679 then
680 (cache,newCref);
681 */
682 end match;
683 end prefixCrefInnerOuter;
684
685 public function prefixExp "Add the supplied prefix to all component references in an expression."
686 input output FCore.Cache cache;
687 input FCore.Graph env;
688 input InnerOuter.InstHierarchy ih;
689 input output DAE.Exp exp;
690 input DAE.Prefix pre;
691 algorithm
692 try
693 1193054 (cache, exp) := prefixExpWork(cache, env, ih, exp, pre);
694 else
695 ✗ Error.addInternalError(getInstanceName() + " failed on exp: " + ExpressionBasics.printExpStr(exp) + " " + makePrefixString(pre), sourceInfo());
696 ✗ fail();
697 end try;
698 end prefixExp;
699
700 protected function prefixExpWork "Add the supplied prefix to all component references in an expression."
701 input output FCore.Cache cache;
702 input FCore.Graph env;
703 input InnerOuter.InstHierarchy ih;
704 input DAE.Exp inExp;
705 input DAE.Prefix pre;
706 output DAE.Exp outExp;
707 algorithm
708 (cache,outExp) := match (inExp,pre)
709 local
710 DAE.Exp e,e1_1,e2_1,e1,e2,e3_1,e3,cref_1,dim_1,cref,dim,start_1,stop_1,start,stop,step_1,step,e_1,exp_1,exp,crefExp;
711 DAE.ComponentRef cr,cr_1;
712 DAE.Operator o;
713 list<DAE.Exp> es_1,es;
714 Absyn.Path f;
715 Boolean sc;
716 list<DAE.Exp> x_1,x;
717 list<list<DAE.Exp>> xs_1,xs;
718 list<DAE.Exp> expl;
719 Integer a;
720 DAE.Type t,tp;
721 Integer index_;
722 Option<tuple<DAE.Exp,Integer,Integer>> isExpisASUB;
723 DAE.ReductionInfo reductionInfo;
724 DAE.ReductionIterators riters;
725 DAE.CallAttributes attr;
726 list<String> fieldNames;
727 DAE.ClockKind clk;
728 list<DAE.Subscript> subs;
729
730 // no prefix, return the input expression
731 case (e,DAE.NOPRE())
732 guard not System.getHasInnerOuterDefinitions()
733 then (cache,e);
734
735 // handle literal constants
736 case ((e as DAE.ICONST()),_) then (cache,e);
737 case ((e as DAE.RCONST()),_) then (cache,e);
738 case ((e as DAE.SCONST()),_) then (cache,e);
739 case ((e as DAE.BCONST()),_) then (cache,e);
740 case ((e as DAE.ENUM_LITERAL()), _) then (cache, e);
741
742 // adrpo: handle prefixing of inner/outer variables
743 case (DAE.CREF(componentRef = cr,ty = t),_)
744 algorithm
745
4/4
✓ Branch 1 taken 263380 times.
✓ Branch 2 taken 8950 times.
✓ Branch 3 taken 104752 times.
✓ Branch 4 taken 158628 times.
272330 if System.getHasInnerOuterDefinitions() and not listEmpty(ih) then
746 try
747 104752 cr_1 := InnerOuter.prefixOuterCrefWithTheInnerPrefix(ih, cr, pre);
748 1624 (cache, t) := prefixExpressionsInType(cache, env, ih, pre, t);
749 1624 outExp := Expression.makeCrefExp(cr_1, t);
750 1624 return;
751 else
752 end try;
753 end if;
754
2/2
✓ Branch 1 taken 140407 times.
✓ Branch 2 taken 130299 times.
270706 if valueEq(DAE.NOPRE(), pre) then
755 140407 crefExp := inExp;
756 else
757 130299 (cache, crefExp) := prefixExpCref(cache, env, ih, inExp, pre);
758 end if;
759 270706 then (cache,crefExp);
760
761 // clocks
762 case (DAE.CLKCONST(clk), _)
763 algorithm
764 23 (cache, clk) := prefixClockKind(cache, env, ih, clk, pre);
765 23 then
766 (cache, DAE.CLKCONST(clk));
767
768 case ((DAE.ASUB(exp = e1, sub = subs)),_)
769 algorithm
770
4/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 406 times.
✓ Branch 3 taken 286 times.
692 expl := list(Expression.getSubscriptExp(sub) for sub in subs);
771 286 (cache, es_1) := prefixExpList(cache, env, ih, expl, pre);
772 286 (cache, e1) := prefixExpWork(cache, env, ih, e1, pre);
773 286 e2 := Expression.makeASUB(e1,es_1);
774 then
775 (cache, e2);
776
777 case ((DAE.TSUB(e1, index_, t)),_)
778 algorithm
779 ✗ (cache,e1) := prefixExpWork(cache, env, ih, e1, pre);
780 ✗ e2 := DAE.TSUB(e1, index_, t);
781 then
782 (cache,e2);
783
784 case (DAE.BINARY(exp1 = e1,operator = o,exp2 = e2),_)
785 algorithm
786 161119 (cache,e1_1) := prefixExpWork(cache, env, ih, e1, pre);
787 161119 (cache,e2_1) := prefixExpWork(cache, env, ih, e2, pre);
788 161119 then
789 (cache,DAE.BINARY(e1_1,o,e2_1));
790
791 case (DAE.UNARY(operator = o,exp = e1),_)
792 algorithm
793 3161 (cache,e1_1) := prefixExpWork(cache, env, ih, e1, pre);
794 3161 then
795 (cache,DAE.UNARY(o,e1_1));
796
797 case (DAE.LBINARY(exp1 = e1,operator = o,exp2 = e2),_)
798 algorithm
799 1846 (cache,e1_1) := prefixExpWork(cache, env, ih, e1, pre);
800 1846 (cache,e2_1) := prefixExpWork(cache, env, ih, e2, pre);
801 1846 then
802 (cache,DAE.LBINARY(e1_1,o,e2_1));
803
804 case (DAE.LUNARY(operator = o,exp = e1),_)
805 algorithm
806 445 (cache,e1_1) := prefixExpWork(cache, env, ih, e1, pre);
807 445 then
808 (cache,DAE.LUNARY(o,e1_1));
809
810 case (DAE.RELATION(exp1 = e1,operator = o,exp2 = e2, index=index_, optionExpisASUB= isExpisASUB),_)
811 algorithm
812 7022 (cache,e1_1) := prefixExpWork(cache, env, ih, e1, pre);
813 7022 (cache,e2_1) := prefixExpWork(cache, env, ih, e2, pre);
814 7022 then
815 (cache,DAE.RELATION(e1_1,o,e2_1,index_,isExpisASUB));
816
817 case (DAE.IFEXP(expCond = e1,expThen = e2,expElse = e3),_)
818 algorithm
819 4528 (cache,e1_1) := prefixExpWork(cache, env, ih, e1, pre);
820 4528 (cache,e2_1) := prefixExpWork(cache, env, ih, e2, pre);
821 4528 (cache,e3_1) := prefixExpWork(cache, env, ih, e3, pre);
822 4528 then
823 (cache,DAE.IFEXP(e1_1,e2_1,e3_1));
824
825 case (DAE.SIZE(exp = cref,sz = SOME(dim)),_)
826 algorithm
827 104 (cache,cref_1) := prefixExpWork(cache, env, ih, cref, pre);
828 104 (cache,dim_1) := prefixExpWork(cache, env, ih, dim, pre);
829 104 then
830 (cache,DAE.SIZE(cref_1,SOME(dim_1)));
831
832 case (DAE.SIZE(exp = cref,sz = NONE()),_)
833 algorithm
834 ✗ (cache,cref_1) := prefixExpWork(cache, env, ih, cref, pre);
835 ✗ then
836 (cache,DAE.SIZE(cref_1,NONE()));
837
838 case (DAE.CALL(f,es,attr),_)
839 algorithm
840 24880 (cache,es_1) := prefixExpList(cache, env, ih, es, pre);
841 24880 then
842 (cache,DAE.CALL(f,es_1,attr));
843
844 case (e as DAE.PARTEVALFUNCTION(),_)
845 algorithm
846 12 (cache,es_1) := prefixExpList(cache, env, ih, e.expList, pre);
847 12 e.expList := es_1;
848 then (cache,e);
849
850 case (DAE.RECORD(f,es,fieldNames,t),_)
851 algorithm
852 2890 (cache,_) := prefixExpList(cache, env, ih, es, pre);
853 2890 then
854 (cache,DAE.RECORD(f,es,fieldNames,t));
855
856 case (DAE.ARRAY(array = {}),_)
857 then (cache, inExp);
858
859 case (DAE.ARRAY(ty = t,scalar = sc,array = es),_)
860 algorithm
861 135490 (cache,es_1) := prefixExpList(cache, env, ih, es, pre);
862
2/2
✓ Branch 0 taken 719 times.
✓ Branch 1 taken 134771 times.
136209 then
863 (cache,DAE.ARRAY(t,sc,es_1));
864
865 case (DAE.TUPLE(PR = es),_)
866 algorithm
867 8 (cache,es_1) := prefixExpList(cache, env, ih, es, pre);
868 8 then
869 (cache,DAE.TUPLE(es_1));
870
871 case (DAE.MATRIX(matrix = {}),_)
872 then (cache,inExp);
873
874 case (DAE.MATRIX(ty = t,integer = a,matrix = (x :: xs)),_)
875 algorithm
876 7783 (cache,x_1) := prefixExpList(cache, env, ih, x, pre);
877
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 7783 times.
7783 (cache,DAE.MATRIX(t,_,xs_1)) := prefixExpWork(cache, env, ih, DAE.MATRIX(t,a,xs), pre);
878 7783 then
879 (cache,DAE.MATRIX(t,a,(x_1 :: xs_1)));
880
881 case (DAE.RANGE(ty = t,start = start,step = NONE(),stop = stop),_)
882 algorithm
883 154 (cache,start_1) := prefixExpWork(cache, env, ih, start, pre);
884 154 (cache,stop_1) := prefixExpWork(cache, env, ih, stop, pre);
885 154 then
886 (cache,DAE.RANGE(t,start_1,NONE(),stop_1));
887
888 case (DAE.RANGE(ty = t,start = start,step = SOME(step),stop = stop),_)
889 algorithm
890 ✗ (cache,start_1) := prefixExpWork(cache, env, ih, start, pre);
891 ✗ (cache,step_1) := prefixExpWork(cache, env, ih, step, pre);
892 ✗ (cache,stop_1) := prefixExpWork(cache, env, ih, stop, pre);
893 ✗ then
894 (cache,DAE.RANGE(t,start_1,SOME(step_1),stop_1));
895
896 case (DAE.CAST(ty = tp,exp = e),_)
897 algorithm
898 528 (cache,e_1) := prefixExpWork(cache, env, ih, e, pre);
899 528 then
900 (cache,DAE.CAST(tp,e_1));
901
902 case (DAE.REDUCTION(reductionInfo = reductionInfo,expr = exp,iterators = riters),_)
903 algorithm
904 7 (cache,exp_1) := prefixExpWork(cache, env, ih, exp, pre);
905 7 (cache,riters) := prefixIterators(cache, env, ih, riters, pre);
906 7 then
907 (cache,DAE.REDUCTION(reductionInfo,exp_1,riters));
908
909 // MetaModelica extension. KS
910 case (DAE.LIST(es),_)
911 algorithm
912 ✗ (cache,es_1) := prefixExpList(cache, env, ih, es, pre);
913 ✗ then (cache,DAE.LIST(es_1));
914
915 case (DAE.CONS(e1,e2),_)
916 algorithm
917 ✗ (cache,e1) := prefixExpWork(cache, env, ih, e1, pre);
918 ✗ (cache,e2) := prefixExpWork(cache, env, ih, e2, pre);
919 ✗ then (cache,DAE.CONS(e1,e2));
920
921 case (DAE.META_TUPLE(es),_)
922 algorithm
923 ✗ (cache,es_1) := prefixExpList(cache, env, ih, es, pre);
924 ✗ then (cache,DAE.META_TUPLE(es_1));
925
926 case (DAE.META_OPTION(SOME(e1)),_)
927 algorithm
928 ✗ (cache,e1) := prefixExpWork(cache, env, ih, e1, pre);
929 ✗ then (cache,DAE.META_OPTION(SOME(e1)));
930
931 case (DAE.META_OPTION(NONE()),_)
932 algorithm
933 then (cache,DAE.META_OPTION(NONE()));
934
935 case (DAE.METARECORDCALL(), _)
936 algorithm
937 ✗ (cache, expl) := prefixExpList(cache, env, ih, inExp.args, pre);
938 ✗ then
939 (cache, DAE.METARECORDCALL(inExp.path, expl, inExp.fieldNames, inExp.index, inExp.typeVars));
940
941 case (e as DAE.UNBOX(e1),_)
942 algorithm
943 ✗ (cache,e1) := prefixExpWork(cache, env, ih, e1, pre);
944 ✗ e.exp := e1;
945 then (cache,e);
946
947 case (e as DAE.BOX(e1),_)
948 algorithm
949 38 (cache,e1) := prefixExpWork(cache, env, ih, e1, pre);
950 38 e.exp := e1;
951 then (cache,e);
952 // ------------------------
953
954 // no prefix, return the input expression
955 case (e,DAE.NOPRE()) then (cache,e);
956
957 case (e as DAE.EMPTY(),_) then (cache,e);
958
959 else
960 algorithm
961 ✗ Error.addInternalError(getInstanceName() + " failed on exp: " + ExpressionBasics.printExpStr(inExp) + " " + makePrefixString(pre), sourceInfo());
962 ✗ then fail();
963 end match;
964 end prefixExpWork;
965
966 protected function prefixExpCref
967 "Helper function to prefixExp for prefixing a cref expression."
968 input FCore.Cache inCache;
969 input FCore.Graph inEnv;
970 input InstanceHierarchy inIH;
971 input DAE.Exp inCref;
972 input DAE.Prefix inPrefix;
973 output FCore.Cache outCache;
974 output DAE.Exp outCref;
975 protected
976 Option<Boolean> is_iter;
977 FCore.Cache cache;
978 DAE.ComponentRef cr;
979 algorithm
980
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130299 times.
130299 DAE.CREF(componentRef = cr) := inCref;
981 130299 (is_iter, cache) := Lookup.isIterator(inCache, inEnv, cr);
982 130299 (outCache, outCref) := prefixExpCref2(cache, inEnv, inIH, is_iter, inCref, inPrefix);
983 end prefixExpCref;
984
985 protected function prefixExpCref2
986 input FCore.Cache inCache;
987 input FCore.Graph inEnv;
988 input InstanceHierarchy inIH;
989 input Option<Boolean> inIsIter;
990 input DAE.Exp inCref;
991 input DAE.Prefix inPrefix;
992 output FCore.Cache outCache;
993 output DAE.Exp outCref;
994 algorithm
995 (outCache, outCref) := match(inCache, inIsIter, inCref)
996 local
997 FCore.Cache cache;
998 DAE.ComponentRef cr;
999 DAE.Type ty;
1000 DAE.Exp exp;
1001
1002 // A cref found in the current scope that's not an iterator.
1003 case (cache, SOME(false), DAE.CREF(componentRef = cr, ty = ty))
1004 algorithm
1005 129649 (cache, cr) := prefixCref(cache, inEnv, inIH, inPrefix, cr);
1006 129649 (cache, ty) := prefixExpressionsInType(cache, inEnv, inIH, inPrefix, ty);
1007 129649 exp := Expression.makeCrefExp(cr, ty);
1008 then
1009 (cache, exp);
1010
1011 // An iterator, shouldn't be prefixed.
1012 case (_, SOME(true), _)
1013 then (inCache, inCref);
1014
1015 // A cref not found in the current scope.
1016 case (cache, NONE(), DAE.CREF(componentRef = cr, ty = ty))
1017 algorithm
1018 331 (cache, cr) := prefixSubscriptsInCref(cache, inEnv, inIH, inPrefix, cr);
1019 331 (cache, ty) := prefixExpressionsInType(cache, inEnv, inIH, inPrefix, ty);
1020 331 exp := Expression.makeCrefExp(cr, ty);
1021 then
1022 (cache, exp);
1023
1024 end match;
1025 end prefixExpCref2;
1026
1027 protected function prefixIterators
1028 input FCore.Cache inCache;
1029 input FCore.Graph inEnv;
1030 input InstanceHierarchy ih;
1031 input DAE.ReductionIterators inIters;
1032 input DAE.Prefix pre;
1033 output FCore.Cache outCache;
1034 output DAE.ReductionIterators outIters;
1035 algorithm
1036 (outCache,outIters) := match (inCache, inEnv, inIters)
1037 local
1038 String id;
1039 DAE.Exp exp,gexp;
1040 DAE.Type ty;
1041 DAE.ReductionIterator iter;
1042 FCore.Cache cache;
1043 FCore.Graph env;
1044 DAE.ReductionIterators iters;
1045
1046 case (cache, _, {}) then (cache,{});
1047 case (cache, env, DAE.REDUCTIONITER(id,exp,SOME(gexp),ty)::iters)
1048 algorithm
1049 ✗ (cache,exp) := prefixExpWork(cache,env,ih,exp,pre);
1050 ✗ (cache,gexp) := prefixExpWork(cache,env,ih,gexp,pre);
1051 ✗ iter := DAE.REDUCTIONITER(id,exp,SOME(gexp),ty);
1052 ✗ (cache,iters) := prefixIterators(cache,env,ih,iters,pre);
1053 ✗ then (cache,iter::iters);
1054 case (cache, env, DAE.REDUCTIONITER(id,exp,NONE(),ty)::iters)
1055 algorithm
1056 7 (cache,exp) := prefixExpWork(cache,env,ih,exp,pre);
1057 7 iter := DAE.REDUCTIONITER(id,exp,NONE(),ty);
1058 7 (cache,iters) := prefixIterators(cache,env,ih,iters,pre);
1059 7 then (cache,iter::iters);
1060 end match;
1061 end prefixIterators;
1062
1063 public function prefixExpList "This function prefixes a list of expressions using the prefixExp function."
1064 input FCore.Cache inCache;
1065 input FCore.Graph inEnv;
1066 input InnerOuter.InstHierarchy inIH;
1067 input list<DAE.Exp> inExpExpLst;
1068 input DAE.Prefix inPrefix;
1069 output FCore.Cache outCache = inCache;
1070 output list<DAE.Exp> outExpExpLst = {};
1071 protected
1072 DAE.Exp e_1;
1073 algorithm
1074
2/2
✓ Branch 0 taken 728683 times.
✓ Branch 1 taken 172652 times.
901335 for e in inExpExpLst loop
1075 728683 (outCache,e_1) := prefixExpWork(outCache, inEnv, inIH, e, inPrefix);
1076 728683 outExpExpLst := e_1::outExpExpLst;
1077 end for;
1078 172652 outExpExpLst := Dangerous.listReverseInPlace(outExpExpLst);
1079 end prefixExpList;
1080
1081 //--------------------------------------------
1082 // PART OF THE WORKAROUND FOR VALUEBLOCKS. KS
1083 protected function prefixStatements "Prefix statements.
1084 PART OF THE WORKAROUND FOR VALUEBLOCKS"
1085 input FCore.Cache cache;
1086 input FCore.Graph env;
1087 input InstanceHierarchy inIH;
1088 input list<DAE.Statement> stmts;
1089 input DAE.Prefix p;
1090 output FCore.Cache outCache = cache;
1091 output list<DAE.Statement> outStmts = {};
1092 protected
1093 algorithm
1094 ✗ for st in stmts loop
1095 () := match st
1096 local
1097 DAE.Type t;
1098 DAE.Exp e,e1,e2,e3;
1099 DAE.ElementSource source;
1100 DAE.Statement elem;
1101
1102 list<DAE.Statement> sList,b;
1103 String id;
1104 list<DAE.Exp> eLst;
1105 Boolean bool;
1106 DAE.Else elseBranch;
1107 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
1108 case DAE.STMT_ASSIGN(t,e1,e,source)
1109 algorithm
1110 ✗ (outCache,e1) := prefixExpWork(outCache,env,inIH,e1,p);
1111 ✗ (outCache,e) := prefixExpWork(outCache,env,inIH,e,p);
1112 ✗ elem := DAE.STMT_ASSIGN(t,e1,e,source);
1113 outStmts := elem::outStmts;
1114 then ();
1115
1116 case DAE.STMT_TUPLE_ASSIGN(t,eLst,e,source)
1117 algorithm
1118 ✗ (outCache,e) := prefixExpWork(outCache,env,inIH,e,p);
1119 ✗ (outCache,eLst) := prefixExpList(outCache,env,inIH,eLst,p);
1120 ✗ elem := DAE.STMT_TUPLE_ASSIGN(t,eLst,e,source);
1121 outStmts := elem::outStmts;
1122 then ();
1123
1124 case DAE.STMT_ASSIGN_ARR(t,e1,e,source)
1125 algorithm
1126 ✗ (outCache,e1) := prefixExpWork(outCache,env,inIH,e1,p);
1127 ✗ (outCache,e) := prefixExpWork(outCache,env,inIH,e,p);
1128 ✗ elem := DAE.STMT_ASSIGN_ARR(t,e1,e,source);
1129 outStmts := elem::outStmts;
1130 then ();
1131
1132 case DAE.STMT_FOR(t,bool,id,e,sList,source,sub_iters)
1133 algorithm
1134 ✗ (outCache,e) := prefixExpWork(outCache,env,inIH,e,p);
1135 ✗ (outCache,sList) := prefixStatements(outCache,env,inIH,sList,p);
1136 ✗ elem := DAE.STMT_FOR(t,bool,id,e,sList,source,sub_iters);
1137 outStmts := elem::outStmts;
1138 then ();
1139
1140 case DAE.STMT_IF(e1,sList,elseBranch,source)
1141 algorithm
1142 ✗ (outCache,e1) := prefixExpWork(outCache,env,inIH,e1,p);
1143 ✗ (outCache,sList) := prefixStatements(outCache,env,inIH,sList,p);
1144 ✗ (outCache,elseBranch) := prefixElse(outCache,env,inIH,elseBranch,p);
1145 ✗ elem := DAE.STMT_IF(e1,sList,elseBranch,source);
1146 outStmts := elem::outStmts;
1147 then ();
1148
1149 case DAE.STMT_WHILE(e1,sList,source)
1150 algorithm
1151 ✗ (outCache,e1) := prefixExpWork(outCache,env,inIH,e1,p);
1152 ✗ (outCache,sList) := prefixStatements(outCache,env,inIH,sList,p);
1153 ✗ elem := DAE.STMT_WHILE(e1,sList,source);
1154 outStmts := elem::outStmts;
1155 then ();
1156
1157 case DAE.STMT_ASSERT(e1,e2,e3,source)
1158 algorithm
1159 ✗ (outCache,e1) := prefixExpWork(outCache,env,inIH,e1,p);
1160 ✗ (outCache,e2) := prefixExpWork(outCache,env,inIH,e2,p);
1161 ✗ (outCache,e3) := prefixExpWork(outCache,env,inIH,e3,p);
1162 ✗ elem := DAE.STMT_ASSERT(e1,e2,e3,source);
1163 outStmts := elem::outStmts;
1164 then ();
1165
1166 case DAE.STMT_FAILURE(b,source)
1167 algorithm
1168 ✗ (outCache,b) := prefixStatements(outCache,env,inIH,b,p);
1169 ✗ elem := DAE.STMT_FAILURE(b,source);
1170 outStmts := elem::outStmts;
1171 then ();
1172
1173 case DAE.STMT_RETURN(source)
1174 algorithm
1175 ✗ elem := DAE.STMT_RETURN(source);
1176 outStmts := elem::outStmts;
1177 then ();
1178
1179 case DAE.STMT_BREAK(source)
1180 algorithm
1181 ✗ elem := DAE.STMT_BREAK(source);
1182 outStmts := elem::outStmts;
1183 then ();
1184 end match;
1185 end for;
1186 ✗ outStmts := Dangerous.listReverseInPlace(outStmts);
1187 end prefixStatements;
1188
1189 protected function prefixElse "Prefix else statements.
1190 PART OF THE WORKAROUND FOR VALUEBLOCKS"
1191 input FCore.Cache cache;
1192 input FCore.Graph env;
1193 input InstanceHierarchy inIH;
1194 input DAE.Else elseBranch;
1195 input DAE.Prefix p;
1196 output FCore.Cache outCache;
1197 output DAE.Else outElse;
1198 algorithm
1199 (outCache,outElse) := match (cache,env,inIH,elseBranch,p)
1200 local
1201 FCore.Cache localCache;
1202 FCore.Graph localEnv;
1203 DAE.Prefix pre;
1204 InstanceHierarchy ih;
1205 DAE.Exp e;
1206 list<DAE.Statement> lStmt;
1207 DAE.Else el,stmt;
1208
1209 case (localCache,_,_,DAE.NOELSE(),_)
1210 then (localCache,DAE.NOELSE());
1211
1212 case (localCache,localEnv,ih,DAE.ELSEIF(e,lStmt,el),pre)
1213 algorithm
1214 ✗ (localCache,e) := prefixExpWork(localCache,localEnv,ih,e,pre);
1215 ✗ (localCache,el) := prefixElse(localCache,localEnv,ih,el,pre);
1216 ✗ (localCache,lStmt) := prefixStatements(localCache,localEnv,ih,lStmt,pre);
1217 ✗ stmt := DAE.ELSEIF(e,lStmt,el);
1218 then (localCache,stmt);
1219
1220 case (localCache,localEnv,ih,DAE.ELSE(lStmt),pre)
1221 algorithm
1222 ✗ (localCache,lStmt) := prefixStatements(localCache,localEnv,ih,lStmt,pre);
1223 ✗ stmt := DAE.ELSE(lStmt);
1224 then (localCache,stmt);
1225 end match;
1226 end prefixElse;
1227
1228 public function makePrefixString "helper function for Mod.verifySingleMod, pretty output"
1229 input DAE.Prefix pre;
1230 output String str;
1231 algorithm
1232 str := match pre
1233 case DAE.NOPRE() then "from top scope";
1234 case _
1235 algorithm
1236 ✗ str := "from calling scope: " + printPrefixStr(pre);
1237 then str;
1238 end match;
1239 end makePrefixString;
1240
1241 public function prefixExpressionsInType
1242 input FCore.Cache inCache;
1243 input FCore.Graph inEnv;
1244 input InnerOuter.InstHierarchy inIH;
1245 input DAE.Prefix inPre;
1246 input DAE.Type inTy;
1247 output FCore.Cache outCache;
1248 output DAE.Type outTy;
1249 algorithm
1250 (outCache, outTy) := matchcontinue inTy
1251 // don't do this for MetaModelica!
1252 case _
1253 algorithm
1254
1/2
✓ Branch 1 taken 131607 times.
✗ Branch 2 not taken.
131607 true := Config.acceptMetaModelicaGrammar();
1255 then
1256 (inCache, inTy);
1257
1258 else
1259 algorithm
1260 131607 (outTy, (outCache, _, _, _)) := Types.traverseType(inTy, (inCache, inEnv, inIH, inPre), prefixArrayDimensions);
1261 then
1262 (outCache, outTy);
1263 end matchcontinue;
1264 end prefixExpressionsInType;
1265
1266 protected function prefixArrayDimensions
1267 "@author: adrpo
1268 this function prefixes all the expressions in types to be found by the back-end or code generation!"
1269 input DAE.Type ty;
1270 input tuple<FCore.Cache,FCore.Graph,InnerOuter.InstHierarchy,DAE.Prefix> tpl;
1271 output DAE.Type oty = ty;
1272 output tuple<FCore.Cache,FCore.Graph,InnerOuter.InstHierarchy,DAE.Prefix> otpl;
1273 algorithm
1274 (oty,otpl) := match (oty,tpl)
1275 local
1276 FCore.Cache cache;
1277 FCore.Graph env;
1278 InnerOuter.InstHierarchy ih;
1279 DAE.Prefix pre;
1280 DAE.Dimensions dims;
1281
1282 case (DAE.T_ARRAY(),(cache, env, ih, pre))
1283 algorithm
1284 14185 (cache, dims) := prefixDimensions(cache, env, ih, pre, oty.dims);
1285 14185 oty.dims := dims;
1286 14185 then
1287 (oty,(cache, env, ih, pre));
1288
1289 else (oty,tpl);
1290
1291 end match;
1292 end prefixArrayDimensions;
1293
1294 public function prefixDimensions
1295 input FCore.Cache inCache;
1296 input FCore.Graph inEnv;
1297 input InnerOuter.InstHierarchy inIH;
1298 input DAE.Prefix inPre;
1299 input DAE.Dimensions inDims;
1300 output FCore.Cache outCache;
1301 output DAE.Dimensions outDims;
1302 algorithm
1303 (outCache,outDims) := matchcontinue inDims
1304 local
1305 DAE.Exp e;
1306 DAE.Dimensions rest, new;
1307 DAE.Dimension d;
1308 FCore.Cache cache;
1309
1310 case {} then (inCache, {});
1311
1312 case DAE.DIM_EXP(exp=e)::rest
1313 algorithm
1314 ✗ (cache, e) := prefixExpWork(inCache, inEnv, inIH, e, inPre);
1315 ✗ (cache, new) := prefixDimensions(cache, inEnv, inIH, inPre, rest);
1316 ✗ then
1317 (cache, DAE.DIM_EXP(e)::new);
1318
1319 case d::rest
1320 algorithm
1321 18441 (cache, new) := prefixDimensions(inCache, inEnv, inIH, inPre, rest);
1322 18441 then
1323 (cache, d::new);
1324 end matchcontinue;
1325 end prefixDimensions;
1326
1327 public function isPrefix
1328 input DAE.Prefix prefix;
1329 output Boolean isPrefix;
1330 algorithm
1331 isPrefix := match prefix
1332 case DAE.PREFIX() then true;
1333 else false;
1334 end match;
1335 end isPrefix;
1336
1337 public function isNoPrefix
1338 input DAE.Prefix inPrefix;
1339 output Boolean outIsEmpty;
1340 algorithm
1341 outIsEmpty := match inPrefix
1342 case DAE.NOPRE() then true;
1343 else false;
1344 end match;
1345 end isNoPrefix;
1346
1347 public function prefixClockKind "Add the supplied prefix to the clock kind"
1348 input FCore.Cache inCache;
1349 input FCore.Graph inEnv;
1350 input InnerOuter.InstHierarchy inIH;
1351 input DAE.ClockKind inClkKind;
1352 input DAE.Prefix inPrefix;
1353 output FCore.Cache outCache;
1354 output DAE.ClockKind outClkKind;
1355 algorithm
1356 (outCache, outClkKind) := match (inCache, inEnv, inIH, inClkKind, inPrefix)
1357 local
1358 DAE.Exp e,resolution,interval,method;
1359 DAE.ClockKind clkKind;
1360 FCore.Cache cache;
1361 FCore.Graph env;
1362 InstanceHierarchy ih;
1363 DAE.Prefix p;
1364
1365 // clock kinds
1366 case (cache, _, _, DAE.INFERRED_CLOCK(), _)
1367 then (cache, inClkKind);
1368
1369 case (cache, env, ih, DAE.RATIONAL_CLOCK(e, resolution), p)
1370 algorithm
1371 1 (cache, e) := prefixExpWork(cache, env, ih, e, p);
1372 1 (cache, resolution) := prefixExpWork(cache, env, ih, resolution, p);
1373 1 clkKind := DAE.RATIONAL_CLOCK(e, resolution);
1374 then
1375 (cache, clkKind);
1376
1377 case (cache, env, ih, DAE.REAL_CLOCK(e), p)
1378 algorithm
1379 5 (cache, e) := prefixExpWork(cache, env, ih, e, p);
1380 5 clkKind := DAE.REAL_CLOCK(e);
1381 then
1382 (cache, clkKind);
1383
1384 case (cache, env, ih, DAE.EVENT_CLOCK(e, interval), p)
1385 algorithm
1386 3 (cache, e) := prefixExpWork(cache, env, ih, e, p);
1387 3 (cache, interval) := prefixExpWork(cache, env, ih, interval, p);
1388 3 clkKind := DAE.EVENT_CLOCK(e, interval);
1389 then
1390 (cache, clkKind);
1391
1392 case (cache, env, ih, DAE.SOLVER_CLOCK(e, method), p)
1393 algorithm
1394 1 (cache, e) := prefixExpWork(cache, env, ih, e, p);
1395 1 (cache, method) := prefixExpWork(cache, env, ih, method, p);
1396 1 clkKind := DAE.SOLVER_CLOCK(e, method);
1397 then
1398 (cache, clkKind);
1399
1400 end match;
1401 end prefixClockKind;
1402
1403 public function getPrefixInfo
1404 input DAE.Prefix inPrefix;
1405 output SourceInfo outInfo;
1406 algorithm
1407 outInfo := match inPrefix
1408 case DAE.PREFIX(compPre = DAE.PRE(info = outInfo)) then outInfo;
1409 else Absyn.dummyInfo;
1410 end match;
1411 end getPrefixInfo;
1412
1413 public function prefixHashWork
1414 input DAE.ComponentPrefix inPrefix;
1415 input output Integer hash;
1416 algorithm
1417 hash := match inPrefix
1418 ✗ case DAE.PRE() then prefixHashWork(inPrefix.next, 31*hash + stringHashDjb2(inPrefix.prefix));
1419 else hash;
1420 end match;
1421 end prefixHashWork;
1422
1423 public function componentPrefixPathEqual
1424 input DAE.ComponentPrefix pre1,pre2;
1425 output Boolean eq;
1426 algorithm
1427 eq := match (pre1,pre2)
1428 case (DAE.PRE(),DAE.PRE())
1429 ✗ then if pre1.prefix==pre2.prefix then componentPrefixPathEqual(pre1.next, pre2.next) else false;
1430 case (DAE.NOCOMPPRE(),DAE.NOCOMPPRE()) then true;
1431 else false;
1432 end match;
1433 end componentPrefixPathEqual;
1434
1435 public function componentPrefix
1436 input DAE.Prefix inPrefix;
1437 output DAE.ComponentPrefix outPrefix;
1438 algorithm
1439 outPrefix := match inPrefix
1440 ✗ case DAE.PREFIX() then inPrefix.compPre;
1441 else DAE.NOCOMPPRE();
1442 end match;
1443 end componentPrefix;
1444
1445 public function writeComponentPrefix
1446 input File.File file;
1447 input DAE.ComponentPrefix pre;
1448 input File.Escape escape=File.Escape.None;
1449 algorithm
1450 () := match pre
1451 case DAE.PRE(next=DAE.NOCOMPPRE())
1452 algorithm
1453 172220 File.writeEscape(file, pre.prefix, escape);
1454 172220 ComponentReference.writeSubscripts(file, pre.subscripts, escape);
1455 then ();
1456 case DAE.PRE()
1457 algorithm
1458 206172 writeComponentPrefix(file, pre.next); // Stored in reverse order...
1459 206172 File.writeEscape(file, pre.prefix, escape);
1460 206172 ComponentReference.writeSubscripts(file, pre.subscripts, escape);
1461 then ();
1462 else ();
1463 end match;
1464 end writeComponentPrefix;
1465
1466 public function hasSubs "Function: crefHaveSubs
1467 Checks whether Prefix has any subscripts, recursive "
1468 input DAE.ComponentPrefix pre;
1469 output Boolean ob;
1470 algorithm
1471 ob := match pre
1472 701 case DAE.PRE(subscripts = {}) then hasSubs(pre.next);
1473 case DAE.PRE() then true;
1474 else false;
1475 end match;
1476 end hasSubs;
1477
1478 function removeCompPrefixFromExps
1479 input DAE.Exp inExp;
1480 input DAE.ComponentPrefix inCompPref;
1481 output DAE.Exp outExp;
1482 algorithm
1483 100863 outExp := Expression.traverseExpBottomUp(inExp, function removeCompPrefixFromCrefExp(inCompPref = inCompPref), false);
1484 end removeCompPrefixFromExps;
1485
1486 protected function removeCompPrefixFromCrefExp
1487 input DAE.Exp inExp;
1488 input Boolean inB;
1489 input DAE.ComponentPrefix inCompPref;
1490 output DAE.Exp outExp;
1491 output Boolean b;
1492 algorithm
1493 (outExp,b) := match inExp
1494 local
1495 DAE.Exp exp;
1496 DAE.ComponentRef cref;
1497
1498 case exp as DAE.CREF(DAE.CREF_QUAL())
1499 algorithm
1500 48912 cref := removePrefixFromCref(exp.componentRef, inCompPref);
1501 48912 exp.componentRef := cref;
1502 then
1503 (exp, true);
1504
1505 else (inExp, inB);
1506 end match;
1507 end removeCompPrefixFromCrefExp;
1508
1509 protected function removePrefixFromCref
1510 input DAE.ComponentRef inCref;
1511 input DAE.ComponentPrefix inCompPref;
1512 output DAE.ComponentRef outCref;
1513 algorithm
1514 outCref := match (inCref, inCompPref)
1515 local
1516 DAE.ComponentRef cref;
1517 DAE.ComponentPrefix pref;
1518
1519 case (_, DAE.NOCOMPPRE()) then inCref;
1520 case (DAE.CREF_IDENT(), _) then inCref;
1521
1522 case (cref as DAE.CREF_QUAL(_), pref as DAE.PRE(next=DAE.NOCOMPPRE())) algorithm
1523
2/2
✓ Branch 0 taken 81824 times.
✓ Branch 1 taken 3203 times.
85027 if stringEqual(cref.ident, pref.prefix) then
1524 else
1525 end if;
1526 85027 then
1527 cref.componentRef;
1528
1529 case (DAE.CREF_QUAL(_), pref as DAE.PRE(next=DAE.PRE(_))) algorithm
1530 66129 cref := removePrefixFromCref(inCref,pref.next);
1531 66129 pref.next := DAE.NOCOMPPRE();
1532 66129 cref := removePrefixFromCref(cref,pref);
1533 then
1534 cref;
1535
1536 case (_, DAE.PRE()) algorithm
1537 ✗ Error.addInternalError(getInstanceName() + " :Cref is not qualified but we have prefix to remove: " + ComponentReference.crefStr(inCref), sourceInfo());
1538 ✗ then
1539 fail();
1540
1541 else algorithm
1542 ✗ Error.addInternalError(getInstanceName() + " :failed on cref: " + ComponentReference.crefStr(inCref), sourceInfo());
1543 ✗ then
1544 fail();
1545 end match;
1546 end removePrefixFromCref;
1547
1548 annotation(__OpenModelica_Interface="frontend");
1549 end PrefixUtil;
1550