Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 61.3% 307 / 0 / 501
Functions: -% 0 / 1 / 1
Branches: 52.7% 98 / 0 / 186

OMCompiler/Compiler/FrontEnd/ComponentReference.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 ComponentReference
37 " file: ComponentReference.mo
38 package: ComponentReference
39 description: All stuff for ComponentRef datatypes
40
41
42 This file contains the module ComponentReference,
43 which contains functions for ComponentRef."
44
45 // public imports
46 public import Absyn;
47 public import ComponentReferenceBasics;
48 public import DAE;
49 public import File;
50
51 // protected imports
52 protected import ClassInf;
53 protected import Config;
54 protected import Debug;
55 protected import Dump;
56 protected import Error;
57 protected import Expression;
58 protected import ExpressionBasics;
59 protected import ExpressionDump;
60 protected import Flags;
61 protected import List;
62 protected import MetaModelica.Dangerous;
63 protected import Print;
64 protected import StringUtil;
65 protected import System;
66 protected import Types;
67 protected import UnorderedSet;
68 protected import Util;
69
70 // do not make this public. instead use the function below.
71 protected constant DAE.ComponentRef dummyCref = DAE.CREF_IDENT("dummy", DAE.T_UNKNOWN_DEFAULT, {});
72
73 public function createEmptyCrefMemory
74 "@author: adrpo
75 creates an array, with one element for each record in ComponentRef!"
76 output array<list<DAE.ComponentRef>> crefMemory;
77 algorithm
78 ✗ crefMemory := arrayCreate(3, {});
79 end createEmptyCrefMemory;
80
81 /***************************************************/
82 /* generate a ComponentRef */
83 /***************************************************/
84
85 public function makeDummyCref
86 "@author: adrpo
87 This function creates a dummy component reference"
88 output DAE.ComponentRef outCrefIdent;
89 annotation(__OpenModelica_EarlyInline = true);
90 algorithm
91 outCrefIdent := dummyCref;
92 end makeDummyCref;
93
94 public function makeUntypedCrefIdent
95 input DAE.Ident ident;
96 output DAE.ComponentRef outCrefIdent;
97 annotation(__OpenModelica_EarlyInline = true);
98 algorithm
99 2982 outCrefIdent := DAE.CREF_IDENT(ident, DAE.T_UNKNOWN_DEFAULT, {});
100 end makeUntypedCrefIdent;
101
102 /***************************************************/
103 /* transform to other types */
104 /***************************************************/
105
106 public function crefToPath
107 "This function converts a ComponentRef to a Path, if possible.
108 If the component reference contains subscripts, it will silently
109 fail."
110 input DAE.ComponentRef inComponentRef;
111 output Absyn.Path outPath;
112 algorithm
113 outPath := match inComponentRef
114 local
115 DAE.Ident i;
116 Absyn.Path p;
117 DAE.ComponentRef c;
118
119 3165 case DAE.CREF_IDENT(ident = i,subscriptLst = {}) then Absyn.IDENT(i);
120
121 case DAE.CREF_QUAL(ident = i,subscriptLst = {},componentRef = c)
122 algorithm
123 ✗ p := crefToPath(c);
124 ✗ then
125 Absyn.QUALIFIED(i,p);
126 end match;
127 end crefToPath;
128
129 public function crefToPathIgnoreSubs
130 input DAE.ComponentRef inComponentRef;
131 output Absyn.Path outPath;
132 algorithm
133 outPath := match inComponentRef
134 local
135 DAE.Ident i;
136 Absyn.Path p;
137 DAE.ComponentRef c;
138
139 14 case DAE.CREF_IDENT(ident = i) then Absyn.IDENT(i);
140 case DAE.CREF_QUAL(ident = i, componentRef = c)
141 algorithm
142 14 p := crefToPathIgnoreSubs(c);
143 14 then
144 Absyn.QUALIFIED(i, p);
145 end match;
146 end crefToPathIgnoreSubs;
147
148 public function pathToCref
149 "This function converts a Absyn.Path to a ComponentRef."
150 input Absyn.Path inPath;
151 output DAE.ComponentRef outComponentRef;
152 algorithm
153 outComponentRef := match inPath
154 local
155 DAE.Ident i;
156 DAE.ComponentRef c;
157 Absyn.Path p;
158
159 95093 case Absyn.IDENT(name = i) then ComponentReferenceBasics.makeCrefIdent(i,DAE.T_UNKNOWN_DEFAULT,{});
160
161 19 case Absyn.FULLYQUALIFIED(p) then pathToCref(p);
162
163 case Absyn.QUALIFIED(name = i,path = p)
164 algorithm
165 355 c := pathToCref(p);
166 355 then
167 ComponentReferenceBasics.makeCrefQual(i,DAE.T_UNKNOWN_DEFAULT,{},c);
168 end match;
169 end pathToCref;
170
171 public function creffromVar
172 " author: Frenkel TUD
173 generates a cref from DAE.Var"
174 input DAE.Var inVar;
175 output DAE.ComponentRef outComponentRef;
176 algorithm
177 outComponentRef := match inVar
178 local
179 String name;
180 DAE.Type ty;
181
182 case DAE.TYPES_VAR(name=name,ty=ty)
183 135466 then
184 ComponentReferenceBasics.makeCrefIdent(name,ty,{});
185 end match;
186 end creffromVar;
187
188 public function unelabCref
189 "Transform an ComponentRef into Absyn.ComponentRef."
190 input DAE.ComponentRef inComponentRef;
191 output Absyn.ComponentRef outComponentRef;
192 algorithm
193 outComponentRef := matchcontinue inComponentRef
194 local
195 list<Absyn.Subscript> subs_1;
196 DAE.Ident id;
197 list<DAE.Subscript> subs;
198 Absyn.ComponentRef cr_1;
199 DAE.ComponentRef cr;
200
201 // identifiers
202 case DAE.CREF_IDENT(ident = id, subscriptLst = subs)
203 algorithm
204 38661 subs_1 := unelabSubscripts(subs);
205 38661 then
206 Absyn.CREF_IDENT(id, subs_1);
207
208 // qualified
209 case DAE.CREF_QUAL(ident = id, subscriptLst = subs, componentRef = cr)
210 algorithm
211 62382 cr_1 := unelabCref(cr);
212 62382 subs_1 := unelabSubscripts(subs);
213 62382 then
214 Absyn.CREF_QUAL(id, subs_1, cr_1);
215
216 case _
217 algorithm
218 ✗ true := Flags.isSet(Flags.FAILTRACE);
219 ✗ print("ComponentReference.unelabCref failed on: " + ComponentReferenceBasics.printComponentRefStr(inComponentRef) + "\n");
220 ✗ then
221 fail();
222
223 end matchcontinue;
224 end unelabCref;
225
226 protected function unelabSubscripts
227 "Helper function to unelabCref, handles subscripts."
228 input list<DAE.Subscript> inSubscriptLst;
229 output list<Absyn.Subscript> outAbsynSubscriptLst;
230 algorithm
231 outAbsynSubscriptLst := match inSubscriptLst
232 local
233 list<Absyn.Subscript> xs_1;
234 list<DAE.Subscript> xs;
235 Absyn.Exp e_1;
236 DAE.Exp e;
237
238 // empty list
239 case {} then {};
240 // whole dimension
241 case DAE.WHOLEDIM() :: xs
242 algorithm
243 ✗ xs_1 := unelabSubscripts(xs);
244 then
245 (Absyn.NOSUB() :: xs_1);
246 // slices
247 case DAE.SLICE(exp = e) :: xs
248 algorithm
249 ✗ xs_1 := unelabSubscripts(xs);
250 ✗ e_1 := Expression.unelabExp(e);
251 ✗ then
252 (Absyn.SUBSCRIPT(e_1) :: xs_1);
253 // indexes
254 case DAE.INDEX(exp = e) :: xs
255 algorithm
256 28221 xs_1 := unelabSubscripts(xs);
257 28221 e_1 := Expression.unelabExp(e);
258 28221 then
259 (Absyn.SUBSCRIPT(e_1) :: xs_1);
260 case DAE.WHOLE_NONEXP(exp = e) :: xs
261 algorithm
262 ✗ xs_1 := unelabSubscripts(xs);
263 ✗ e_1 := Expression.unelabExp(e);
264 ✗ then
265 (Absyn.SUBSCRIPT(e_1) :: xs_1);
266 end match;
267 end unelabSubscripts;
268
269 public function toExpCref
270 "Translates an Absyn cref to an untyped DAE cref."
271 input Absyn.ComponentRef absynCref;
272 output DAE.ComponentRef daeCref;
273 algorithm
274 daeCref := match absynCref
275 local
276
277 case Absyn.CREF_IDENT()
278 324371 then ComponentReferenceBasics.makeCrefIdent(absynCref.name, DAE.T_UNKNOWN_DEFAULT,
279 toExpCrefSubs(absynCref.subscripts));
280
281 case Absyn.CREF_QUAL()
282 499744 then ComponentReferenceBasics.makeCrefQual(absynCref.name, DAE.T_UNKNOWN_DEFAULT,
283 toExpCrefSubs(absynCref.subscripts), toExpCref(absynCref.componentRef));
284
285 case Absyn.CREF_FULLYQUALIFIED()
286 29251 then toExpCref(absynCref.componentRef);
287
288 case Absyn.WILD() then DAE.WILD();
289 case Absyn.ALLWILD() then DAE.WILD();
290 end match;
291 end toExpCref;
292
293 protected function toExpCrefSubs
294 "Translates a list of Absyn subscripts to a list of untyped DAE subscripts."
295 input list<Absyn.Subscript> absynSubs;
296 output list<DAE.Subscript> daeSubs;
297 algorithm
298
4/4
✓ Branch 0 taken 333 times.
✓ Branch 1 taken 824115 times.
✓ Branch 2 taken 333 times.
✓ Branch 3 taken 824115 times.
824448 daeSubs := list(
299 match sub
300 329 case Absyn.SUBSCRIPT() then DAE.INDEX(Expression.fromAbsynExp(sub.subscript));
301 case Absyn.NOSUB() then DAE.WHOLEDIM();
302 end match
303 for sub in absynSubs);
304 end toExpCrefSubs;
305
306 public function crefStr
307 "This function simply converts a ComponentRef to a String."
308 input DAE.ComponentRef inComponentRef;
309 output String outString;
310 algorithm
311
1/2
✓ Branch 1 taken 334385 times.
✗ Branch 2 not taken.
668770 outString := stringDelimitList(toStringList(inComponentRef), if Flags.getConfigBool(Flags.MODELICA_OUTPUT) then "__" else ".");
312 end crefStr;
313
314 public function crefListStr
315 "This function simply converts a list of ComponentReferences to a String."
316 input list<DAE.ComponentRef> crList;
317 output String outString = "";
318 algorithm
319 ✗ for cr in crList loop
320 ✗ outString := outString + crefStr(cr) + "\n";
321 end for;
322 end crefListStr;
323
324 public function crefModelicaStr
325 "Same as crefStr, but uses _ instead of . "
326 input DAE.ComponentRef inComponentRef;
327 output String outString;
328 algorithm
329 44 outString := stringDelimitList(toStringList(inComponentRef), "_");
330 end crefModelicaStr;
331
332 public function printComponentRefOptStr
333 "@autor: adrpo
334 Print a cref or none"
335 input Option<DAE.ComponentRef> inComponentRefOpt;
336 output String outString;
337 algorithm
338 outString := match inComponentRefOpt
339 local
340 String str;
341 DAE.ComponentRef cref;
342
343 // none
344 case NONE() then "NONE()";
345
346 // some
347 case SOME(cref)
348 algorithm
349 ✗ str := ComponentReferenceBasics.printComponentRefStr(cref);
350 ✗ str := "SOME(" + str + ")";
351 then
352 str;
353 end match;
354 end printComponentRefOptStr;
355
356 public function printComponentRefStrFixDollarDer
357 "Like printComponentRefStr but also fixes the special dollar-sign variables"
358 input DAE.ComponentRef inComponentRef;
359 output String outString;
360 algorithm
361 outString := match inComponentRef
362 local
363 DAE.ComponentRef cr;
364 case DAE.CREF_QUAL(ident = DAE.derivativeNamePrefix, subscriptLst = {}, componentRef = cr)
365 ✗ then "der(" + ComponentReferenceBasics.printComponentRefStr(cr) + ")";
366 ✗ else ComponentReferenceBasics.printComponentRefStr(inComponentRef);
367 end match;
368 end printComponentRefStrFixDollarDer;
369
370 public function debugPrintComponentRefTypeStr "Function: debugPrintComponentRefTypeStr
371 This function is equal to debugPrintComponentRefTypeStr with the extra feature that it
372 prints the base type of each ComponentRef.
373 NOTE Only used for debugging."
374 input DAE.ComponentRef inComponentRef;
375 output String outString;
376 algorithm
377 outString := match inComponentRef
378 local
379 DAE.Ident s,str,str2,strrest,str_1;
380 list<DAE.Subscript> subs;
381 DAE.ComponentRef cr;
382 DAE.Type ty;
383
384 case DAE.WILD() then "_";
385
386 case DAE.CREF_IDENT(ident = s,identType=ty,subscriptLst = subs)
387 algorithm
388 ✗ str_1 := ExpressionBasics.printListStr(subs, ExpressionDump.debugPrintSubscriptStr, ", ");
389 ✗ str := s + (if stringLength(str_1) > 0 then "["+ str_1 + "]" else "");
390 ✗ str2 := TypesDump.unparseType(ty);
391 ✗ str := stringAppendList({str," [",str2,"]"});
392 then
393 str;
394
395 // Does not handle names with underscores
396 case DAE.CREF_QUAL(ident = s,identType=ty,subscriptLst = subs,componentRef = cr)
397 algorithm
398 ✗ if (Config.modelicaOutput())
399 then
400 ✗ str := ComponentReferenceBasics.printComponentRef2Str(s, subs);
401 ✗ str2 := TypesDump.unparseType(ty);
402 ✗ strrest := debugPrintComponentRefTypeStr(cr);
403 ✗ str := stringAppendList({str," [",str2,"] ", "__", strrest});
404 else
405 ✗ str_1 := ExpressionBasics.printListStr(subs, ExpressionDump.debugPrintSubscriptStr, ", ");
406 ✗ str := s + (if stringLength(str_1) > 0 then "["+ str_1 + "]" else "");
407 ✗ str2 := TypesDump.unparseType(ty);
408 ✗ strrest := debugPrintComponentRefTypeStr(cr);
409 ✗ str := stringAppendList({str," [",str2,"] ", ".", strrest});
410 end if;
411 then
412 str;
413
414 end match;
415 end debugPrintComponentRefTypeStr;
416
417 public function crefIsIdent
418 "returns true if ComponentRef is an ident,
419 i.e a => true , a.b => false"
420 input DAE.ComponentRef cr;
421 output Boolean res;
422 algorithm
423 res := match cr
424 case DAE.CREF_IDENT() then true;
425 else false;
426 end match;
427 end crefIsIdent;
428
429 public function crefIsNotIdent
430 "returns true if ComponentRef is not an ident,
431 i.e a => false , a.b => true"
432 input DAE.ComponentRef cr;
433 output Boolean res;
434 algorithm
435 res := match cr
436 case DAE.CREF_IDENT() then false;
437 else true;
438 end match;
439 end crefIsNotIdent;
440
441 public function isInternalCref
442 "Returns true if the cref is prefixed with '$'"
443 input DAE.ComponentRef cr;
444 output Boolean b;
445 protected
446 String s;
447 algorithm
448 b := match cr
449 case DAE.CREF_QUAL(ident=DAE.derivativeNamePrefix) then false; // allow exception for derivate vars
450 case DAE.CREF_QUAL(ident=DAE.previousNamePrefix) then false; // allow exception for Clk-previous vars
451 20101 case DAE.CREF_IDENT(ident=s) then StringUtil.startsWith(s, "$outputAlias_");
452 ✗ case DAE.CREF_IDENT(ident=s) then StringUtil.startsWith(s, "$");
453 329525 case DAE.CREF_QUAL(ident=s) then StringUtil.startsWith(s, "$");
454 else false;
455 end match;
456 end isInternalCref;
457
458 public function isRecord "
459 function isRecord
460 returns true if the type of the last ident is a record"
461 input DAE.ComponentRef cr;
462 output Boolean b;
463 algorithm
464 b := match cr
465 local
466 DAE.ComponentRef comp;
467 case DAE.CREF_IDENT(identType = DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(_))) then true;
468 /* this case is false because it is not the last ident.
469 case(DAE.CREF_QUAL(identType = DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(_)))) then true;*/
470 465146 case DAE.CREF_QUAL(componentRef=comp) then isRecord(comp);
471 else false;
472 end match;
473 end isRecord;
474
475 public function isArrayElement "returns true if cref is elemnt of an array"
476 input DAE.ComponentRef cr;
477 output Boolean b;
478 algorithm
479 b := match cr
480 local
481 DAE.ComponentRef comp;
482 case DAE.CREF_IDENT(identType = DAE.T_ARRAY()) then true;
483 case DAE.CREF_QUAL(identType = DAE.T_ARRAY()) then true;
484 358449 case DAE.CREF_QUAL(componentRef=comp) then isArrayElement(comp);
485 else false;
486 end match;
487 end isArrayElement;
488
489 public function isPreCref
490 input DAE.ComponentRef cr;
491 output Boolean b;
492 algorithm
493 b := match cr
494 case DAE.CREF_QUAL(ident=DAE.preNamePrefix) then true;
495 else false;
496 end match;
497 end isPreCref;
498
499 public function isPreviousCref
500 input DAE.ComponentRef cr;
501 output Boolean b;
502 algorithm
503 b := match cr
504 case DAE.CREF_QUAL(ident=DAE.previousNamePrefix) then true;
505 else false;
506 end match;
507 end isPreviousCref;
508
509 public function isStartCref
510 input DAE.ComponentRef cr;
511 output Boolean b;
512 algorithm
513 b := match cr
514 case DAE.CREF_QUAL(ident=DAE.startNamePrefix) then true;
515 else false;
516 end match;
517 end isStartCref;
518
519 public function popPreCref
520 input DAE.ComponentRef inCR;
521 output DAE.ComponentRef outCR;
522 algorithm
523 outCR := match inCR
524 local DAE.ComponentRef cr;
525 case DAE.CREF_QUAL(ident = DAE.preNamePrefix, componentRef=cr) then cr;
526 else inCR;
527 end match;
528 end popPreCref;
529
530 public function popCref
531 input DAE.ComponentRef inCR;
532 output DAE.ComponentRef outCR;
533 algorithm
534 outCR := match inCR
535 local DAE.ComponentRef cr;
536 case DAE.CREF_QUAL(componentRef=cr) then cr;
537 else inCR;
538 end match;
539 end popCref;
540
541 public function crefIsFirstArrayElt
542 "This function returns true for component references that
543 are arrays and references the first element of the array.
544 like for instance a.b{1,1} and a{1} returns true but
545 a.b{1,2} or a{2} returns false."
546 input DAE.ComponentRef inComponentRef;
547 output Boolean outBoolean;
548 algorithm
549 outBoolean := matchcontinue inComponentRef
550 local
551 list<DAE.Subscript> subs;
552 DAE.ComponentRef cr;
553 case cr
554 algorithm
555
4/4
✓ Branch 1 taken 14304 times.
✓ Branch 2 taken 404401 times.
✓ Branch 5 taken 14110 times.
✓ Branch 6 taken 194 times.
418705 if (stringEqual(Config.simCodeTarget(), "Cpp"))then
556
2/2
✓ Branch 1 taken 8712 times.
✓ Branch 2 taken 5398 times.
14110 subs as (_ :: _) := crefLastSubs(cr);
557 else
558
2/2
✓ Branch 1 taken 196875 times.
✓ Branch 2 taken 207720 times.
404595 subs as (_ :: _) := ComponentReferenceBasics.crefSubs(cr);
559 end if;
560 // fails if any mapped functions returns false
561 213118 then List.all(subs, Expression.subscriptIsFirst);
562 else false;
563 end matchcontinue;
564 end crefIsFirstArrayElt;
565
566 public function crefHaveSubs "Function: crefHaveSubs
567 Checks whether Componentref has any subscripts, recursive "
568 input DAE.ComponentRef icr;
569 output Boolean ob;
570 algorithm ob := matchcontinue icr
571 local
572 DAE.ComponentRef cr;
573 Boolean b;
574 DAE.Ident str;
575 Integer idx;
576 case DAE.CREF_QUAL(subscriptLst = _ :: _) then true;
577 case DAE.CREF_IDENT(subscriptLst = _ :: _) then true;
578 case DAE.CREF_IDENT(ident = str,subscriptLst ={}) // for stringified crefs!
579 algorithm
580 8640 idx := System.stringFind(str, "["); // (-1 on failure)
581
1/2
✓ Branch 0 taken 8640 times.
✗ Branch 1 not taken.
8640 true := idx > 0; // index should be more than 0!
582 then true;
583 case DAE.CREF_QUAL(subscriptLst = {},componentRef = cr)
584 algorithm
585 27411 b := crefHaveSubs(cr);
586 then b;
587 else false;
588 end matchcontinue;
589 end crefHaveSubs;
590
591 public function crefHasScalarSubscripts "returns true if the subscripts of the cref results in a scalar variable.
592 For example given Real x[3,3]
593 x[1,2] has scalar subscripts
594 x[1] has not scalar subscripts
595 x[:,1] has not scalar subscripts
596 x[{1,2},1] has not scalar subscripts
597 "
598 input DAE.ComponentRef cr;
599 output Boolean hasScalarSubs;
600 algorithm
601 hasScalarSubs := matchcontinue cr
602 local
603 list<DAE.Subscript> subs;
604 DAE.Type tp;
605 DAE.Dimensions dims;
606
607 /* No subscripts */
608
2/2
✓ Branch 1 taken 14733 times.
✓ Branch 2 taken 22869 times.
37602 case _ algorithm {} := crefLastSubs(cr); then true;
609
610 /* constant Subscripts that match type => true */
611 case _ algorithm
612
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14733 times.
14733 subs as (_::_):= crefLastSubs(cr);
613
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 14716 times.
14733 true := Expression.subscriptConstants(subs);
614 14716 tp := crefLastType(cr);
615 14716 dims := Expression.arrayDimension(tp);
616 // Since all subscripts are constants, sufficient to compare length of dimensions
617 // Dimensions may be removed when a component is instantiated if it has
618 // constant subscripts though, so it may have more subscripts than
619 // dimensions.
620
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 14716 times.
14716 true := listLength(dims) <= listLength(subs);
621 then true;
622
623 /* All other cases are false */
624 else false;
625 end matchcontinue;
626 end crefHasScalarSubscripts;
627
628 public function crefIsScalarWithAllConstSubs
629 ""
630 input DAE.ComponentRef inCref;
631 output Boolean isScalar;
632 algorithm
633 isScalar := matchcontinue inCref
634 local
635 list<DAE.Subscript> subs;
636 list<DAE.Dimension> dims;
637
638
2/2
✓ Branch 1 taken 829710 times.
✓ Branch 2 taken 761277 times.
1590987 case _ algorithm {} := ComponentReferenceBasics.crefSubs(inCref); then true;
639
640 case _
641 algorithm
642
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 829710 times.
829710 subs as (_::_):= ComponentReferenceBasics.crefSubs(inCref);
643 829710 dims := ComponentReferenceBasics.crefDims(inCref);
644 // Dimensions may be removed when a component is instantiated if it has
645 // constant subscripts though, so it may have more subscripts than
646 // dimensions.
647 // mahge: TODO: Does this still happen?
648
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 829710 times.
829710 true := listLength(dims) <= listLength(subs);
649
2/2
✓ Branch 1 taken 200 times.
✓ Branch 2 taken 829510 times.
829710 true := Expression.subscriptConstants(subs);
650 then
651 true;
652
653 else false;
654
655 end matchcontinue;
656 end crefIsScalarWithAllConstSubs;
657
658 public function crefIsScalarWithVariableSubs
659 ""
660 input DAE.ComponentRef inCref;
661 output Boolean isScalar;
662 algorithm
663 isScalar := matchcontinue inCref
664 local
665 list<DAE.Subscript> subs;
666 list<DAE.Dimension> dims;
667
668 case _
669 algorithm
670
2/2
✓ Branch 1 taken 304259 times.
✓ Branch 2 taken 346388 times.
650647 subs as (_::_):= ComponentReferenceBasics.crefSubs(inCref);
671 346388 dims := ComponentReferenceBasics.crefDims(inCref);
672 // Dimensions may be removed when a component is instantiated if it has
673 // constant subscripts though, so it may have more subscripts than
674 // dimensions.
675 // mahge: TODO: Does this still happen?
676
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 346388 times.
346388 true := listLength(dims) <= listLength(subs);
677
2/2
✓ Branch 1 taken 344342 times.
✓ Branch 2 taken 2046 times.
346388 false := Expression.subscriptConstants(subs);
678 then
679 true;
680
681 else false;
682
683 end matchcontinue;
684 end crefIsScalarWithVariableSubs;
685
686 public function containWholeDim " A function to check if a cref contains a [:] wholedim element in the subscriptlist.
687 "
688 input DAE.ComponentRef inRef;
689 output Boolean wholedim;
690
691 algorithm
692 wholedim := match inRef
693 local
694 DAE.ComponentRef cr;
695 list<DAE.Subscript> ssl;
696 DAE.Type ty;
697 case DAE.CREF_IDENT(_,ty,ssl)
698 algorithm
699 ✗ wholedim := containWholeDim2(ssl,ty);
700 then
701 wholedim;
702 case DAE.CREF_QUAL(_,_,_,cr)
703 algorithm
704 ✗ wholedim := containWholeDim(cr);
705 then
706 wholedim;
707 else false;
708 end match;
709 end containWholeDim;
710
711 public function traverseCref
712 replaceable type Type_a subtypeof Any;
713 input DAE.ComponentRef cref;
714 input FuncType func;
715 input Type_a argIn;
716 output Type_a argOut;
717 partial function FuncType
718 input DAE.ComponentRef crefIn;
719 input Type_a inType;
720 output Type_a outType;
721 end FuncType;
722 algorithm
723 argOut := matchcontinue cref
724 local
725 DAE.ComponentRef cr;
726 Type_a arg;
727 case DAE.CREF_IDENT(_,_,_)
728 algorithm
729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14186 times.
14186 arg := func(cref,argIn);
730 then arg;
731 case DAE.CREF_QUAL(_,_,_,cr)
732 algorithm
733
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22222 times.
22222 arg := func(cref,argIn);
734 22222 then traverseCref(cr,func,arg);
735 else
736 algorithm
737 ✗ print("traverseCref failed!");
738 ✗ then fail();
739 end matchcontinue;
740 end traverseCref;
741
742 public function crefIsRec"traverse function to check if one of the crefs is a record"
743 input DAE.ComponentRef cref;
744 input Boolean isRecIn;
745 output Boolean isRec;
746 algorithm
747 // is this case the last ident needs a consideration
748
2/4
✓ Branch 0 taken 36408 times.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36408 times.
36408 isRec := isRecIn or Types.isRecord(crefLastType(cref));
749 end crefIsRec;
750
751 public function crefGetFirstRec
752 input DAE.ComponentRef cref;
753 output DAE.ComponentRef result;
754 output Boolean isRec;
755 algorithm
756 (result, isRec) := match cref
757 local
758 DAE.ComponentRef innerCref;
759 273888 case DAE.CREF_IDENT() then (cref, Types.isRecord(crefType(cref)));
760 case DAE.CREF_QUAL() algorithm
761
2/2
✓ Branch 2 taken 129767 times.
✓ Branch 3 taken 1036386 times.
1166153 if Types.isRecord(crefType(cref)) then
762 129767 result := DAE.CREF_IDENT(cref.ident, cref.identType, cref.subscriptLst);
763 129767 isRec := true;
764 else
765 1036386 (innerCref, isRec) := crefGetFirstRec(cref.componentRef);
766 1036386 result := DAE.CREF_QUAL(cref.ident, cref.identType, cref.subscriptLst, innerCref);
767 end if;
768 1166153 then (result, isRec);
769 else (cref, false);
770 end match;
771 end crefGetFirstRec;
772
773 protected function containWholeDim2 "
774 A function to check if a cref contains a [:] wholedim element in the subscriptlist."
775 input list<DAE.Subscript> inRef;
776 input DAE.Type inType;
777 output Boolean wholedim;
778 algorithm
779 wholedim := matchcontinue(inRef,inType)
780 local
781 list<DAE.Subscript> ssl;
782 Boolean b;
783 DAE.Type tty;
784 DAE.Dimensions ad;
785 DAE.Exp es1;
786
787 case({},_) then false;
788
789 case((DAE.WHOLEDIM())::_,DAE.T_ARRAY()) then true;
790
791 case((DAE.SLICE(es1))::_, DAE.T_ARRAY(dims=ad))
792 algorithm
793 ✗ true := containWholeDim3(es1,ad);
794 then
795 true;
796
797 case(_::ssl,DAE.T_ARRAY(tty,ad))
798 algorithm
799 ✗ ad := List.restOrEmpty(ad);
800 ✗ b := containWholeDim2(ssl,DAE.T_ARRAY(tty,ad));
801 then
802 b;
803
804 case(_::ssl,_)
805 algorithm
806 ✗ wholedim := containWholeDim2(ssl,inType);
807 then
808 wholedim;
809 end matchcontinue;
810 end containWholeDim2;
811
812 protected function containWholeDim3 "Verify that a slice adresses all dimensions"
813 input DAE.Exp inExp;
814 input DAE.Dimensions ad;
815 output Boolean ob;
816 algorithm
817 ob := matchcontinue(inExp,ad)
818 local
819 list<DAE.Exp> expl;
820 Integer x1,x2;
821 DAE.Dimension d;
822
823 case(DAE.ARRAY(array=expl), d :: _)
824 algorithm
825 ✗ x1 := listLength(expl);
826 ✗ x2 := Expression.dimensionSize(d);
827 ✗ true := intEq(x1, x2);
828 then
829 true;
830
831 else false;
832 end matchcontinue;
833 end containWholeDim3;
834
835 /***************************************************/
836 /* Getter */
837 /***************************************************/
838
839 public function crefArrayGetFirstCref
840 "mahge: This function is used to get the first element in
841 an array cref if the cref was to be expanded. e.g.
842 (a->nonarray, b->array) given a.b[1] return a.b[1].
843 (a->nonarray, b->array) given a.b return a.b[1].
844 (a->array, b->array) given a[1].b return a[1].b[1]
845 (a->array, b->array) given a[2].b return a[2].b[1]
846 i.e essentially filling the missing subs with 1.
847 "
848 input DAE.ComponentRef inComponentRef;
849 output DAE.ComponentRef outComponentRef;
850 algorithm
851 outComponentRef := match inComponentRef
852 local
853 DAE.ComponentRef cr;
854 list<DAE.Dimension> dims;
855 list<DAE.Subscript> subs, newsubs;
856 Integer diff;
857 DAE.Type ty;
858 DAE.Ident i;
859
860 case DAE.CREF_IDENT(i, ty, subs)
861 algorithm
862 1915437 dims := TypesDump.getDimensions(ty);
863 1915437 diff := listLength(dims) - listLength(subs);
864 1915437 newsubs := List.fill(DAE.INDEX(DAE.ICONST(1)), diff);
865 1915437 then
866 DAE.CREF_IDENT(i, ty, listAppend(subs,newsubs));
867
868 case DAE.CREF_QUAL(i, ty, subs, cr)
869 algorithm
870 3794138 dims := TypesDump.getDimensions(ty);
871 3794138 diff := listLength(dims) - listLength(subs);
872 3794138 newsubs := List.fill(DAE.INDEX(DAE.ICONST(1)), diff);
873 3794138 cr := crefArrayGetFirstCref(cr);
874 3794138 then
875 DAE.CREF_QUAL(i, ty, listAppend(subs,newsubs), cr);
876 end match;
877 end crefArrayGetFirstCref;
878
879
880 public function crefLastPath
881 "Returns the last identifier of a cref as an Absyn.IDENT."
882 input DAE.ComponentRef inComponentRef;
883 output Absyn.Path outPath;
884 algorithm
885 outPath := match inComponentRef
886 local
887 DAE.Ident i;
888 DAE.ComponentRef c;
889 12593 case DAE.CREF_IDENT(ident = i, subscriptLst = {}) then Absyn.IDENT(i);
890 23852 case DAE.CREF_QUAL(componentRef = c, subscriptLst = {}) then crefLastPath(c);
891 end match;
892 end crefLastPath;
893
894 public function crefRest
895 input DAE.ComponentRef inCref;
896 output DAE.ComponentRef outCref;
897 algorithm
898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1329727 times.
1329727 DAE.CREF_QUAL(componentRef = outCref) := inCref;
899 end crefRest;
900
901 protected function crefTypeFullComputeDims
902 input list<DAE.Dimension> inDims;
903 input list<DAE.Subscript> inSubs;
904 output list<DAE.Dimension> outDims;
905 protected
906 list<DAE.Dimension> dims;
907 DAE.Dimension dim, slice_dim;
908 algorithm
909 dims := inDims;
910 outDims := {};
911
2/2
✓ Branch 0 taken 723781 times.
✓ Branch 1 taken 3095379 times.
3819160 for sub in inSubs loop
912
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 723779 times.
✓ Branch 3 taken 723765 times.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
723781 dim::dims := dims;
913
914 () := match sub
915 case DAE.INDEX() then ();
916
917 case DAE.SLICE() algorithm
918
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 slice_dim::_ := TypesDump.getDimensions(Expression.typeof(sub.exp));
919 outDims := slice_dim::outDims;
920 then ();
921
922 case DAE.WHOLEDIM() algorithm
923 outDims := dim::outDims;
924 then ();
925
926 end match;
927
928 end for;
929
930 3095379 outDims := listAppend(outDims, dims) annotation(__OpenModelica_DisableListAppendWarning=true);
931
932 end crefTypeFullComputeDims;
933
934 public function crefTypeFull2
935 "Helper function to crefTypeFull."
936 input DAE.ComponentRef inCref;
937 input list<DAE.Dimension> accumDims = {};
938 output DAE.Type outType;
939 output list<DAE.Dimension> outDims;
940 algorithm
941 (outType, outDims) := match inCref
942 local
943 DAE.ComponentRef cr;
944 DAE.Type ty, basety;
945 list<DAE.Dimension> dims;
946 list<DAE.Subscript> subs;
947
948 case DAE.CREF_IDENT(identType = ty, subscriptLst = subs)
949 algorithm
950 912495 (ty,dims) := TypesDump.flattenArrayType(ty);
951 912495 dims := crefTypeFullComputeDims(dims, subs);
952
953
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 912484 times.
912495 if not listEmpty(accumDims) then
954 11 dims := listReverse(List.append_reverse(dims, accumDims));
955 end if;
956
1/2
✓ Branch 0 taken 912495 times.
✗ Branch 1 not taken.
912495 then (ty, dims);
957
958 case DAE.CREF_QUAL(identType = ty, subscriptLst = subs, componentRef = cr)
959 algorithm
960 2182886 (ty,dims) := TypesDump.flattenArrayType(ty);
961 2182886 dims := crefTypeFullComputeDims(dims, subs);
962
963 2182884 (basety, dims) := crefTypeFull2(cr, List.append_reverse(dims, accumDims));
964 then (basety, dims);
965
966 else
967 algorithm
968 ✗ true := Flags.isSet(Flags.FAILTRACE);
969 ✗ Debug.trace("ComponentReference.crefTypeFull2 failed on cref: ");
970 ✗ Debug.traceln(ComponentReferenceBasics.printComponentRefStr(inCref));
971 ✗ then
972 fail();
973 end match;
974 end crefTypeFull2;
975
976 public function crefTypeFull
977 "mahge:
978 This function gives the type of a cref.
979 This is done by considering how many dimensions and subscripts
980 the cref has. It also takes in to consideration where the subscripts
981 are loacated in a qualifed cref. e.g. consider :
982 record R
983 Real [4]
984 end R;
985
986 R a[3][2];
987
988 if we have a cref a[1][1].b[1] --> Real
989 a[1].b --> Real[2][4]
990 a.b[1] --> Real[3][2]
991 a[1][1].b --> Real[4]
992 a[1].b[1] --> Real[2]
993
994 "
995 input DAE.ComponentRef inCref;
996 output DAE.Type outType;
997 protected
998 DAE.Type ty;
999 list<DAE.Dimension> dims;
1000 algorithm
1001 890663 (ty,dims) := crefTypeFull2(inCref);
1002
2/2
✓ Branch 0 taken 2340 times.
✓ Branch 1 taken 888321 times.
890661 if listEmpty(dims) then
1003 outType := ty;
1004 else
1005 2340 outType := DAE.T_ARRAY(ty, dims);
1006 end if;
1007 end crefTypeFull;
1008
1009 public function crefType
1010 " ***deprecated. Use crefTypeFull unless you really specifically want the type of the first cref.
1011 Function for extracting the type of the first identifier of a cref.
1012 "
1013 input DAE.ComponentRef inCref;
1014 output DAE.Type outType;
1015 algorithm
1016 outType := match inCref
1017 local
1018 DAE.Type ty;
1019
1020 case DAE.CREF_IDENT(identType = ty) then ty;
1021 case DAE.CREF_QUAL(identType = ty) then ty;
1022
1023 else
1024 algorithm
1025 ✗ true := Flags.isSet(Flags.FAILTRACE);
1026 ✗ Debug.trace("ComponentReference.crefType failed on cref: ");
1027 ✗ Debug.traceln(ComponentReferenceBasics.printComponentRefStr(inCref));
1028 ✗ then
1029 fail();
1030
1031 end match;
1032 end crefType;
1033
1034 public function crefLastType
1035 " ***deprecated.
1036 mahge: Use crefTypeFull unless you really specifically want the type of the last cref.
1037 Remember the type of a cref is not the same as the type of the last cref!!.
1038
1039 returns the 'last' type of a cref.
1040 For instance, for the cref 'a.b' it returns the type in identifier 'b'
1041 adrpo:
1042 NOTE THAT THIS WILL BE AN ARRAY TYPE IF THE LAST CREF IS AN ARRAY TYPE
1043 If you want to get the component reference type considering subscripts use:
1044 crefTypeConsiderSubs"
1045 input DAE.ComponentRef inRef;
1046 output DAE.Type res;
1047 algorithm
1048 res := match inRef
1049 local
1050 DAE.Type t2;
1051 DAE.ComponentRef cr;
1052
1053 case DAE.CREF_IDENT(_,t2,_) then t2;
1054 5455177 case DAE.CREF_QUAL(_,_,_,cr) then crefLastType(cr);
1055 end match;
1056 end crefLastType;
1057
1058 public function crefFirstSubs
1059 input DAE.ComponentRef inCref;
1060 output list<DAE.Subscript> outSubscripts;
1061 algorithm
1062 outSubscripts := match inCref
1063 2677324 case DAE.CREF_IDENT() then inCref.subscriptLst;
1064 2295852 case DAE.CREF_QUAL() then inCref.subscriptLst;
1065 else {};
1066 end match;
1067 end crefFirstSubs;
1068
1069 public function crefLastSubs "Return the last subscripts of a ComponentRef"
1070 input DAE.ComponentRef inComponentRef;
1071 output list<DAE.Subscript> outSubscriptLst;
1072 algorithm
1073 outSubscriptLst := match inComponentRef
1074 local
1075 list<DAE.Subscript> subs;
1076 DAE.ComponentRef cr;
1077 case DAE.CREF_IDENT(subscriptLst = subs)
1078 then subs;
1079 case DAE.CREF_QUAL(componentRef = cr)
1080 2969833 then crefLastSubs(cr);
1081 end match;
1082 end crefLastSubs;
1083
1084 public function crefTypeConsiderSubs
1085 " ***deprecated.
1086 mahge: use crefTypeFull(). This is not what you want. We need to consider not just the last subs but all subs.
1087 We can have slices.
1088
1089 Function: crefTypeConsiderSubs
1090 Author: PA
1091 Function for extracting the type out of a componentReference and consider the influence of the last subscript list.
1092 For exampel. If the last cref type is Real[3,3] and the last subscript list is {Expression.INDEX(1)}, the type becomes Real[3], i.e
1093 one dimension is lifted.
1094 See also, crefType.
1095 "
1096 input DAE.ComponentRef cr;
1097 output DAE.Type res;
1098 algorithm
1099 46538 res := Expression.unliftArrayTypeWithSubs(crefLastSubs(cr),crefLastType(cr));
1100 end crefTypeConsiderSubs;
1101
1102 public function crefNameType "Function: crefType
1103 Function for extracting the name and type out of the first cref of a componentReference.
1104 "
1105 input DAE.ComponentRef inRef;
1106 output DAE.Ident id;
1107 output DAE.Type res;
1108 algorithm
1109 (id,res) :=
1110 match inRef
1111 local
1112 DAE.Type t2;
1113 DAE.Ident name;
1114 String s;
1115
1116 case DAE.CREF_IDENT(name,t2,_) then (name,t2);
1117
1118 case DAE.CREF_QUAL(name,t2,_,_) then (name,t2);
1119
1120 else
1121 algorithm
1122 ✗ true := Flags.isSet(Flags.FAILTRACE);
1123 ✗ Debug.trace("-ComponentReference.crefType failed on Cref:");
1124 ✗ s := ComponentReferenceBasics.printComponentRefStr(inRef);
1125 ✗ Debug.traceln(s);
1126 ✗ then
1127 fail();
1128 end match;
1129 end crefNameType;
1130
1131 public function getArrayCref
1132 input DAE.ComponentRef name;
1133 output Option<DAE.ComponentRef> arrayCref;
1134 algorithm
1135 arrayCref := matchcontinue name
1136 local
1137 DAE.ComponentRef arrayCrefInner;
1138
1139 case _ algorithm
1140
2/2
✓ Branch 1 taken 370080 times.
✓ Branch 2 taken 48625 times.
418705 true := crefIsFirstArrayElt(name);
1141
4/4
✓ Branch 1 taken 1434 times.
✓ Branch 2 taken 47191 times.
✓ Branch 5 taken 1425 times.
✓ Branch 6 taken 9 times.
48625 if (stringEqual(Config.simCodeTarget(), "Cpp")) then
1142 1425 arrayCrefInner := ComponentReferenceBasics.crefStripLastSubs(name);
1143 else
1144 47200 arrayCrefInner := crefStripSubs(name);
1145 end if;
1146 then SOME(arrayCrefInner);
1147
1148 else
1149 then NONE();
1150 end matchcontinue;
1151 end getArrayCref;
1152
1153 public function getArraySubs
1154 input DAE.ComponentRef name;
1155 output list<DAE.Subscript> arraySubs;
1156 algorithm
1157 arraySubs := matchcontinue name
1158 local
1159 list<DAE.Subscript> arrayCrefSubs;
1160
1161 case _ algorithm
1162 ✗ arrayCrefSubs := ComponentReferenceBasics.crefSubs(name);
1163 then arrayCrefSubs;
1164
1165 else
1166 then {};
1167 end matchcontinue;
1168 end getArraySubs;
1169
1170 /***************************************************/
1171 /* Change */
1172 /***************************************************/
1173
1174 public function crefPrependIdent "prepends (e..g as a suffix) an identifier to a component reference, given the identifier, subscript and the type
1175 author: PA
1176
1177 The crefPrependIdent function extends a ComponentRef by appending
1178 an identifier and a (possibly empty) list of subscripts. Adding
1179 the identifier A to the component reference x.y[10] would
1180 produce the component reference x.y[10].A, for instance.
1181
1182 Example
1183 crefPrependIdent(a.b,c,{},Real) => a.b.c [Real]
1184 crefPrependIdent(a,c,{1},Integer[1]) => a.c[1] [Integer[1]]
1185
1186 alternative names: crefAddSuffix, crefAddIdent
1187 "
1188 input DAE.ComponentRef icr;
1189 input DAE.Ident ident;
1190 input list<DAE.Subscript> subs;
1191 input DAE.Type tp;
1192 output DAE.ComponentRef newCr;
1193 algorithm
1194 newCr := match icr
1195 local
1196 DAE.Type tp1;
1197 String id1;
1198 list<DAE.Subscript> subs1;
1199 DAE.ComponentRef cr;
1200
1201 case DAE.CREF_IDENT(id1,tp1,subs1)
1202 1992668 then
1203 ComponentReferenceBasics.makeCrefQual(id1,tp1,subs1,ComponentReferenceBasics.makeCrefIdent(ident,tp,subs));
1204
1205 case DAE.CREF_QUAL(id1,tp1,subs1,cr)
1206 algorithm
1207 1673232 cr := crefPrependIdent(cr,ident,subs,tp);
1208 1673232 then
1209 ComponentReferenceBasics.makeCrefQual(id1,tp1,subs1,cr);
1210 end match;
1211 end crefPrependIdent;
1212
1213 public function crefPrefixDer "public function crefPrefixDer
1214 Appends $DER to a cref, so a => $DER.a"
1215 input DAE.ComponentRef inCref;
1216 output DAE.ComponentRef outCref;
1217 algorithm
1218 97647 outCref := ComponentReferenceBasics.makeCrefQual(DAE.derivativeNamePrefix, DAE.T_REAL_DEFAULT, {}, inCref);
1219 end crefPrefixDer;
1220
1221 public function crefPrefixPre "public function crefPrefixPre
1222 Appends $PRE to a cref, so a => $PRE.a"
1223 input DAE.ComponentRef inCref;
1224 output DAE.ComponentRef outCref;
1225 algorithm
1226 222966 outCref := ComponentReferenceBasics.makeCrefQual(DAE.preNamePrefix, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
1227 end crefPrefixPre;
1228
1229 public function getConcealedCref "public function getConcealedCref
1230 Replaces a cref to concealed so a => $concealed1"
1231 output DAE.ComponentRef outCref;
1232 protected
1233 String ident;
1234 algorithm
1235 2 ident := "$concealed" + intString(System.tmpTick()+1);
1236 2 outCref := ComponentReferenceBasics.makeCrefIdent(ident, DAE.T_UNKNOWN_DEFAULT, {});
1237 end getConcealedCref;
1238
1239 public function crefPrefixPrevious "public function crefPrefixPrevious
1240 Appends $CLKPRE to a cref, so a => $CLKPRE.a"
1241 input DAE.ComponentRef inCref;
1242 output DAE.ComponentRef outCref;
1243 algorithm
1244 1369 outCref := ComponentReferenceBasics.makeCrefQual(DAE.previousNamePrefix, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
1245 end crefPrefixPrevious;
1246
1247 public function crefPrefixAux "public function crefPrefixAux
1248 Appends $AUX to a cref, so a => $AUX.a"
1249 input DAE.ComponentRef inCref;
1250 output DAE.ComponentRef outCref;
1251 algorithm
1252 ✗ outCref := ComponentReferenceBasics.makeCrefQual(DAE.auxNamePrefix, DAE.T_REAL_DEFAULT, {}, inCref);
1253 end crefPrefixAux;
1254
1255 public function crefRemovePrePrefix
1256 "Strips a leading $PRE or $START qualifier from a cref. Used by the code
1257 generation templates before looking up a SimVar (cref2simvar) to obtain
1258 index/nominal/min/max info: $PRE.x and $START.x are not SimVars of their
1259 own, they share the storage of x, so they must resolve to x's SimVar.
1260 Without stripping $START the lookup fails and emits the -2
1261 ERROR_simVarFromHT_failed sentinel, which crashes at runtime when used as
1262 a scalar index (ticket #15433, nested initialization nonlinear systems
1263 iterating over $START.<var>)."
1264 input output DAE.ComponentRef cref;
1265 algorithm
1266 cref := match cref
1267 8 case DAE.CREF_QUAL(ident=DAE.preNamePrefix) then cref.componentRef;
1268 ✗ case DAE.CREF_QUAL(ident=DAE.startNamePrefix) then cref.componentRef;
1269 else cref;
1270 end match;
1271 end crefRemovePrePrefix;
1272
1273 public function crefPrefixStart "public function crefPrefixStart
1274 Appends $START to a cref, so a => $START.a"
1275 input DAE.ComponentRef inCref;
1276 output DAE.ComponentRef outCref;
1277 algorithm
1278 326622 outCref := ComponentReferenceBasics.makeCrefQual(DAE.startNamePrefix, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
1279 end crefPrefixStart;
1280
1281 public function crefPrefixString
1282 "Prefixes a cref with a string identifier, e.g.:
1283 crefPrefixString(a, b.c) => a.b.c"
1284 input String inString;
1285 input DAE.ComponentRef inCref;
1286 output DAE.ComponentRef outCref;
1287 algorithm
1288 42 outCref := ComponentReferenceBasics.makeCrefQual(inString, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
1289 end crefPrefixString;
1290
1291 public function crefPrefixStringList
1292 "Prefixes a cref with a list of strings, e.g.:
1293 crefPrefixStringList({a, b, c}, d.e.f) => a.b.c.d.e.f"
1294 input list<String> inStrings;
1295 input DAE.ComponentRef inCref;
1296 output DAE.ComponentRef outCref;
1297 algorithm
1298 outCref := match(inStrings, inCref)
1299 local
1300 String str;
1301 list<String> rest_str;
1302 DAE.ComponentRef cref;
1303
1304 case (str :: rest_str, cref)
1305 algorithm
1306 ✗ cref := crefPrefixStringList(rest_str, cref);
1307 ✗ cref := crefPrefixString(str, cref);
1308 then
1309 cref;
1310
1311 else inCref;
1312
1313 end match;
1314 end crefPrefixStringList;
1315
1316 public function prefixWithPath
1317 input DAE.ComponentRef inCref;
1318 input Absyn.Path inPath;
1319 output DAE.ComponentRef outCref;
1320 algorithm
1321 outCref := match inPath
1322 local
1323 Absyn.Ident name;
1324 Absyn.Path rest_path;
1325 DAE.ComponentRef cref;
1326
1327 case Absyn.IDENT(name = name)
1328 ✗ then DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, inCref);
1329
1330 case Absyn.QUALIFIED(name = name, path = rest_path)
1331 algorithm
1332 ✗ cref := prefixWithPath(inCref, rest_path);
1333 ✗ then
1334 DAE.CREF_QUAL(name, DAE.T_UNKNOWN_DEFAULT, {}, cref);
1335
1336 case Absyn.FULLYQUALIFIED(path = rest_path)
1337 ✗ then prefixWithPath(inCref, rest_path);
1338
1339 end match;
1340 end prefixWithPath;
1341
1342 public function prependStringCref
1343 "Prepend a string to a component reference.
1344 For qualified named, this means prepending a
1345 string to the first identifier."
1346 input String inString;
1347 input DAE.ComponentRef inComponentRef;
1348 output DAE.ComponentRef outComponentRef;
1349 algorithm
1350 outComponentRef := match (inString,inComponentRef)
1351 local
1352 DAE.Ident i_1,p,i;
1353 list<DAE.Subscript> s;
1354 DAE.ComponentRef c;
1355 DAE.Type t2;
1356
1357 case (p,DAE.CREF_QUAL(ident = i, identType = t2, subscriptLst = s,componentRef = c))
1358 algorithm
1359 8883 i_1 := stringAppend(p, i);
1360 8883 then
1361 ComponentReferenceBasics.makeCrefQual(i_1,t2,s,c);
1362
1363 case (p,DAE.CREF_IDENT(ident = i, identType = t2, subscriptLst = s))
1364 algorithm
1365 10905 i_1 := stringAppend(p, i);
1366 10905 then
1367 ComponentReferenceBasics.makeCrefIdent(i_1,t2,s);
1368 end match;
1369 end prependStringCref;
1370
1371 public function appendStringCref
1372 input String str;
1373 input DAE.ComponentRef cr;
1374 output DAE.ComponentRef ocr;
1375 algorithm
1376 200532 ocr := joinCrefs(cr,DAE.CREF_IDENT(str,DAE.T_UNKNOWN_DEFAULT,{}));
1377 end appendStringCref;
1378
1379 public function appendStringFirstIdent
1380 "Appends a string to the first identifier of a cref."
1381 input String inString;
1382 input DAE.ComponentRef inCref;
1383 output DAE.ComponentRef outCref;
1384 algorithm
1385 outCref := match inCref
1386 local
1387 DAE.Ident id;
1388 list<DAE.Subscript> subs;
1389 DAE.ComponentRef cr;
1390 DAE.Type ty;
1391
1392 case DAE.CREF_QUAL(id, ty, subs, cr)
1393 algorithm
1394 7 id := stringAppend(id, inString);
1395 7 then DAE.CREF_QUAL(id, ty, subs, cr);
1396
1397 case DAE.CREF_IDENT(id, ty, subs)
1398 algorithm
1399 3071 id := stringAppend(id, inString);
1400 3071 then
1401 DAE.CREF_IDENT(id, ty, subs);
1402
1403 end match;
1404 end appendStringFirstIdent;
1405
1406 public function appendStringLastIdent
1407 "Appends a string to the last identifier of a cref."
1408 input String inString;
1409 input DAE.ComponentRef inCref;
1410 output DAE.ComponentRef outCref;
1411 algorithm
1412 outCref := match inCref
1413 local
1414 DAE.Ident id;
1415 list<DAE.Subscript> subs;
1416 DAE.ComponentRef cr;
1417 DAE.Type ty;
1418
1419 case DAE.CREF_QUAL(id, ty, subs, cr)
1420 algorithm
1421 32 cr := appendStringLastIdent(inString,cr);
1422 32 then DAE.CREF_QUAL(id, ty, subs, cr);
1423
1424 case DAE.CREF_IDENT(id, ty, subs)
1425 algorithm
1426 1792 id := stringAppend(id, inString);
1427 1792 then
1428 DAE.CREF_IDENT(id, ty, subs);
1429
1430 end match;
1431 end appendStringLastIdent;
1432
1433 public function joinCrefs
1434 "Joins two component references by concatenating them.
1435 alternative names: crefAppend
1436 "
1437 input DAE.ComponentRef inComponentRef1 " first part of the new componentref";
1438 input DAE.ComponentRef inComponentRef2 " last part of the new componentref";
1439 output DAE.ComponentRef outComponentRef;
1440 algorithm
1441 outComponentRef := match (inComponentRef1,inComponentRef2)
1442 local
1443 DAE.Ident id;
1444 list<DAE.Subscript> sub;
1445 DAE.ComponentRef cr2,cr_1,cr;
1446 DAE.Type t2;
1447
1448 case (DAE.CREF_IDENT(ident = id, identType = t2, subscriptLst = sub),cr2)
1449 1257522 then
1450 ComponentReferenceBasics.makeCrefQual(id,t2,sub,cr2);
1451
1452 case (DAE.CREF_QUAL(ident = id, identType = t2, subscriptLst = sub,componentRef = cr),cr2)
1453 algorithm
1454 1077241 cr_1 := joinCrefs(cr, cr2);
1455 1077241 then
1456 ComponentReferenceBasics.makeCrefQual(id,t2,sub,cr_1);
1457 end match;
1458 end joinCrefs;
1459
1460 public function joinCrefsR
1461 "like joinCrefs but with last part as first argument."
1462 input DAE.ComponentRef inComponentRef2 " last part of the new componentref";
1463 input DAE.ComponentRef inComponentRef1 " first part of the new componentref";
1464 output DAE.ComponentRef outComponentRef;
1465 algorithm
1466 outComponentRef := match (inComponentRef2,inComponentRef1)
1467 local
1468 DAE.Ident id;
1469 list<DAE.Subscript> sub;
1470 DAE.ComponentRef cr2,cr_1,cr;
1471 DAE.Type t2;
1472
1473 case (cr2,DAE.CREF_IDENT(ident = id, identType = t2, subscriptLst = sub))
1474 98097 then
1475 ComponentReferenceBasics.makeCrefQual(id,t2,sub,cr2);
1476
1477 case (cr2,DAE.CREF_QUAL(ident = id, identType = t2, subscriptLst = sub,componentRef = cr))
1478 algorithm
1479 2278 cr_1 := joinCrefs(cr, cr2);
1480 2278 then
1481 ComponentReferenceBasics.makeCrefQual(id,t2,sub,cr_1);
1482 end match;
1483 end joinCrefsR;
1484
1485 public function joinCrefsExp
1486 "Like joinCrefs but first argument is an expression"
1487 input output DAE.Exp exp;
1488 input output DAE.ComponentRef cref;
1489 algorithm
1490 exp := match exp
1491 local
1492 DAE.ComponentRef cr;
1493 DAE.Type tp;
1494 case DAE.CREF(cr, tp)
1495 algorithm
1496 2 cr := joinCrefs(cref, cr);
1497 2 then
1498 DAE.CREF(cr,tp);
1499 else exp;
1500 end match;
1501 end joinCrefsExp;
1502
1503 public function subscriptCref
1504 "The subscriptCref function adds a subscript to the ComponentRef
1505 For instance a.b with subscript 10 becomes a.b[10] and c.d[1,2]
1506 with subscript 3,4 becomes c.d[1,2,3,4]"
1507 input DAE.ComponentRef inComponentRef;
1508 input list<DAE.Subscript> inSubscriptLst;
1509 output DAE.ComponentRef outComponentRef;
1510 algorithm
1511 outComponentRef := match (inComponentRef,inSubscriptLst)
1512 local
1513 list<DAE.Subscript> newsub_1,sub,newsub;
1514 DAE.Ident id;
1515 DAE.ComponentRef cref_1,cref;
1516 DAE.Type t2;
1517
1518 case (DAE.CREF_IDENT(ident = id,subscriptLst = sub, identType = t2),newsub)
1519 algorithm
1520 114550 newsub_1 := listAppend(sub, newsub);
1521 114550 then
1522 ComponentReferenceBasics.makeCrefIdent(id, t2, newsub_1);
1523
1524 case (DAE.CREF_QUAL(ident = id,subscriptLst = sub,componentRef = cref, identType = t2),newsub)
1525 algorithm
1526 265345 cref_1 := subscriptCref(cref, newsub);
1527 265345 then
1528 ComponentReferenceBasics.makeCrefQual(id, t2, sub,cref_1);
1529 end match;
1530 end subscriptCref;
1531
1532 public function subscriptCrefWithInt
1533 "Subscripts a component reference with a constant integer. It also unlifts the
1534 type of the components reference so that the type of the reference is correct
1535 with regards to the subscript. If the reference is not of array type this
1536 function will fail."
1537 input DAE.ComponentRef inComponentRef;
1538 input Integer inSubscript;
1539 output DAE.ComponentRef outComponentRef;
1540 algorithm
1541 outComponentRef := match inComponentRef
1542 local
1543 list<DAE.Subscript> subs;
1544 DAE.Subscript new_sub;
1545 DAE.Ident id;
1546 DAE.ComponentRef rest_cref;
1547 DAE.Type ty;
1548
1549 case DAE.CREF_IDENT(ident = id, subscriptLst = subs, identType = ty)
1550 algorithm
1551 48 new_sub := DAE.INDEX(DAE.ICONST(inSubscript));
1552 48 subs := List.appendElt(new_sub, subs);
1553 48 ty := Expression.unliftArray(ty);
1554 48 then
1555 ComponentReferenceBasics.makeCrefIdent(id, ty, subs);
1556
1557 case DAE.CREF_QUAL(ident = id, subscriptLst = subs,
1558 componentRef = rest_cref, identType = ty)
1559 algorithm
1560 26 rest_cref := subscriptCrefWithInt(rest_cref, inSubscript);
1561 26 then
1562 ComponentReferenceBasics.makeCrefQual(id, ty, subs, rest_cref);
1563
1564 end match;
1565 end subscriptCrefWithInt;
1566
1567 public function crefSetLastSubs "sets the subs of the last componenentref ident"
1568 input DAE.ComponentRef inComponentRef;
1569 input list<DAE.Subscript> inSubs;
1570 output DAE.ComponentRef outComponentRef;
1571 algorithm
1572 outComponentRef := match inComponentRef
1573 local
1574 DAE.Ident id;
1575 DAE.Type tp;
1576 list<DAE.Subscript> subs;
1577 DAE.ComponentRef cr;
1578
1579 case DAE.CREF_IDENT(ident=id, identType=tp)
1580 115033 then ComponentReferenceBasics.makeCrefIdent(id, tp, inSubs);
1581
1582 case DAE.CREF_QUAL(ident=id, identType=tp, subscriptLst=subs, componentRef=cr) algorithm
1583 394166 cr := crefSetLastSubs(cr, inSubs);
1584 394166 then ComponentReferenceBasics.makeCrefQual(id, tp, subs, cr);
1585 end match;
1586 end crefSetLastSubs;
1587
1588 public function crefApplySubs
1589 "Apply subs to the first componenentref idents that are of array type.
1590 author: rfranke"
1591 input DAE.ComponentRef inComponentRef;
1592 input list<DAE.Subscript> inSubs;
1593 output DAE.ComponentRef outComponentRef;
1594 algorithm
1595 outComponentRef := match inComponentRef
1596 local
1597 DAE.Ident id;
1598 DAE.Type tp;
1599 list<DAE.Subscript> subs, subs1, subs2;
1600 DAE.ComponentRef cr;
1601 DAE.Dimensions dims;
1602
1603 case DAE.CREF_IDENT(ident = id, identType = tp as DAE.T_ARRAY(dims = dims), subscriptLst = subs)
1604 algorithm
1605
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 407 times.
407 if listLength(subs) + listLength(inSubs) > listLength(dims) then
1606 ✗ Error.addInternalError("ComponentReference.crefApplySubs ["
1607 + ExpressionBasics.printListStr(inSubs, ExpressionBasics.printSubscriptStr, ",") + "] to ident "
1608 + ComponentReferenceBasics.printComponentRefStr(inComponentRef) + " with " + intString(listLength(dims)) + " dimensions\n", sourceInfo());
1609 ✗ fail();
1610 end if;
1611 407 then
1612 ComponentReferenceBasics.makeCrefIdent(id, tp, listAppend(subs, inSubs));
1613
1614 case DAE.CREF_QUAL(ident = id, identType = tp as DAE.T_ARRAY(dims = dims), subscriptLst = subs, componentRef = cr)
1615 algorithm
1616
2/2
✓ Branch 3 taken 159 times.
✓ Branch 4 taken 44 times.
203 if listLength(inSubs) > listLength(dims) - listLength(subs) then
1617 159 (subs1, subs2) := List.split(inSubs, listLength(dims) - listLength(subs));
1618 159 cr := crefApplySubs(cr, subs2);
1619 else
1620 subs1 := inSubs;
1621 end if;
1622
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 203 times.
203 if listLength(subs) + listLength(subs1) > listLength(dims) then
1623 ✗ Error.addInternalError("ComponentReference.crefApplySubs ["
1624 + ExpressionBasics.printListStr(inSubs, ExpressionBasics.printSubscriptStr, ",") + "] to qual "
1625 + ComponentReferenceBasics.printComponentRefStr(inComponentRef) + " with " + intString(listLength(dims)) + " dimensions\n", sourceInfo());
1626 ✗ fail();
1627 end if;
1628 203 then
1629 ComponentReferenceBasics.makeCrefQual(id, tp, listAppend(subs, subs1), cr);
1630
1631 case DAE.CREF_QUAL(ident = id, identType = tp, subscriptLst = subs, componentRef = cr)
1632 algorithm
1633 550 cr := crefApplySubs(cr, inSubs);
1634 550 then
1635 ComponentReferenceBasics.makeCrefQual(id, tp, subs, cr);
1636
1637 else
1638 algorithm
1639 ✗ Error.addInternalError("ComponentReference.crefApplySubs to non array " + ComponentReferenceBasics.printComponentRefStr(inComponentRef) + "\n", sourceInfo());
1640 ✗ then
1641 fail();
1642 end match;
1643 end crefApplySubs;
1644
1645 public function crefSetType "
1646 sets the type of a cref."
1647 input output DAE.ComponentRef cref;
1648 input DAE.Type ty;
1649 algorithm
1650 cref := match cref
1651 case DAE.CREF_IDENT() algorithm
1652 ✗ cref.identType := ty;
1653 then cref;
1654
1655 case DAE.CREF_QUAL() algorithm
1656 ✗ cref.identType := ty;
1657 then cref;
1658
1659 else algorithm
1660 ✗ Error.addInternalError(getInstanceName() + " was applied on a cref that has no type: " + crefStr(cref), sourceInfo());
1661 ✗ then fail();
1662 end match;
1663 end crefSetType;
1664
1665 public function crefSetLastType "
1666 sets the 'last' type of a cref."
1667 input DAE.ComponentRef inRef;
1668 input DAE.Type newType;
1669 output DAE.ComponentRef outRef;
1670 algorithm
1671 outRef := match inRef
1672 local
1673 DAE.Type ty;
1674 DAE.ComponentRef child;
1675 list<DAE.Subscript> subs;
1676 DAE.Ident id;
1677
1678 case DAE.CREF_IDENT(id,_,subs)
1679 426842 then ComponentReferenceBasics.makeCrefIdent(id,newType,subs);
1680
1681 case DAE.CREF_QUAL(id,ty,subs,child)
1682 algorithm
1683 796797 child := crefSetLastType(child,newType);
1684 796797 then
1685 ComponentReferenceBasics.makeCrefQual(id,ty,subs,child);
1686
1687 end match;
1688 end crefSetLastType;
1689
1690 public function replaceCrefSliceSub "
1691 Go trough ComponentRef searching for a slice eighter in
1692 qual's or finaly ident. if none find, add dimension to DAE.CREF_IDENT(,ss:INPUTARG,)"
1693 input DAE.ComponentRef inCr;
1694 input list<DAE.Subscript> newSub;
1695 output DAE.ComponentRef outCr;
1696 algorithm
1697 outCr := matchcontinue inCr
1698 local
1699 DAE.Type t2,identType;
1700 DAE.ComponentRef child;
1701 list<DAE.Subscript> subs;
1702 String name;
1703
1704 // debugging case, uncomment for enabling
1705 // case(child,newSub)
1706 // equation
1707 // str1 = ComponentReferenceBasics.printComponentRefStr(child);
1708 // str2 = stringDelimitList(List.map(newSub, printSubscriptStr), ", ");
1709 // str = "replaceCrefSliceSub(" + str1 + " subs: [" + str2 + "]\n";
1710 // print(str);
1711 // then
1712 // fail();
1713
1714 // Case where we try to find a Expression.DAE.SLICE()
1715 case DAE.CREF_IDENT(name,identType,subs)
1716 algorithm
1717 ✗ subs := replaceSliceSub(subs, newSub);
1718 ✗ then
1719 ComponentReferenceBasics.makeCrefIdent(name,identType,subs);
1720
1721 // case where there is not existant Expression.DAE.SLICE() as subscript
1722 case DAE.CREF_IDENT(identType = t2, subscriptLst = subs)
1723 algorithm
1724 ✗ true := (listLength(Expression.arrayTypeDimensions(t2)) >= (listLength(subs)+1));
1725 ✗ child := subscriptCref(inCr,newSub);
1726 then
1727 child;
1728
1729 case DAE.CREF_IDENT(identType = t2, subscriptLst = subs)
1730 algorithm
1731 ✗ false := (listLength(Expression.arrayTypeDimensions(t2)) >= (listLength(subs)+listLength(newSub)));
1732 ✗ child := subscriptCref(inCr,newSub);
1733 ✗ if Flags.isSet(Flags.FAILTRACE) then
1734 ✗ Debug.trace("WARNING - Expression.replaceCref_SliceSub setting subscript last, not containing dimension\n");
1735 end if;
1736 then
1737 child;
1738
1739 // Try DAE.CREF_QUAL with DAE.SLICE subscript
1740 case DAE.CREF_QUAL(name,identType,subs,child)
1741 algorithm
1742 ✗ subs := replaceSliceSub(subs, newSub);
1743 ✗ then
1744 ComponentReferenceBasics.makeCrefQual(name,identType,subs,child);
1745
1746 // case where there is not existant Expression.DAE.SLICE() as subscript in CREF_QUAL
1747 case DAE.CREF_QUAL(name,identType,subs,child)
1748 algorithm
1749 ✗ true := (listLength(Expression.arrayTypeDimensions(identType)) >= (listLength(subs)+1));
1750 ✗ then
1751 ComponentReferenceBasics.makeCrefQual(name, identType, listAppend(subs, newSub), child);
1752
1753 // DAE.CREF_QUAL without DAE.SLICE, search child
1754 case DAE.CREF_QUAL(name,identType,subs,child)
1755 algorithm
1756 ✗ child := replaceCrefSliceSub(child,newSub);
1757 ✗ then
1758 ComponentReferenceBasics.makeCrefQual(name,identType,subs,child);
1759
1760 else
1761 algorithm
1762 ✗ true := Flags.isSet(Flags.FAILTRACE);
1763 ✗ Debug.trace("- Expression.replaceCref_SliceSub failed\n");
1764 ✗ then
1765 fail();
1766 end matchcontinue;
1767 end replaceCrefSliceSub;
1768
1769 protected function replaceSliceSub "
1770 A function for replacing any occurance of DAE.SLICE or DAE.WHOLEDIM with new sub."
1771 input list<DAE.Subscript> inSubs;
1772 input list<DAE.Subscript> inSub;
1773 output list<DAE.Subscript> osubs;
1774 algorithm
1775 osubs := match inSubs
1776 local
1777 list<DAE.Subscript> subs;
1778 DAE.Subscript sub;
1779
1780 case (DAE.SLICE(_))::subs
1781 algorithm
1782 ✗ subs := listAppend(inSub,subs);
1783 then
1784 subs;
1785
1786 // adrpo, 2010-02-23:
1787 // WHOLEDIM is *also* a special case of SLICE
1788 // that contains the all subscripts, so we need
1789 // to handle that too here!
1790 case (DAE.WHOLEDIM())::subs
1791 algorithm
1792 ✗ subs := listAppend(inSub,subs);
1793 then
1794 subs;
1795
1796 case (sub)::subs
1797 algorithm
1798 ✗ subs := replaceSliceSub(subs,inSub);
1799 then
1800 (sub::subs);
1801 end match;
1802 end replaceSliceSub;
1803
1804 public function stripCrefIdentSliceSubs "
1805 Author BZ
1806 Strips the SLICE-subscripts fromt the -last- subscript list. All other subscripts are not changed.
1807 For example
1808 x[1].y[{1,2},3,{1,3,7}] => x[1].y[3]
1809 Alternative names: stripLastSliceSubs"
1810 input DAE.ComponentRef inCref;
1811 output DAE.ComponentRef outCref;
1812 algorithm
1813 outCref := match inCref
1814 local
1815 DAE.Ident id;
1816 DAE.ComponentRef cr;
1817 DAE.Type ty;
1818 list<DAE.Subscript> subs;
1819
1820 case DAE.CREF_IDENT(ident = id,subscriptLst=subs, identType = ty)
1821 algorithm
1822 ✗ subs := removeSliceSubs(subs);
1823 ✗ then
1824 ComponentReferenceBasics.makeCrefIdent(id,ty,subs);
1825
1826 case DAE.CREF_QUAL(componentRef = cr, identType=ty, subscriptLst=subs, ident=id)
1827 algorithm
1828 ✗ outCref := stripCrefIdentSliceSubs(cr);
1829 ✗ then
1830 ComponentReferenceBasics.makeCrefQual(id,ty,subs,outCref);
1831 end match;
1832 end stripCrefIdentSliceSubs;
1833
1834 public function stripArrayCref"strips the cref at the array-cref. remove subscripts, outputs appended crefs"
1835 input DAE.ComponentRef crefIn;
1836 output DAE.ComponentRef crefHead;
1837 output Integer idxOut;
1838 output Option<DAE.ComponentRef> crefTail;
1839 algorithm
1840 (crefHead, idxOut, crefTail) := match crefIn
1841 local
1842 Integer idx;
1843 DAE.Ident id;
1844 DAE.ComponentRef cr, outCref;
1845 DAE.Type ty;
1846 case DAE.CREF_IDENT(ident = id,subscriptLst={DAE.INDEX(DAE.ICONST(idx))}, identType = ty)
1847 algorithm
1848 // the complete cref is an array
1849 ✗ then
1850 (ComponentReferenceBasics.makeCrefIdent(id,ty,{}),idx,NONE());
1851
1852 case DAE.CREF_QUAL(componentRef = cr, identType=ty, subscriptLst={DAE.INDEX(DAE.ICONST(idx))}, ident=id)
1853 algorithm
1854 // strip the cref here
1855 ✗ then
1856 (ComponentReferenceBasics.makeCrefIdent(id,ty,{}),idx,SOME(cr));
1857
1858 case DAE.CREF_QUAL(componentRef = cr, identType=ty, ident=id)
1859 algorithm
1860 // continue
1861 ✗ outCref := stripCrefIdentSliceSubs(cr);
1862 ✗ then
1863 (ComponentReferenceBasics.makeCrefQual(id,ty,{},outCref),-1,NONE());
1864 end match;
1865 end stripArrayCref;
1866
1867 protected function removeSliceSubs "
1868 helper function for stripCrefIdentSliceSubs"
1869 input list<DAE.Subscript> subs;
1870 output list<DAE.Subscript> osubs = {};
1871 algorithm
1872 ✗ for s in subs loop
1873 osubs := match s
1874 case DAE.SLICE() then osubs;
1875 else s::osubs;
1876 end match;
1877 end for;
1878 ✗ osubs := Dangerous.listReverseInPlace(osubs);
1879 end removeSliceSubs;
1880
1881 public function crefStripSubs
1882 "Removes all subscript of a componentref"
1883 input DAE.ComponentRef inCref;
1884 output DAE.ComponentRef outCref;
1885 algorithm
1886 outCref := match inCref
1887 local
1888 DAE.Ident id;
1889 DAE.ComponentRef cr;
1890 DAE.Type ty;
1891
1892 case DAE.CREF_IDENT(ident = id,identType = ty)
1893 643504 then ComponentReferenceBasics.makeCrefIdent(id,ty,{});
1894
1895 case DAE.CREF_QUAL(componentRef = cr, identType=ty, ident=id)
1896 algorithm
1897 566950 outCref := crefStripSubs(cr);
1898 566950 then
1899 ComponentReferenceBasics.makeCrefQual(id,ty,{},outCref);
1900 end match;
1901 end crefStripSubs;
1902
1903 public function crefRenameSeedRoot
1904 "Replaces a seed cref's root ident ($SEED_<jacName>.rest) with $SEED_<newJacName>"
1905 input DAE.ComponentRef inCref;
1906 input String newJacName;
1907 output DAE.ComponentRef outCref;
1908 algorithm
1909 outCref := match inCref
1910 // only seed crefs, e.g. $DER.x must not become the seed of x
1911 case DAE.CREF_IDENT() guard(StringUtil.startsWith(inCref.ident, "$SEED_"))
1912 ✗ then ComponentReferenceBasics.makeCrefIdent("$SEED_" + newJacName, inCref.identType, inCref.subscriptLst);
1913
1914 case DAE.CREF_QUAL() guard(StringUtil.startsWith(inCref.ident, "$SEED_"))
1915 ✗ then ComponentReferenceBasics.makeCrefQual("$SEED_" + newJacName, inCref.identType, inCref.subscriptLst, inCref.componentRef);
1916
1917 else inCref;
1918 end match;
1919 end crefRenameSeedRoot;
1920
1921 public function crefStripSubsExceptModelSubs
1922 "Removes all subscript of a componentref expcept for model subscripts"
1923 input DAE.ComponentRef inCref;
1924 output DAE.ComponentRef outCref;
1925 protected
1926 function is_model_array
1927 input DAE.Type ty;
1928 output Boolean res;
1929 protected
1930 ClassInf.State state;
1931 algorithm
1932 res := match ty
1933 case DAE.T_ARRAY(ty = DAE.T_COMPLEX(complexClassType = state))
1934 then match state
1935 case ClassInf.MODEL() then true;
1936 case ClassInf.BLOCK() then true;
1937 else false;
1938 end match;
1939 else false;
1940 end match;
1941 end is_model_array;
1942 algorithm
1943 outCref := match inCref
1944 local
1945 DAE.Ident id;
1946 DAE.ComponentRef cr, cref;
1947 DAE.Type ty;
1948
1949 case DAE.CREF_IDENT()
1950 guard is_model_array(inCref.identType)
1951 then inCref;
1952
1953 case cref as DAE.CREF_QUAL(componentRef = cr)
1954 guard is_model_array(inCref.identType)
1955 algorithm
1956 2223 outCref := crefStripSubsExceptModelSubs(cr);
1957 2223 cref.componentRef := outCref;
1958 then
1959 cref;
1960
1961 case DAE.CREF_IDENT(ident = id, identType = ty)
1962 37844 then ComponentReferenceBasics.makeCrefIdent(id,ty,{});
1963
1964 case DAE.CREF_QUAL(componentRef = cr, identType = ty, ident = id)
1965 algorithm
1966 35031 outCref := crefStripSubsExceptModelSubs(cr);
1967 35031 then
1968 ComponentReferenceBasics.makeCrefQual(id,ty,{},outCref);
1969
1970 else inCref;
1971 end match;
1972 end crefStripSubsExceptModelSubs;
1973
1974 public function crefStripPrefix
1975 "Strips a prefix/cref from a component reference"
1976 input DAE.ComponentRef cref;
1977 input DAE.ComponentRef prefix;
1978 output DAE.ComponentRef outCref;
1979 algorithm
1980 outCref := match(cref,prefix)
1981 local
1982 list<DAE.Subscript> subs1,subs2;
1983 DAE.ComponentRef cr1,cr2;
1984 DAE.Ident id1,id2;
1985
1986 case(DAE.CREF_QUAL(id1,_,subs1,cr1),DAE.CREF_IDENT(id2,_,subs2))
1987 algorithm
1988 ✗ true := stringEq(id1, id2);
1989 ✗ true := ExpressionBasics.subscriptEqual(subs1,subs2);
1990 then cr1;
1991
1992 case(DAE.CREF_QUAL(id1,_,subs1,cr1),DAE.CREF_QUAL(id2,_,subs2,cr2))
1993 algorithm
1994 ✗ true := stringEq(id1, id2);
1995 ✗ true := ExpressionBasics.subscriptEqual(subs1,subs2);
1996 ✗ then crefStripPrefix(cr1,cr2);
1997 end match;
1998 end crefStripPrefix;
1999
2000 public function crefStripLastIdent
2001 "Strips the last part of a component reference, i.e ident and subs"
2002 input DAE.ComponentRef inCr;
2003 output DAE.ComponentRef outCr;
2004 algorithm
2005 outCr := match inCr
2006 local
2007 DAE.Ident id;
2008 list<DAE.Subscript> subs;
2009 DAE.ComponentRef cr1,cr;
2010 DAE.Type t2;
2011
2012 case DAE.CREF_QUAL(id,t2,subs,DAE.CREF_IDENT(_,_,_))
2013 4915102 then
2014 ComponentReferenceBasics.makeCrefIdent(id,t2,subs);
2015
2016 case DAE.CREF_QUAL(id,t2,subs,cr)
2017 algorithm
2018 4960813 cr1 := crefStripLastIdent(cr);
2019 4960813 then
2020 ComponentReferenceBasics.makeCrefQual(id,t2,subs,cr1);
2021 end match;
2022 end crefStripLastIdent;
2023
2024 public function crefStripIterSub
2025 "Recursively looks up subscripts and strips the given iter sub.
2026 This gives an array variable that is defined in a for loop (no NF_SCALARIZE).
2027 Removes all iteration subscripts if an empty or no iter input was given.
2028 author: rfranke"
2029 input DAE.ComponentRef inComponentRef;
2030 input DAE.Ident iter = "";
2031 output DAE.ComponentRef outComponentRef;
2032 protected
2033 DAE.Ident ident, index;
2034 DAE.Type ty;
2035 list<DAE.Subscript> subs;
2036 DAE.ComponentRef cref;
2037 algorithm
2038 outComponentRef := match inComponentRef
2039 case DAE.CREF_IDENT(ident = ident, identType = ty,
2040 subscriptLst = subs as {DAE.INDEX(exp = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = index)))})
2041
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 325 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 325 times.
✗ Branch 9 not taken.
650 then
2042 ComponentReferenceBasics.makeCrefIdent(ident, ty, if ("" == iter) or (index == iter) then {} else subs);
2043 case DAE.CREF_QUAL(ident = ident, identType = ty, componentRef = cref,
2044 subscriptLst = subs as {DAE.INDEX(exp = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = index)))})
2045 algorithm
2046
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 186 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 186 times.
186 if ("" == iter) or (index == iter) then
2047 subs := {};
2048 else
2049 ✗ cref := crefStripIterSub(cref, iter);
2050 end if;
2051 186 then
2052 ComponentReferenceBasics.makeCrefQual(ident, ty, subs, cref);
2053 case DAE.CREF_QUAL(ident = ident, identType = ty, componentRef = cref,
2054 subscriptLst = subs)
2055 338 then
2056 ComponentReferenceBasics.makeCrefQual(ident, ty, subs, crefStripIterSub(cref, iter));
2057 else
2058 inComponentRef;
2059 end match;
2060 end crefStripIterSub;
2061
2062 public function crefStripFirstIdent
2063 "Strips the first part of a component reference,
2064 i.e the identifier and eventual subscripts"
2065 input DAE.ComponentRef inCr;
2066 output DAE.ComponentRef outCr;
2067 algorithm
2068 outCr := match inCr
2069 local
2070 DAE.ComponentRef cr;
2071 case DAE.CREF_QUAL(componentRef = cr) then cr;
2072 end match;
2073 end crefStripFirstIdent;
2074
2075 public function crefStripLastSubsStringified
2076 "author: PA
2077 Same as crefStripLastSubs but works on
2078 a stringified component ref instead."
2079 input DAE.ComponentRef inComponentRef;
2080 output DAE.ComponentRef outComponentRef;
2081 algorithm
2082 outComponentRef := matchcontinue inComponentRef
2083 local
2084 list<DAE.Ident> lst,lst_1;
2085 DAE.Ident id_1,id;
2086 DAE.ComponentRef cr;
2087 DAE.Type t2;
2088
2089 case DAE.CREF_IDENT(ident = id,identType = t2,subscriptLst = {})
2090 algorithm
2091 //print("\n +++++++++++++++++++++++++++++ ");print(id);print("\n");
2092 ✗ lst := Util.stringSplitAtChar(id, "[");
2093 ✗ lst_1 := List.stripLast(lst);
2094 ✗ id_1 := stringDelimitList(lst_1, "[");
2095 ✗ then
2096 ComponentReferenceBasics.makeCrefIdent(id_1,t2,{});
2097
2098 case cr then cr;
2099
2100 end matchcontinue;
2101 end crefStripLastSubsStringified;
2102
2103 public function stringifyComponentRef
2104 "Translates a ComponentRef into a DAE.CREF_IDENT by putting
2105 the string representation of the ComponentRef into it.
2106 See also stringigyCrefs.
2107
2108 NOTE: This function should not be used in OMC, since the OMC backend no longer
2109 uses stringified components. It is still used by MathCore though."
2110 input DAE.ComponentRef cr;
2111 output DAE.ComponentRef outComponentRef;
2112 protected
2113 list<DAE.Subscript> subs;
2114 DAE.ComponentRef cr_1;
2115 DAE.Ident crs;
2116 DAE.Type ty;
2117 algorithm
2118 ✗ subs := crefLastSubs(cr);
2119 ✗ cr_1 := ComponentReferenceBasics.crefStripLastSubs(cr);
2120 ✗ crs := ComponentReferenceBasics.printComponentRefStr(cr_1);
2121 ✗ ty := crefLastType(cr) "The type of the stringified cr is taken from the last identifier";
2122 ✗ outComponentRef := ComponentReferenceBasics.makeCrefIdent(crs,ty,subs);
2123 end stringifyComponentRef;
2124
2125 /***************************************************/
2126 /* Print and Dump */
2127 /***************************************************/
2128
2129 public function printComponentRef
2130 "Print a ComponentRef."
2131 input DAE.ComponentRef inComponentRef;
2132 algorithm
2133 () := match inComponentRef
2134 local
2135 DAE.Ident s;
2136 list<DAE.Subscript> subs;
2137 DAE.ComponentRef cr;
2138 // _
2139 case DAE.WILD()
2140 algorithm
2141 ✗ Print.printBuf("_");
2142 then
2143 ();
2144 // ids
2145 case DAE.CREF_IDENT(ident = s,subscriptLst = subs)
2146 algorithm
2147 ✗ printComponentRef2(s, subs);
2148 then
2149 ();
2150 // qualified crefs, does not handle names with underscores
2151 case DAE.CREF_QUAL(ident = s,subscriptLst = subs,componentRef = cr)
2152 algorithm
2153 ✗ if (Config.modelicaOutput())
2154 then
2155 ✗ printComponentRef2(s, subs);
2156 ✗ Print.printBuf("__");
2157 printComponentRef(cr);
2158 else
2159 ✗ printComponentRef2(s, subs);
2160 ✗ Print.printBuf(".");
2161 printComponentRef(cr);
2162 end if;
2163 then
2164 ();
2165 end match;
2166 end printComponentRef;
2167
2168 protected function printComponentRef2
2169 "Helper function to printComponentRef"
2170 input DAE.Ident inString;
2171 input list<DAE.Subscript> inSubscriptLst;
2172 algorithm
2173 () := matchcontinue (inString,inSubscriptLst)
2174 local
2175 DAE.Ident s;
2176 list<DAE.Subscript> l;
2177
2178 case (s,{})
2179 algorithm
2180 ✗ Print.printBuf(s);
2181 then
2182 ();
2183
2184 case (s,l)
2185 algorithm
2186 ✗ if (Config.modelicaOutput())
2187 then
2188 ✗ Print.printBuf(s);
2189 ✗ Print.printBuf("_L");
2190 ✗ ExpressionDump.printList(l, ExpressionDump.printSubscript, ",");
2191 ✗ Print.printBuf("_R");
2192 else
2193 ✗ Print.printBuf(s);
2194 ✗ Print.printBuf("[");
2195 ✗ ExpressionDump.printList(l, ExpressionDump.printSubscript, ",");
2196 ✗ Print.printBuf("]");
2197 end if;
2198 then
2199 ();
2200
2201 end matchcontinue;
2202 end printComponentRef2;
2203
2204 public function printComponentRefList
2205 input list<DAE.ComponentRef> crs;
2206 protected
2207 String buffer;
2208 algorithm
2209 ✗ buffer := "{" + stringDelimitList(List.map(crs, ComponentReferenceBasics.printComponentRefStr), ", ") + "}\n";
2210 ✗ print(buffer);
2211 end printComponentRefList;
2212
2213 public function replaceWholeDimSubscript
2214 input DAE.ComponentRef icr;
2215 input Integer index;
2216 output DAE.ComponentRef ocr;
2217 algorithm
2218 ocr := matchcontinue icr
2219 local
2220 String id;
2221 DAE.Type et;
2222 list<DAE.Subscript> ss;
2223 DAE.ComponentRef cr;
2224
2225 case DAE.CREF_QUAL(id,et,ss,cr)
2226 algorithm
2227 54 ss := replaceWholeDimSubscript2(ss,index);
2228 ✗ then DAE.CREF_QUAL(id,et,ss,cr);
2229 case DAE.CREF_QUAL(id,et,ss,cr)
2230 algorithm
2231 54 cr := replaceWholeDimSubscript(cr,index);
2232 54 then DAE.CREF_QUAL(id,et,ss,cr);
2233 case DAE.CREF_IDENT(id,et,ss)
2234 algorithm
2235 628 ss := replaceWholeDimSubscript2(ss,index);
2236 593 then DAE.CREF_IDENT(id,et,ss);
2237 end matchcontinue;
2238 end replaceWholeDimSubscript;
2239
2240 public function replaceWholeDimSubscript2
2241 input list<DAE.Subscript> isubs;
2242 input Integer index;
2243 output list<DAE.Subscript> osubs;
2244 algorithm
2245 osubs := match isubs
2246 local
2247 DAE.Subscript sub;
2248 list<DAE.Subscript> subs;
2249
2250 case DAE.WHOLEDIM()::subs
2251 algorithm
2252 593 sub := DAE.INDEX(DAE.ICONST(index));
2253 then sub::subs;
2254 // TODO: SLICE, NONEXP
2255 case sub::subs
2256 algorithm
2257 1058 subs := replaceWholeDimSubscript2(subs,index);
2258 then sub::subs;
2259 end match;
2260 end replaceWholeDimSubscript2;
2261
2262 public function splitCrefLast
2263 "Splits a cref at the end, e.g. a.b.c.d => {a.b.c, d}."
2264 input DAE.ComponentRef inCref;
2265 output DAE.ComponentRef outPrefixCref;
2266 output DAE.ComponentRef outLastCref;
2267 algorithm
2268 (outPrefixCref, outLastCref) := match inCref
2269 local
2270 DAE.Ident id;
2271 DAE.Type ty;
2272 list<DAE.Subscript> subs;
2273 DAE.ComponentRef prefix, last;
2274
2275 case DAE.CREF_QUAL(id, ty, subs, last as DAE.CREF_IDENT())
2276 5159 then (DAE.CREF_IDENT(id, ty, subs), last);
2277
2278 case DAE.CREF_QUAL(id, ty, subs, last)
2279 algorithm
2280 5500 (prefix, last) := splitCrefLast(last);
2281 5500 then
2282 (DAE.CREF_QUAL(id, ty, subs, prefix), last);
2283
2284 end match;
2285 end splitCrefLast;
2286
2287 public function firstNCrefs
2288 "Gets the first a cref at the n-th cref, e.g. (a.b.c.d,2) => a.b."
2289 input DAE.ComponentRef inCref;
2290 input Integer nIn;
2291 output DAE.ComponentRef outFirstCrefs;
2292
2293 algorithm
2294 outFirstCrefs := match(inCref,nIn)
2295 local
2296 DAE.Ident id;
2297 DAE.Type ty;
2298 list<DAE.Subscript> subs;
2299 DAE.ComponentRef prefix, last;
2300 case(_,0)
2301 then (inCref);
2302
2303 case(DAE.CREF_QUAL(id, ty, subs, _),1)
2304 1176 then DAE.CREF_IDENT(id, ty, subs);
2305
2306 case(DAE.CREF_IDENT(_, _, _),_)
2307 then inCref;
2308
2309 case (DAE.CREF_QUAL(id, ty, subs, last),)
2310 algorithm
2311 1605 prefix := firstNCrefs(last,nIn-1);
2312 1605 then
2313 DAE.CREF_QUAL(id, ty, subs, prefix);
2314
2315 else
2316 then (inCref);
2317
2318 end match;
2319 end firstNCrefs;
2320
2321 public function splitCrefFirst
2322 input DAE.ComponentRef inCref;
2323 output DAE.ComponentRef outCrefFirst;
2324 output DAE.ComponentRef outCrefRest;
2325 protected
2326 DAE.Ident id;
2327 DAE.Type ty;
2328 list<DAE.Subscript> subs;
2329 algorithm
2330 ✗ DAE.CREF_QUAL(id, ty, subs, outCrefRest) := inCref;
2331 ✗ outCrefFirst := DAE.CREF_IDENT(id, ty, subs);
2332 end splitCrefFirst;
2333
2334 public function toStringList
2335 "Converts a component reference to a list of strings."
2336 input DAE.ComponentRef inCref;
2337 output list<String> outStringList;
2338 algorithm
2339 334429 outStringList := Dangerous.listReverseInPlace(toStringList_tail(inCref, {}));
2340 end toStringList;
2341
2342 protected function toStringList_tail
2343 "Tail-recursive implementation of toStringList."
2344 input DAE.ComponentRef inCref;
2345 input list<String> inAccumStrings;
2346 output list<String> outStringList;
2347 algorithm
2348 outStringList := match inCref
2349 local
2350 String id;
2351 DAE.ComponentRef cref;
2352
2353 case DAE.CREF_QUAL(ident = id, componentRef = cref)
2354 394973 then toStringList_tail(cref, id :: inAccumStrings);
2355
2356 case DAE.CREF_IDENT(ident = id)
2357 then id :: inAccumStrings;
2358
2359 else {};
2360
2361 end match;
2362 end toStringList_tail;
2363
2364 public function crefDepth
2365 input DAE.ComponentRef inCref;
2366 output Integer depth;
2367 algorithm
2368 depth :=
2369 match inCref
2370 local
2371 DAE.ComponentRef n;
2372
2373 case DAE.WILD() then 0;
2374 case DAE.CREF_IDENT() then 1;
2375 case DAE.CREF_QUAL(componentRef = n)
2376 129771 then
2377 crefDepth1(n,1);
2378 end match;
2379 end crefDepth;
2380
2381 protected function crefDepth1
2382 input DAE.ComponentRef inCref;
2383 input Integer iDepth;
2384 output Integer depth;
2385 algorithm
2386 depth :=
2387 match inCref
2388 local
2389 DAE.ComponentRef n;
2390
2391 case DAE.WILD() then iDepth;
2392 129771 case DAE.CREF_IDENT() then 1+iDepth;
2393 case DAE.CREF_QUAL(componentRef = n)
2394 260823 then
2395 crefDepth1(n,1+iDepth);
2396 end match;
2397 end crefDepth1;
2398
2399 public function expandCref
2400 "Expands an array cref into a list of elements, e.g.:
2401
2402 expandCref(x) => {x[1], x[2], x[3]}
2403
2404 This function expects the subscripts of the cref to be constant evaluated,
2405 otherwise it will fail."
2406 input DAE.ComponentRef inCref;
2407 input Boolean expandRecord;
2408 output list<DAE.ComponentRef> outCref;
2409 algorithm
2410 outCref := match expandRecord
2411 1985406 case _ then expandCref_impl(inCref,expandRecord);
2412
2413 else
2414 algorithm
2415 ✗ true := Flags.isSet(Flags.FAILTRACE);
2416 ✗ Debug.traceln("- ComponentReference.expandCref failed on " +
2417 ComponentReferenceBasics.printComponentRefStr(inCref));
2418 ✗ then
2419 fail();
2420
2421 end match;
2422 end expandCref;
2423
2424 public function expandCref_impl
2425 input DAE.ComponentRef inCref;
2426 input Boolean expandRecord;
2427 output list<DAE.ComponentRef> outCref;
2428 algorithm
2429 outCref := matchcontinue(inCref,expandRecord)
2430 local
2431 DAE.Ident id;
2432 DAE.Type ty, basety,correctTy;
2433 list<DAE.Dimension> dims;
2434 list<DAE.Subscript> subs;
2435 DAE.ComponentRef cref;
2436 list<DAE.ComponentRef> crefs, crefs2;
2437 list<DAE.Var> varLst;
2438 Integer missing_subs;
2439
2440 // A scalar record ident cref. Expand record true
2441 case (DAE.CREF_IDENT(_, DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD(_)), {}),true)
2442 algorithm
2443 // Create a list of crefs from names
2444 15252 crefs := List.map(varLst,creffromVar);
2445 15252 crefs := List.map1r(crefs,joinCrefs,inCref);
2446 15252 then
2447 List.mapFlat(crefs, function expandCref_impl(expandRecord = true));
2448
2449 // A array record ident cref without subscripts. Expand record true
2450 case (DAE.CREF_IDENT(id, ty as DAE.T_ARRAY(), {}),true)
2451 algorithm
2452 // Flatten T_ARRAY(T_ARRAY(T_COMPLEX(), dim2,src), dim1,src) types to one level T_ARRAY(simpletype, alldims, src)
2453
3/4
✓ Branch 1 taken 27831 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
27838 (basety as DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD()), dims) := TypesDump.flattenArrayType(ty);
2454 7 correctTy := DAE.T_ARRAY(basety,dims);
2455 // Create a list of : subscripts to generate all elements.
2456 7 subs := List.fill(DAE.WHOLEDIM(), listLength(dims));
2457 7 crefs := expandCref2(id, correctTy, subs, dims);
2458 7 then
2459 expandCrefLst(crefs,varLst,{});
2460
2461 // A array type cref (possibly record but no expansion of records) without subscripts.
2462 case (DAE.CREF_IDENT(id, ty as DAE.T_ARRAY(), {}),_)
2463 algorithm
2464 // Flatten T_ARRAY(T_ARRAY(T_..., dim2,src), dim1,src) types to one level T_ARRAY(simpletype, alldims, src)
2465 74259 (basety, dims) := TypesDump.flattenArrayType(ty);
2466 74259 correctTy := DAE.T_ARRAY(basety,dims);
2467 // Create a list of : subscripts to generate all elements.
2468 74259 subs := List.fill(DAE.WHOLEDIM(), listLength(dims));
2469 74259 then
2470 expandCref2(id, correctTy, subs, dims);
2471
2472 // A array complex cref with subscripts. Expand record true
2473 case (DAE.CREF_IDENT(id, ty as DAE.T_ARRAY(), subs),true)
2474 algorithm
2475 // Flatten T_ARRAY(T_ARRAY(T_COMPLEX(), dim2,src), dim1,src) types to one level T_ARRAY(simpletype, alldims, src)
2476
3/4
✓ Branch 1 taken 739272 times.
✓ Branch 2 taken 887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 887 times.
740159 (basety as DAE.T_COMPLEX(varLst=varLst,complexClassType=ClassInf.RECORD()), dims) := TypesDump.flattenArrayType(ty);
2477 887 correctTy := DAE.T_ARRAY(basety,dims);
2478
2479 // Pad the list of subscripts with : if necessary to fill out all dimensions.
2480 887 missing_subs := listLength(dims) - listLength(subs);
2481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 887 times.
887 if missing_subs > 0 then
2482 ✗ subs := listAppend(subs, List.fill(DAE.WHOLEDIM(), missing_subs))
2483 annotation(__OpenModelica_DisableListAppendWarning=true);
2484 end if;
2485
2486 // Use the subscripts to generate only the wanted elements.
2487 887 crefs := expandCref2(id, correctTy, subs, dims);
2488 887 then
2489 expandCrefLst(crefs,varLst,{});
2490
2491 // A array type cref (possibly record but no expansion of records) with subscripts.
2492 case (DAE.CREF_IDENT(id, ty as DAE.T_ARRAY(), subs),_)
2493 algorithm
2494 // Flatten T_ARRAY(T_ARRAY(T_..., dim2,src), dim1,src) types to one level T_ARRAY(simpletype, alldims, src)
2495 1056437 (basety, dims) := TypesDump.flattenArrayType(ty);
2496 1056437 correctTy := DAE.T_ARRAY(basety,dims);
2497
2498 // Pad the list of subscripts with : if necessary to fill out all dimensions.
2499 1056437 missing_subs := listLength(dims) - listLength(subs);
2500
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 1056341 times.
1056437 if missing_subs > 0 then
2501 96 subs := listAppend(subs, List.fill(DAE.WHOLEDIM(), missing_subs))
2502 annotation(__OpenModelica_DisableListAppendWarning=true);
2503 end if;
2504 // Use the subscripts to generate only the wanted elements.
2505 1056437 then
2506 expandCref2(id, correctTy, subs, dims);
2507
2508
2509 // A qualified cref with array type.
2510 case (DAE.CREF_QUAL(id, ty as DAE.T_ARRAY(), subs, cref),_)
2511 algorithm
2512 // Expand the rest of the cref.
2513 105665 crefs := expandCref_impl(cref,expandRecord);
2514 // Flatten T_ARRAY(T_ARRAY(T_..., dim2,src), dim1,src) types to one level T_ARRAY(simpletype, alldims, src)
2515 105665 (basety, dims) := TypesDump.flattenArrayType(ty);
2516 105665 correctTy := DAE.T_ARRAY(basety,dims);
2517 // Create a simple identifier for the head of the cref and expand it.
2518 105665 cref := DAE.CREF_IDENT(id, correctTy, subs);
2519 105665 crefs2 := expandCref_impl(cref,false);
2520 105665 crefs2 := listReverse(crefs2);
2521 // crefs2 = List.map1(crefs2,crefSetType,correctTy);
2522 // Create all combinations of the two lists.
2523 105665 crefs := expandCrefQual(crefs2, crefs);
2524 then
2525 crefs;
2526
2527 // A qualified cref with scalar type.
2528 case (DAE.CREF_QUAL(id, ty, subs, cref),_)
2529 algorithm
2530 // Expand the rest of the cref.
2531 2586338 crefs := expandCref_impl(cref,expandRecord);
2532 // Append the head of this cref to all of the generated crefs.
2533
4/4
✓ Branch 0 taken 3266772 times.
✓ Branch 1 taken 2586338 times.
✓ Branch 2 taken 3266772 times.
✓ Branch 3 taken 2586338 times.
5853110 crefs := list(ComponentReferenceBasics.makeCrefQual(id, ty, subs, c) for c in crefs);
2534 then
2535 crefs;
2536
2537 // All other cases, no expansion.
2538 else {inCref};
2539
2540 end matchcontinue;
2541 end expandCref_impl;
2542
2543 protected function expandCrefLst
2544 input list<DAE.ComponentRef> inCrefs;
2545 input list<DAE.Var> varLst;
2546 input list<list<DAE.ComponentRef>> inCrefsAcc;
2547 output list<DAE.ComponentRef> outCref;
2548 algorithm
2549 outCref := match inCrefs
2550 local
2551 DAE.ComponentRef cr;
2552 list<DAE.ComponentRef> crefs,rest;
2553 894 case {} then List.flatten(inCrefsAcc);
2554 case cr::rest
2555 algorithm
2556 // Create a list of crefs from names
2557 905 crefs := List.map(varLst,creffromVar);
2558 905 crefs := List.map1r(crefs,joinCrefs,cr);
2559 905 then
2560 expandCrefLst(rest,varLst,crefs::inCrefsAcc);
2561 end match;
2562 end expandCrefLst;
2563
2564 protected function expandCrefQual
2565 "Helper function to expandCref_impl. Constructs all combinations of the head
2566 and rest cref lists. E.g.:
2567 expandCrefQual({x, y}, {a, b}) => {x.a, x.b, y.a, y.b} "
2568 input list<DAE.ComponentRef> inHeadCrefs;
2569 input list<DAE.ComponentRef> inRestCrefs;
2570 output list<DAE.ComponentRef> outCrefs = {};
2571 protected
2572 list<DAE.ComponentRef> crefs;
2573 algorithm
2574
2/2
✓ Branch 0 taken 107027 times.
✓ Branch 1 taken 105665 times.
212692 for cref in inHeadCrefs loop
2575
4/4
✓ Branch 0 taken 129932 times.
✓ Branch 1 taken 107027 times.
✓ Branch 2 taken 129932 times.
✓ Branch 3 taken 107027 times.
236959 crefs := list(joinCrefs(cref, rest_cref) for rest_cref in inRestCrefs);
2576 107027 outCrefs := listAppend(crefs, outCrefs);
2577 end for;
2578 end expandCrefQual;
2579
2580 protected function expandCref2
2581 input DAE.Ident inId;
2582 input DAE.Type inType;
2583 input list<DAE.Subscript> inSubscripts;
2584 input list<DAE.Dimension> inDimensions;
2585 output list<DAE.ComponentRef> outCrefs = {};
2586 protected
2587 list<list<DAE.Subscript>> subslst;
2588 algorithm
2589 // Expand each subscript into a list of subscripts.
2590 1131590 subslst := List.threadMap(inSubscripts, inDimensions, Expression.expandSubscript);
2591
2592 1131286 subslst := List.combination(subslst);
2593
2/2
✓ Branch 0 taken 1452283 times.
✓ Branch 1 taken 1131286 times.
2583569 for subs in subslst loop
2594 1452283 outCrefs := ComponentReferenceBasics.makeCrefIdent(inId,inType,subs)::outCrefs;
2595 end for;
2596 1131286 outCrefs := listReverse(outCrefs);
2597 end expandCref2;
2598
2599 public function replaceSubsWithString
2600 input DAE.ComponentRef inCref;
2601 output DAE.ComponentRef outCref;
2602 algorithm
2603 outCref := match inCref
2604 local
2605 DAE.Ident ident;
2606 DAE.Type identType;
2607 list<DAE.Subscript> subscriptLst;
2608 DAE.ComponentRef cr,cr1;
2609 case DAE.CREF_QUAL(ident=ident,identType=identType,subscriptLst={},componentRef=cr)
2610 algorithm
2611 136609 cr1 := replaceSubsWithString(cr);
2612 136609 then
2613 DAE.CREF_QUAL(ident,identType,{},cr1);
2614 case DAE.CREF_QUAL(ident=ident,identType=identType,subscriptLst=subscriptLst,componentRef=cr)
2615 algorithm
2616 4707 identType := Expression.unliftArrayTypeWithSubs(subscriptLst,identType);
2617 4707 cr1 := replaceSubsWithString(cr);
2618 4707 cr := makeCrefsFromSubScriptLst(subscriptLst, DAE.CREF_IDENT(ident, identType, {}));
2619 4707 then
2620 joinCrefs(cr, cr1);
2621
2622 case DAE.CREF_IDENT(subscriptLst={})
2623 then
2624 inCref;
2625 case DAE.CREF_IDENT(ident=ident,identType=identType,subscriptLst=subscriptLst)
2626 algorithm
2627 90 identType := Expression.unliftArrayTypeWithSubs(subscriptLst,identType);
2628 90 cr := makeCrefsFromSubScriptLst(subscriptLst, DAE.CREF_IDENT(ident, identType, {}));
2629 then
2630 cr;
2631
2632 case DAE.WILD()
2633 then
2634 inCref;
2635 end match;
2636 end replaceSubsWithString;
2637
2638 public function makeCrefsFromSubScriptLst
2639 input list<DAE.Subscript> inSubscriptLst;
2640 input DAE.ComponentRef inPreCref;
2641 output DAE.ComponentRef outCref = inPreCref;
2642 algorithm
2643
2/2
✓ Branch 0 taken 4797 times.
✓ Branch 1 taken 4797 times.
9594 for subScript in inSubscriptLst loop
2644 outCref := match subScript
2645 local
2646 DAE.ComponentRef cr;
2647 DAE.Exp e;
2648 String str;
2649 case DAE.INDEX(exp = e) algorithm
2650 4797 cr := makeCrefsFromSubScriptExp(e);
2651 4797 then
2652 joinCrefs(outCref, cr);
2653
2654 // all other should probably fails or evaluated before
2655 else algorithm
2656 ✗ str := ExpressionBasics.printSubscriptStr(subScript);
2657 ✗ Error.addInternalError("function ComponentReference.makeCrefsFromSubScriptLst for:" + str + "\n", sourceInfo());
2658 ✗ then
2659 fail();
2660 end match;
2661 end for;
2662 end makeCrefsFromSubScriptLst;
2663
2664 public function makeCrefsFromSubScriptExp
2665 input DAE.Exp inExp;
2666 output DAE.ComponentRef outCref;
2667 algorithm
2668 outCref := match inExp
2669 local
2670 DAE.Operator op;
2671 DAE.ComponentRef cr1, cr2;
2672 String str;
2673 DAE.Exp e1, e2;
2674 Absyn.Path enum_lit;
2675
2676 case DAE.ICONST() algorithm
2677 4797 str := ExpressionBasics.printExpStr(inExp);
2678 4797 then
2679 DAE.CREF_IDENT(str,DAE.T_UNKNOWN_DEFAULT,{});
2680
2681 case DAE.CREF()
2682 ✗ then
2683 Expression.expCref(inExp);
2684
2685 case DAE.BINARY(operator=op, exp1=e1, exp2=e2) algorithm
2686 ✗ str := ExpressionDump.binopSymbol(op);
2687 ✗ cr1 := makeCrefsFromSubScriptExp(e1);
2688 ✗ cr2 := makeCrefsFromSubScriptExp(e2);
2689 ✗ outCref := prependStringCref(str, cr1);
2690 ✗ outCref := joinCrefs(outCref, cr2);
2691 then
2692 outCref;
2693
2694 case DAE.ENUM_LITERAL(name = enum_lit) algorithm
2695 ✗ str := System.stringReplace(AbsynUtil.pathString(enum_lit), ".", "$P");
2696 ✗ then
2697 DAE.CREF_IDENT(str,DAE.T_UNKNOWN_DEFAULT,{});
2698
2699 else algorithm
2700 ✗ str := ExpressionDump.dumpExpStr(inExp, 0);
2701 ✗ Error.addInternalError("function ComponentReference.makeCrefsFromSubScriptExp for:" + str + "\n", sourceInfo());
2702 ✗ then
2703 fail();
2704 end match;
2705 end makeCrefsFromSubScriptExp;
2706
2707 public function replaceLast
2708 "Replaces the last part of a cref with a new cref."
2709 input DAE.ComponentRef inCref;
2710 input DAE.ComponentRef inNewLast;
2711 output DAE.ComponentRef outCref;
2712 algorithm
2713 outCref := match inCref
2714 local
2715 DAE.Ident ident;
2716 DAE.Type ty;
2717 list<DAE.Subscript> subs;
2718 DAE.ComponentRef cref;
2719
2720 case DAE.CREF_QUAL(ident, ty, subs, cref)
2721 algorithm
2722 ✗ cref := replaceLast(cref, inNewLast);
2723 ✗ then
2724 DAE.CREF_QUAL(ident, ty, subs, cref);
2725
2726 case DAE.CREF_IDENT() then inNewLast;
2727
2728 end match;
2729 end replaceLast;
2730
2731 public function expandArrayCref
2732 "deprecated. use expandArray"
2733 input DAE.ComponentRef inCr;
2734 input list<DAE.Dimension> inDims;
2735 output list<DAE.ComponentRef> outCrefs;
2736 protected
2737 DAE.Type lasttype;
2738 DAE.ComponentRef tmpcref;
2739 algorithm
2740 ✗ lasttype := crefLastType(inCr);
2741 ✗ lasttype := Types.liftTypeWithDims(lasttype, inDims);
2742 ✗ tmpcref := crefSetLastType(inCr, lasttype);
2743 ✗ outCrefs := expandCref(tmpcref, false);
2744 end expandArrayCref;
2745
2746 protected function expandArrayCref1
2747 input DAE.ComponentRef inCr;
2748 input list<list<DAE.Subscript>> inSubscripts;
2749 input list<DAE.Subscript> inAccumSubs;
2750 input list<DAE.ComponentRef> inAccumCrefs;
2751 output list<DAE.ComponentRef> outCrefs;
2752 algorithm
2753 outCrefs := match inSubscripts
2754 local
2755 DAE.Subscript sub;
2756 list<DAE.Subscript> subs;
2757 list<list<DAE.Subscript>> rest_subs;
2758 list<DAE.ComponentRef> crefs;
2759 DAE.ComponentRef cref;
2760
2761 case (sub :: subs) :: rest_subs
2762 algorithm
2763 ✗ crefs := expandArrayCref1(inCr, subs :: rest_subs, inAccumSubs, inAccumCrefs);
2764 ✗ crefs := expandArrayCref1(inCr, rest_subs, sub :: inAccumSubs, crefs);
2765 then
2766 crefs;
2767
2768 case _ :: _
2769 then inAccumCrefs;
2770
2771 else
2772 algorithm
2773 ✗ cref := crefSetLastSubs(inCr,inAccumSubs);
2774 then
2775 cref :: inAccumCrefs;
2776
2777 end match;
2778 end expandArrayCref1;
2779
2780 public function explode
2781 "Explodes a cref into a list of CREF_IDENTs."
2782 input DAE.ComponentRef inCref;
2783 output list<DAE.ComponentRef> outParts;
2784 algorithm
2785 3250 outParts := Dangerous.listReverseInPlace(explode_tail(inCref, {}));
2786 end explode;
2787
2788 protected function explode_tail
2789 input DAE.ComponentRef inCref;
2790 input list<DAE.ComponentRef> inParts;
2791 output list<DAE.ComponentRef> outParts;
2792 algorithm
2793 outParts := match inCref
2794 local
2795 DAE.ComponentRef first_cr, rest_cr;
2796
2797 case DAE.CREF_QUAL(componentRef = rest_cr)
2798 algorithm
2799 4401 first_cr := ComponentReferenceBasics.crefFirstCref(inCref);
2800 4401 then
2801 explode_tail(rest_cr, first_cr :: inParts);
2802
2803 else inCref :: inParts;
2804
2805 end match;
2806 end explode_tail;
2807
2808 public function implode
2809 "Constructs a cref from a list of CREF_IDENTs."
2810 input list<DAE.ComponentRef> inParts;
2811 output DAE.ComponentRef outCref;
2812 protected
2813 algorithm
2814 1625 outCref := implode_reverse(listReverse(inParts));
2815 end implode;
2816
2817 public function implode_reverse
2818 "Constructs a cref from a reversed list of CREF_IDENTs."
2819 input list<DAE.ComponentRef> inParts;
2820 output DAE.ComponentRef outCref;
2821 protected
2822 DAE.ComponentRef first;
2823 list<DAE.ComponentRef> rest;
2824 algorithm
2825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1892943 times.
1892943 first :: rest := inParts;
2826 1892943 outCref := implode_tail(rest, first);
2827 end implode_reverse;
2828
2829 protected function implode_tail
2830 input list<DAE.ComponentRef> inParts;
2831 input DAE.ComponentRef inAccumCref;
2832 output DAE.ComponentRef outCref;
2833 algorithm
2834 outCref := match inParts
2835 local
2836 DAE.Ident id;
2837 DAE.Type ty;
2838 list<DAE.Subscript> subs;
2839 list<DAE.ComponentRef> rest;
2840 DAE.ComponentRef cr;
2841
2842 case DAE.CREF_IDENT(id, ty, subs) :: rest
2843 algorithm
2844 1240161 cr := DAE.CREF_QUAL(id, ty, subs, inAccumCref);
2845 1240161 then
2846 implode_tail(rest, cr);
2847
2848 case {} then inAccumCref;
2849
2850 end match;
2851 end implode_tail;
2852
2853 public function identifierCount
2854 input DAE.ComponentRef inCref;
2855 output Integer outIdCount;
2856 algorithm
2857 1625 outIdCount := identifierCount_tail(inCref, 0);
2858 end identifierCount;
2859
2860 protected function identifierCount_tail
2861 input DAE.ComponentRef inCref;
2862 input Integer inAccumCount;
2863 output Integer outIdCount;
2864 algorithm
2865 outIdCount := match inCref
2866 local
2867 DAE.ComponentRef cr;
2868
2869 case DAE.CREF_QUAL(componentRef = cr)
2870 2730 then identifierCount_tail(cr, inAccumCount + 1);
2871
2872 1625 else inAccumCount + 1;
2873 end match;
2874 end identifierCount_tail;
2875
2876 public function checkCrefSubscriptsBounds
2877 "Checks that the subscripts in a cref are valid given the dimensions of the
2878 cref's type. Prints an error if they are not."
2879 input DAE.ComponentRef inCref;
2880 input SourceInfo inInfo;
2881 algorithm
2882 36424 checkCrefSubscriptsBounds2(inCref, inCref, inInfo);
2883 end checkCrefSubscriptsBounds;
2884
2885 protected function checkCrefSubscriptsBounds2
2886 input DAE.ComponentRef inCref;
2887 input DAE.ComponentRef inWholeCref;
2888 input SourceInfo inInfo;
2889 algorithm
2890 () := match inCref
2891 local
2892 DAE.Type ty;
2893 list<DAE.Subscript> subs;
2894 DAE.ComponentRef rest_cr;
2895
2896 case DAE.CREF_QUAL(identType = ty, subscriptLst = subs, componentRef = rest_cr)
2897 algorithm
2898 59092 checkCrefSubscriptsBounds3(ty, subs, inWholeCref, inInfo);
2899 59092 checkCrefSubscriptsBounds2(rest_cr, inWholeCref, inInfo);
2900 then
2901 ();
2902
2903 case DAE.CREF_IDENT(identType = ty, subscriptLst = subs)
2904 algorithm
2905 36424 checkCrefSubscriptsBounds3(ty, subs, inWholeCref, inInfo);
2906 then
2907 ();
2908
2909 end match;
2910 end checkCrefSubscriptsBounds2;
2911
2912 protected function checkCrefSubscriptsBounds3
2913 input DAE.Type inCrefType;
2914 input list<DAE.Subscript> inSubscripts;
2915 input DAE.ComponentRef inWholeCref;
2916 input SourceInfo inInfo;
2917 protected
2918 list<DAE.Dimension> dims;
2919 list<DAE.Subscript> subs;
2920 algorithm
2921 95516 dims := TypesDump.getDimensions(inCrefType);
2922 // The type might contain dimensions from the cref part's prefix here, so
2923 // reverse the lists and check them from the back to pair up each subscript
2924 // with the correct dimension.
2925 95516 dims := listReverse(dims);
2926 95516 subs := listReverse(inSubscripts);
2927 95516 checkCrefSubscriptsBounds4(subs, dims, 1, inWholeCref, inInfo);
2928 end checkCrefSubscriptsBounds3;
2929
2930 protected function checkCrefSubscriptsBounds4
2931 input list<DAE.Subscript> inSubscripts;
2932 input list<DAE.Dimension> inDimensions;
2933 input Integer inIndex;
2934 input DAE.ComponentRef inWholeCref;
2935 input SourceInfo inInfo;
2936 algorithm
2937 () := match(inSubscripts, inDimensions)
2938 local
2939 DAE.Subscript sub;
2940 list<DAE.Subscript> rest_subs;
2941 DAE.Dimension dim;
2942 list<DAE.Dimension> rest_dims;
2943
2944 case (sub :: rest_subs, dim :: rest_dims)
2945 algorithm
2946
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2134 times.
2134 true := checkCrefSubscriptBounds(sub, dim, inIndex, inWholeCref, inInfo);
2947 2134 checkCrefSubscriptsBounds4(rest_subs, rest_dims, inIndex + 1, inWholeCref, inInfo);
2948 then
2949 ();
2950
2951 case ({}, _) then ();
2952
2953 // Cref types are sometimes messed up, and we might get a cref with
2954 // subscripts but no dimensions here. That's usually fine, since the
2955 // subscripts in those cases are generated by the compiler.
2956 case (_, {}) then ();
2957 end match;
2958 end checkCrefSubscriptsBounds4;
2959
2960 protected function checkCrefSubscriptBounds
2961 input DAE.Subscript inSubscript;
2962 input DAE.Dimension inDimension;
2963 input Integer inIndex;
2964 input DAE.ComponentRef inWholeCref;
2965 input SourceInfo inInfo;
2966 output Boolean outIsValid;
2967 algorithm
2968 outIsValid := matchcontinue(inSubscript, inDimension)
2969 local
2970 Integer idx, dim;
2971 list<DAE.Exp> expl;
2972 DAE.Exp exp;
2973
2974 /*/ allow index 0 with dimension 0
2975 case (DAE.INDEX(exp = exp as DAE.ICONST(integer = idx)),
2976 DAE.DIM_INTEGER(integer = dim), _, _, _)
2977 algorithm
2978 true = idx == 0 and dim == 0;
2979 then
2980 true;*/
2981
2982 case (DAE.INDEX(exp = exp as DAE.ICONST(integer = idx)), DAE.DIM_INTEGER(integer = dim))
2983 algorithm
2984
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 false := idx > 0 and idx <= dim;
2985 ✗ printSubscriptBoundsError(exp, inDimension, inIndex, inWholeCref, inInfo);
2986 then
2987 false;
2988
2989 case (DAE.SLICE(exp = DAE.ARRAY(array = expl)), DAE.DIM_INTEGER(integer = dim))
2990 algorithm
2991 14 exp := List.getMemberOnTrue(dim, expl, subscriptExpOutOfBounds);
2992 ✗ printSubscriptBoundsError(exp, inDimension, inIndex, inWholeCref, inInfo);
2993 then
2994 false;
2995
2996 else true;
2997 end matchcontinue;
2998 end checkCrefSubscriptBounds;
2999
3000 protected function subscriptExpOutOfBounds
3001 input Integer inDimSize;
3002 input DAE.Exp inSubscriptExp;
3003 output Boolean outOutOfBounds;
3004 algorithm
3005 outOutOfBounds := match inSubscriptExp
3006 local
3007 Integer i;
3008
3009 90 case DAE.ICONST(integer = i) then i < 1 or i > inDimSize;
3010 else false;
3011 end match;
3012 end subscriptExpOutOfBounds;
3013
3014 protected function printSubscriptBoundsError
3015 input DAE.Exp inSubscriptExp;
3016 input DAE.Dimension inDimension;
3017 input Integer inIndex;
3018 input DAE.ComponentRef inCref;
3019 input SourceInfo inInfo;
3020 protected
3021 String sub_str, dim_str, idx_str, cref_str;
3022 algorithm
3023 ✗ sub_str := ExpressionBasics.printExpStr(inSubscriptExp);
3024 ✗ dim_str := ExpressionBasics.dimensionString(inDimension);
3025 ✗ idx_str := intString(inIndex);
3026 ✗ cref_str := ComponentReferenceBasics.printComponentRefStr(inCref);
3027 ✗ Error.addSourceMessage(Error.ARRAY_INDEX_OUT_OF_BOUNDS,
3028 {sub_str, idx_str, dim_str, cref_str}, inInfo);
3029 end printSubscriptBoundsError;
3030
3031 public function crefAppendedSubs
3032 input DAE.ComponentRef cref;
3033 output String s;
3034 protected
3035 String s1,s2;
3036 algorithm
3037 ✗ s1 := stringDelimitList(toStringList(cref), "_P");
3038 ✗ s2 := stringDelimitList(List.mapMap(ComponentReferenceBasics.crefSubs(cref),Expression.getSubscriptExp,ExpressionBasics.printExpStr),",");
3039 ✗ s := s1+"["+s2+"]";
3040 end crefAppendedSubs;
3041
3042 public function writeCref
3043 input File.File file;
3044 input DAE.ComponentRef cref;
3045 input File.Escape escape = File.Escape.None;
3046 protected
3047 DAE.ComponentRef c = cref;
3048 algorithm
3049 4117369 while true loop
3050 c := match c
3051 case DAE.CREF_IDENT()
3052 algorithm
3053 1654445 File.writeEscape(file, c.ident, escape);
3054 1654445 writeSubscripts(file, c.subscriptLst, escape);
3055 1654445 return;
3056 then fail();
3057 case DAE.CREF_QUAL(ident=DAE.derivativeNamePrefix)
3058 algorithm
3059 89953 File.write(file, "der(");
3060 89953 writeCref(file, c.componentRef, escape);
3061 89953 File.write(file, ")");
3062 89953 return;
3063 then fail();
3064 case DAE.CREF_QUAL(ident=DAE.previousNamePrefix)
3065 algorithm
3066 669 File.write(file, "previous(");
3067 669 writeCref(file, c.componentRef, escape);
3068 669 File.write(file, ")");
3069 669 return;
3070 then fail();
3071 case DAE.CREF_QUAL()
3072 algorithm
3073 4117369 File.writeEscape(file, c.ident, escape);
3074 4117369 writeSubscripts(file, c.subscriptLst, escape);
3075 4117369 File.write(file, ".");
3076 4117369 then c.componentRef;
3077 end match;
3078 end while;
3079 end writeCref;
3080
3081 public function writeSubscripts
3082 input File.File file;
3083 input list<DAE.Subscript> subs;
3084 input File.Escape escape = File.Escape.None;
3085 protected
3086 Boolean first=true;
3087 Integer i;
3088 DAE.Exp exp;
3089 algorithm
3090
2/2
✓ Branch 0 taken 5131209 times.
✓ Branch 1 taken 1018997 times.
6150206 if listEmpty(subs) then
3091 5131209 return;
3092 end if;
3093 1018997 File.write(file, "[");
3094
2/2
✓ Branch 0 taken 1238079 times.
✓ Branch 1 taken 1018997 times.
2257076 for s in subs loop
3095
2/2
✓ Branch 0 taken 219082 times.
✓ Branch 1 taken 1018997 times.
1238079 if not first then
3096 219082 File.write(file, ",");
3097 else
3098 first := false;
3099 end if;
3100 () := match s
3101 case DAE.WHOLEDIM()
3102 113 algorithm File.write(file, ":"); then ();
3103 case DAE.SLICE(DAE.ICONST(i))
3104 ✗ algorithm File.writeInt(file, i); then ();
3105 case DAE.INDEX(DAE.ICONST(i))
3106 1233520 algorithm File.writeInt(file, i); then ();
3107 case DAE.WHOLE_NONEXP(DAE.ICONST(i))
3108 ✗ algorithm File.writeInt(file, i); then ();
3109 case DAE.SLICE(exp)
3110 21 algorithm File.write(file, ExpressionBasics.printExpStr(exp)); then ();
3111 case DAE.INDEX(exp)
3112 4425 algorithm File.write(file, ExpressionBasics.printExpStr(exp)); then ();
3113 case DAE.WHOLE_NONEXP(exp)
3114 ✗ algorithm File.write(file, ExpressionBasics.printExpStr(exp)); then ();
3115 end match;
3116 end for;
3117 1018997 File.write(file, "]");
3118 end writeSubscripts;
3119
3120 function getConsumedMemory
3121 input DAE.ComponentRef inCref;
3122 output Real szIdents=0;
3123 output Real szTypes=0;
3124 output Real szSubs=0;
3125 protected
3126 DAE.ComponentRef cr=inCref;
3127 Boolean b = true;
3128 algorithm
3129 ✗ while b loop
3130 (b,cr) := match cr
3131 case DAE.CREF_IDENT()
3132 algorithm
3133 ✗ szIdents := szIdents + System.getSizeOfData(cr.ident);
3134 ✗ szTypes := szTypes + System.getSizeOfData(cr.identType);
3135 ✗ szSubs := szSubs + System.getSizeOfData(cr.subscriptLst);
3136 then (false,cr);
3137 case DAE.CREF_QUAL()
3138 algorithm
3139 ✗ szIdents := szIdents + System.getSizeOfData(cr.ident);
3140 ✗ szTypes := szTypes + System.getSizeOfData(cr.identType);
3141 ✗ szSubs := szSubs + System.getSizeOfData(cr.subscriptLst);
3142 ✗ then (true,cr.componentRef);
3143 else (false,cr);
3144 end match;
3145 end while;
3146 end getConsumedMemory;
3147
3148 public function createDifferentiatedCrefName
3149 input DAE.ComponentRef inCref;
3150 input DAE.ComponentRef inX;
3151 input String inMatrixName;
3152 output DAE.ComponentRef outCref;
3153 protected
3154 list<DAE.Subscript> subs;
3155 constant Boolean debug = false;
3156 algorithm
3157 if debug then print("inCref: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\n"); end if;
3158
3159 // move subs and and type to lastCref, to move type replace by last type
3160 // and move last cref type to the last cref.
3161 75531 subs := crefLastSubs(inCref);
3162 75531 outCref := ComponentReferenceBasics.crefStripLastSubs(inCref);
3163 75531 outCref := replaceSubsWithString(outCref);
3164 if debug then print("after full type: " + TypesDump.printTypeStr(crefTypeFull(crefStripIterSub(outCref))) + "\n"); end if;
3165 75531 outCref := crefSetLastType(outCref, DAE.T_UNKNOWN_DEFAULT);
3166 if debug then print("after strip: " + ComponentReferenceBasics.printComponentRefListStr(expandCref(outCref, true)) + "\n"); end if;
3167
3168 // join crefs
3169 75531 outCref := joinCrefs(outCref, ComponentReferenceBasics.makeCrefIdent(DAE.partialDerivativeNamePrefix + inMatrixName, DAE.T_UNKNOWN_DEFAULT, {}));
3170 75531 outCref := joinCrefs(outCref, inX);
3171 if debug then print("after join: " + ComponentReferenceBasics.printComponentRefListStr(expandCref(outCref, true)) + "\n"); end if;
3172
3173 // fix subs and type of the last cref
3174 75531 outCref := crefSetLastSubs(outCref, subs);
3175 75531 outCref := crefSetLastType(outCref, crefLastType(inCref));
3176 if debug then print("outCref: " + ComponentReferenceBasics.printComponentRefStr(outCref) + "\n"); end if;
3177 end createDifferentiatedCrefName;
3178
3179 public function isTime
3180 input DAE.ComponentRef cref;
3181 output Boolean b;
3182 algorithm
3183 b := match cref
3184 case DAE.CREF_IDENT(ident = "time") then true;
3185 else false;
3186 end match;
3187 end isTime;
3188
3189 public function isWild
3190 input DAE.ComponentRef cref;
3191 output Boolean b;
3192 algorithm
3193 b := match cref
3194 case DAE.WILD() then true;
3195 else false;
3196 end match;
3197 end isWild;
3198
3199 public function uniqueList
3200 input list<DAE.ComponentRef> crefs;
3201 output list<DAE.ComponentRef> uniqueCrefs;
3202 algorithm
3203 278612 uniqueCrefs := UnorderedSet.unique_list(crefs, ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
3204 end uniqueList;
3205
3206 annotation(__OpenModelica_Interface="frontend_base");
3207 end ComponentReference;
3208