Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 57.0% 102 / 0 / 179
Functions: -% 0 / 1 / 1
Branches: 60.3% 41 / 0 / 68

OMCompiler/Compiler/NFFrontEnd/NFBinding.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 uniontype NFBinding
37
38 public
39 import BaseModelica;
40 import Expression = NFExpression;
41 import NFInstNode.InstNode;
42 import NFInstNode;
43 import Type = NFType;
44 import NFPrefixes.{Variability, Purity};
45 import ErrorTypes;
46 import Mutable;
47 import Subscript = NFSubscript;
48
49 protected
50 import Absyn;
51 import Binding = NFBinding;
52 import Component = NFComponent;
53 import ComponentRef = NFComponentRef;
54 import Pointer;
55 import PointerWeak;
56 import Variable = NFVariable;
57 import DAE;
58 import Dump;
59 import Error;
60
61 public
62 constant Binding EMPTY_BINDING = UNBOUND();
63 constant Integer NO_CONFIDENCE = 99999; // Value has no significance other than being large, and visible when debugging.
64
65 type EachType = enumeration(
66 NOT_EACH,
67 EACH
68 );
69
70 type EvalState = enumeration(
71 NOT_EVALUATED,
72 EVALUATING,
73 EVALUATED
74 );
75
76 type Source = enumeration(
77 BINDING "The binding comes from a binding equation.",
78 TYPE "The binding is an attribute modifier of a type, see Inst.markTypeModifier.",
79 MODIFIER "The binding comes from a modifier.",
80 GENERATED "The binding was generated by the frontend."
81 );
82
83 record UNBOUND
84 end UNBOUND;
85
86 record RAW_BINDING
87 Absyn.Exp bindingExp;
88 NFInstNode.ScopeRef scope "Weakly: the scope owns the class this binding
89 sits in.";
90 list<Subscript> subs;
91 EachType eachType;
92 Source source;
93 Integer confidence;
94 SourceInfo info;
95 end RAW_BINDING;
96
97 record UNTYPED_BINDING
98 Expression bindingExp;
99 Boolean isProcessing;
100 NFInstNode.ScopeRef scope "See RAW_BINDING.scope.";
101 EachType eachType;
102 Source source;
103 Integer confidence;
104 SourceInfo info;
105 end UNTYPED_BINDING;
106
107 record TYPED_BINDING
108 Expression bindingExp;
109 Type bindingType;
110 Variability variability;
111 Purity purity;
112 EachType eachType;
113 Mutable<EvalState> evalState;
114 Boolean isFlattened;
115 Source source;
116 Integer confidence;
117 SourceInfo info;
118 end TYPED_BINDING;
119
120 record FLAT_BINDING
121 Expression bindingExp;
122 Variability variability;
123 Source source;
124 Integer confidence;
125 end FLAT_BINDING;
126
127 record CEVAL_BINDING
128 "Used by the constant evaluation for generated bindings (e.g. record
129 bindings constructed from the record fields) that should be discarded
130 during flattening."
131 Expression bindingExp;
132 end CEVAL_BINDING;
133
134 record INVALID_BINDING
135 Binding binding;
136 list<ErrorTypes.TotalMessage> errors;
137 end INVALID_BINDING;
138
139 record WILD end WILD;
140
141 public
142 function fromAbsyn
143 input Option<Absyn.Exp> bindingExp;
144 input Boolean eachPrefix;
145 input InstNode scope;
146 input Integer instanceLevel;
147 input SourceInfo info;
148 output Binding binding;
149 algorithm
150 binding := match bindingExp
151 local
152 Absyn.Exp exp;
153 EachType each_ty;
154
155 case SOME(exp)
156 algorithm
157
2/2
✓ Branch 0 taken 2056421 times.
✓ Branch 1 taken 16612 times.
2073033 each_ty := if eachPrefix then EachType.EACH else EachType.NOT_EACH;
158 2073033 then
159 RAW_BINDING(exp, InstNode.scopeRef(scope), {}, each_ty, Source.BINDING, instanceLevel, info);
160
161 else EMPTY_BINDING;
162 end match;
163 end fromAbsyn;
164
165 function isBound
166 input Binding binding;
167 output Boolean isBound;
168 algorithm
169 isBound := match binding
170 case UNBOUND() then false;
171 case INVALID_BINDING() then false;
172 else true;
173 end match;
174 end isBound;
175
176 function isExplicitlyBound
177 input Binding binding;
178 output Boolean isBound;
179 algorithm
180 isBound := match binding
181 case UNBOUND() then false;
182 case CEVAL_BINDING() then false;
183 case INVALID_BINDING() then false;
184 else true;
185 end match;
186 end isExplicitlyBound;
187
188 function isUnbound
189 input Binding binding;
190 output Boolean isUnbound;
191 algorithm
192 isUnbound := match binding
193 case UNBOUND() then true;
194 else false;
195 end match;
196 end isUnbound;
197
198 function isInvalid
199 input Binding binding;
200 output Boolean isInvalid;
201 algorithm
202 isInvalid := match binding
203 case INVALID_BINDING() then true;
204 else false;
205 end match;
206 end isInvalid;
207
208 function typedExp
209 input Binding binding;
210 output Option<Expression> exp;
211 algorithm
212 exp := match binding
213 42626 case TYPED_BINDING() then SOME(binding.bindingExp);
214 243 case FLAT_BINDING() then SOME(binding.bindingExp);
215 else NONE();
216 end match;
217 end typedExp;
218
219 function getUntypedExp
220 input Binding binding;
221 output Expression exp;
222 algorithm
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 120326 times.
120326 UNTYPED_BINDING(bindingExp = exp) := binding;
224 end getUntypedExp;
225
226 function getTypedExp
227 input Binding binding;
228 output Expression exp;
229 algorithm
230 exp := match binding
231 2741868 case TYPED_BINDING() then binding.bindingExp;
232 833872 case FLAT_BINDING() then binding.bindingExp;
233 end match;
234 end getTypedExp;
235
236 function setTypedExp
237 input Expression exp;
238 input output Binding binding;
239 algorithm
240 () := match binding
241 case TYPED_BINDING()
242 algorithm
243 254323 binding.bindingExp := exp;
244 then
245 ();
246
247 case FLAT_BINDING()
248 algorithm
249 9623 binding.bindingExp := exp;
250 then
251 ();
252 end match;
253 end setTypedExp;
254
255 function hasExp
256 input Binding binding;
257 output Boolean hasExp;
258 algorithm
259 hasExp := match binding
260 case UNTYPED_BINDING() then true;
261 case TYPED_BINDING() then true;
262 case FLAT_BINDING() then true;
263 else false;
264 end match;
265 end hasExp;
266
267 function getExp
268 input Binding binding;
269 output Expression exp;
270 algorithm
271 exp := match binding
272 35809 case UNTYPED_BINDING() then binding.bindingExp;
273 149141 case TYPED_BINDING() then binding.bindingExp;
274 17913 case FLAT_BINDING() then binding.bindingExp;
275 end match;
276 end getExp;
277
278 function getExpOpt
279 input Binding binding;
280 output Option<Expression> exp;
281 algorithm
282 exp := match binding
283 41308 case UNTYPED_BINDING() then SOME(binding.bindingExp);
284 6747 case TYPED_BINDING() then SOME(binding.bindingExp);
285 152 case FLAT_BINDING() then SOME(binding.bindingExp);
286 else NONE();
287 end match;
288 end getExpOpt;
289
290 function setExp
291 input Expression exp;
292 input output Binding binding;
293 algorithm
294 () := match binding
295 case UNTYPED_BINDING()
296 algorithm
297 ✗ binding.bindingExp := exp;
298 then
299 ();
300
301 case TYPED_BINDING()
302 algorithm
303 22875 binding.bindingExp := exp;
304 then
305 ();
306
307 case FLAT_BINDING()
308 algorithm
309 1870 binding.bindingExp := exp;
310 then
311 ();
312
313 end match;
314 end setExp;
315
316 function isRecordExp
317 input Binding binding;
318 output Boolean isRecordExp;
319 algorithm
320 isRecordExp := match binding
321 ✗ case TYPED_BINDING() then Expression.isRecord(binding.bindingExp);
322 else false;
323 end match;
324 end isRecordExp;
325
326 function isCrefExp
327 input Binding binding;
328 output Boolean isCref;
329 algorithm
330 isCref := match binding
331 ✗ case TYPED_BINDING() then Expression.isCref(binding.bindingExp);
332 else false;
333 end match;
334 end isCrefExp;
335
336 function recordFieldBinding
337 input InstNode fieldNode;
338 input Binding recordBinding;
339 output Binding fieldBinding = recordBinding;
340 protected
341 Expression exp;
342 Type ty;
343 Variability var;
344 Purity purity;
345 String field_name = InstNode.name(fieldNode);
346 algorithm
347 fieldBinding := match fieldBinding
348 case UNTYPED_BINDING()
349 algorithm
350 ✗ fieldBinding.bindingExp := Expression.recordElement(field_name, fieldBinding.bindingExp);
351 then
352 fieldBinding;
353
354 case TYPED_BINDING()
355 algorithm
356 26 exp := Expression.recordElement(field_name, fieldBinding.bindingExp);
357 26 ty := Expression.typeOf(exp);
358 26 purity := Expression.purity(exp);
359 26 var := Expression.variability(exp);
360 26 then
361 TYPED_BINDING(exp, ty, var, purity, fieldBinding.eachType, fieldBinding.evalState,
362 fieldBinding.isFlattened, fieldBinding.source, fieldBinding.confidence, fieldBinding.info);
363
364 case FLAT_BINDING()
365 algorithm
366 ✗ exp := Expression.recordElement(field_name, fieldBinding.bindingExp);
367 ✗ var := Expression.variability(exp);
368 ✗ then
369 FLAT_BINDING(exp, var, fieldBinding.source, fieldBinding.confidence);
370
371 case CEVAL_BINDING()
372 algorithm
373 ✗ fieldBinding.bindingExp := Expression.recordElement(field_name, fieldBinding.bindingExp);
374 then
375 fieldBinding;
376
377 end match;
378 end recordFieldBinding;
379
380 function variability
381 input Binding binding;
382 output Variability var;
383 algorithm
384 var := match binding
385 842559 case TYPED_BINDING() then binding.variability;
386 977 case FLAT_BINDING() then binding.variability;
387 else
388 algorithm
389 ✗ Error.terminate(getInstanceName() + " got unknown binding", sourceInfo());
390 ✗ then
391 fail();
392 end match;
393 end variability;
394
395 function setVariability
396 input Variability var;
397 input output Binding binding;
398 algorithm
399 () := match binding
400 ✗ case TYPED_BINDING() algorithm binding.variability := var; then ();
401 ✗ case FLAT_BINDING() algorithm binding.variability := var; then ();
402 else ();
403 end match;
404 end setVariability;
405
406 function purity
407 input Binding binding;
408 output Purity purity;
409 algorithm
410 purity := match binding
411 17 case TYPED_BINDING() then binding.purity;
412 else Purity.PURE;
413 end match;
414 end purity;
415
416 function getInfo
417 input Binding binding;
418 output SourceInfo info;
419 algorithm
420 info := match binding
421 ✗ case RAW_BINDING() then binding.info;
422 827963 case UNTYPED_BINDING() then binding.info;
423 1618012 case TYPED_BINDING() then binding.info;
424 else Absyn.dummyInfo;
425 end match;
426 end getInfo;
427
428 function getType
429 input Binding binding;
430 output Type ty;
431 algorithm
432 ty := match binding
433 case UNBOUND() then Type.UNKNOWN();
434 case RAW_BINDING() then Type.UNKNOWN();
435 case UNTYPED_BINDING() then Type.UNKNOWN();
436 13575 case TYPED_BINDING() then binding.bindingType;
437 280 case FLAT_BINDING() then Expression.typeOf(binding.bindingExp);
438 ✗ case CEVAL_BINDING() then Expression.typeOf(binding.bindingExp);
439 ✗ case INVALID_BINDING() then getType(binding.binding);
440 end match;
441 end getType;
442
443 function isEach
444 input Binding binding;
445 output Boolean isEach;
446 algorithm
447 isEach := match binding
448 25 case RAW_BINDING() then binding.eachType == EachType.EACH;
449 ✗ case UNTYPED_BINDING() then binding.eachType == EachType.EACH;
450 ✗ case TYPED_BINDING() then binding.eachType == EachType.EACH;
451 else false;
452 end match;
453 end isEach;
454
455 function isTyped
456 input Binding binding;
457 output Boolean isTyped;
458 algorithm
459 isTyped := match binding
460 case TYPED_BINDING() then true;
461 case FLAT_BINDING() then true;
462 else false;
463 end match;
464 end isTyped;
465
466 function toString
467 input Binding binding;
468 input String prefix = "";
469 output String string;
470 algorithm
471 string := match binding
472 case UNBOUND() then "";
473 20 case RAW_BINDING() then prefix + Dump.printExpStr(binding.bindingExp);
474 5 case UNTYPED_BINDING() then prefix + Expression.toString(binding.bindingExp);
475 13 case TYPED_BINDING() then prefix + Expression.toString(binding.bindingExp);
476 1 case FLAT_BINDING() then prefix + Expression.toString(binding.bindingExp);
477 ✗ case CEVAL_BINDING() then prefix + Expression.toString(binding.bindingExp);
478 ✗ case INVALID_BINDING() then toString(binding.binding, prefix);
479 else "";
480 end match;
481 end toString;
482
483 function toFlatString
484 input Binding binding;
485 input BaseModelica.OutputFormat format;
486 input String prefix = "";
487 output String string;
488 algorithm
489 string := match binding
490 case UNBOUND() then "";
491 ✗ case RAW_BINDING() then prefix + Dump.printExpStr(binding.bindingExp);
492 ✗ case UNTYPED_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format);
493 68 case TYPED_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format);
494 145 case FLAT_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format);
495 ✗ case CEVAL_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format);
496 ✗ case INVALID_BINDING() then toFlatString(binding.binding, format, prefix);
497 else "";
498 end match;
499
500
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 3 times.
313 if format.showConfidence then
501 3 string := string + " /* confidence = " + String(actualConfidence(binding)) + "*/";
502 end if;
503 end toFlatString;
504
505 function toDebugString
506 input Binding binding;
507 output String string;
508 algorithm
509 string := match binding
510 case WILD() then "WILD";
511 case UNBOUND() then "UNBOUND";
512 case RAW_BINDING() then "RAW_BINDING";
513 case UNTYPED_BINDING() then "UNTYPED_BINDING";
514 case TYPED_BINDING() then "TYPED_BINDING";
515 case FLAT_BINDING() then "FLAT_BINDING";
516 case CEVAL_BINDING() then "CEVAL_BINDING";
517 case INVALID_BINDING() then "INVALID_BINDING";
518 else "UNKNOWN";
519 end match;
520 end toDebugString;
521
522 function isEqual
523 input Binding binding1;
524 input Binding binding2;
525 output Boolean equal;
526 algorithm
527 equal := match (binding1, binding2)
528 case (UNBOUND(), UNBOUND()) then true;
529
530 // TODO: Handle propagated dims.
531 case (RAW_BINDING(), RAW_BINDING())
532 32551 then AbsynUtil.expEqual(binding1.bindingExp, binding2.bindingExp);
533
534 case (UNTYPED_BINDING(), UNTYPED_BINDING())
535 ✗ then Expression.isEqual(binding1.bindingExp, binding2.bindingExp);
536
537 case (TYPED_BINDING(), TYPED_BINDING())
538 1 then Expression.isEqual(binding1.bindingExp, binding2.bindingExp);
539
540 else false;
541 end match;
542 end isEqual;
543
544 function toDAE
545 input Binding binding;
546 output DAE.Binding outBinding;
547 algorithm
548 outBinding := match binding
549 case WILD() then DAE.UNBOUND();
550 case UNBOUND() then DAE.UNBOUND();
551 24727 case TYPED_BINDING() then makeDAEBinding(binding.bindingExp, binding.variability);
552 ✗ case FLAT_BINDING() then makeDAEBinding(binding.bindingExp, binding.variability);
553 case CEVAL_BINDING() then DAE.UNBOUND();
554 case INVALID_BINDING()
555 algorithm
556 ✗ Error.addTotalMessages(binding.errors);
557 ✗ then
558 fail();
559 else
560 algorithm
561 ✗ Error.terminate(getInstanceName() + " got untyped binding", sourceInfo());
562 ✗ then
563 fail();
564 end match;
565 end toDAE;
566
567 function makeDAEBinding
568 input Expression exp;
569 input Variability var;
570 output DAE.Binding binding;
571 algorithm
572 24727 binding := DAE.EQBOUND(
573 Expression.toDAE(exp),
574 NONE(),
575 Variability.variabilityToDAEConst(var),
576 DAE.BINDING_FROM_DEFAULT_VALUE() // TODO: revise this.
577 );
578 end makeDAEBinding;
579
580 function toDAEExp
581 input Binding binding;
582 output Option<DAE.Exp> bindingExp;
583 algorithm
584 bindingExp := match binding
585 case UNBOUND() then NONE();
586 75030 case TYPED_BINDING() then SOME(Expression.toDAE(binding.bindingExp));
587 85346 case FLAT_BINDING() then SOME(Expression.toDAE(binding.bindingExp));
588 case CEVAL_BINDING() then NONE();
589 else
590 algorithm
591 ✗ Error.terminate(getInstanceName() + " got untyped binding", sourceInfo());
592 ✗ then
593 fail();
594 end match;
595 end toDAEExp;
596
597 function applyExp
598 input Binding binding;
599 input ApplyFn fn;
600
601 partial function ApplyFn
602 input Expression exp;
603 end ApplyFn;
604 algorithm
605 () := match binding
606 ✗ case UNTYPED_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then ();
607 ✗ case TYPED_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then ();
608 ✗ case FLAT_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then ();
609 ✗ case CEVAL_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then ();
610 else ();
611 end match;
612 end applyExp;
613
614 function applyExpShallow
615 input Binding binding;
616 input ApplyFn fn;
617
618 partial function ApplyFn
619 input Expression exp;
620 end ApplyFn;
621 algorithm
622 () := match binding
623 ✗ case UNTYPED_BINDING() algorithm fn(binding.bindingExp); then ();
624
1/2
✓ Branch 0 taken 549476 times.
✗ Branch 1 not taken.
549476 case TYPED_BINDING() algorithm fn(binding.bindingExp); then ();
625
1/2
✓ Branch 0 taken 53285 times.
✗ Branch 1 not taken.
53285 case FLAT_BINDING() algorithm fn(binding.bindingExp); then ();
626 ✗ case CEVAL_BINDING() algorithm fn(binding.bindingExp); then ();
627 else ();
628 end match;
629 end applyExpShallow;
630
631 function mapExp
632 input output Binding binding;
633 input MapFunc mapFn;
634
635 partial function MapFunc
636 input output Expression exp;
637 end MapFunc;
638 protected
639 Expression e1, e2;
640 algorithm
641 () := match binding
642 case UNTYPED_BINDING(bindingExp = e1)
643 algorithm
644 1 e2 := Expression.map(e1, mapFn);
645
646
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if not referenceEq(e1, e2) then
647 1 binding.bindingExp := e2;
648 end if;
649 then
650 ();
651
652 case TYPED_BINDING(bindingExp = e1)
653 algorithm
654 186893 e2 := Expression.map(e1, mapFn);
655
656
2/2
✓ Branch 0 taken 37355 times.
✓ Branch 1 taken 149538 times.
186893 if not referenceEq(e1, e2) then
657 37355 binding.bindingExp := e2;
658 end if;
659 then
660 ();
661
662 case FLAT_BINDING(bindingExp = e1)
663 algorithm
664 59885 e2 := Expression.map(e1, mapFn);
665
666
2/2
✓ Branch 0 taken 6136 times.
✓ Branch 1 taken 53749 times.
59885 if not referenceEq(e1, e2) then
667 6136 binding.bindingExp := e2;
668 end if;
669 then
670 ();
671
672 case CEVAL_BINDING(bindingExp = e1)
673 algorithm
674 ✗ e2 := Expression.map(e1, mapFn);
675
676 ✗ if not referenceEq(e1, e2) then
677 ✗ binding.bindingExp := e2;
678 end if;
679 then
680 ();
681
682 else ();
683 end match;
684 end mapExp;
685
686 function mapExpShallow
687 input output Binding binding;
688 input MapFunc mapFn;
689
690 partial function MapFunc
691 input output Expression exp;
692 end MapFunc;
693 protected
694 Expression e1, e2;
695 algorithm
696 () := match binding
697 case UNTYPED_BINDING(bindingExp = e1)
698 algorithm
699 ✗ e2 := mapFn(e1);
700
701 ✗ if not referenceEq(e1, e2) then
702 ✗ binding.bindingExp := e2;
703 end if;
704 then
705 ();
706
707 case TYPED_BINDING(bindingExp = e1)
708 algorithm
709
2/2
✓ Branch 0 taken 867052 times.
✓ Branch 1 taken 1147382 times.
2014434 e2 := mapFn(e1);
710
711
2/2
✓ Branch 0 taken 110482 times.
✓ Branch 1 taken 1903952 times.
2014434 if not referenceEq(e1, e2) then
712 110482 binding.bindingExp := e2;
713 end if;
714 then
715 ();
716
717 case FLAT_BINDING(bindingExp = e1)
718 algorithm
719
2/2
✓ Branch 0 taken 12378 times.
✓ Branch 1 taken 677803 times.
690181 e2 := mapFn(e1);
720
721
2/2
✓ Branch 0 taken 16599 times.
✓ Branch 1 taken 673582 times.
690181 if not referenceEq(e1, e2) then
722 16599 binding.bindingExp := e2;
723 end if;
724 then
725 ();
726
727 case CEVAL_BINDING(bindingExp = e1)
728 algorithm
729 ✗ e2 := mapFn(e1);
730
731 ✗ if not referenceEq(e1, e2) then
732 ✗ binding.bindingExp := e2;
733 end if;
734 then
735 ();
736
737 else ();
738 end match;
739 end mapExpShallow;
740
741 function foldExp<ArgT>
742 input Binding binding;
743 input FoldFunc foldFn;
744 input output ArgT arg;
745
746 partial function FoldFunc
747 input Expression exp;
748 input output ArgT arg;
749 end FoldFunc;
750 algorithm
751 arg := match binding
752 ✗ case UNTYPED_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg);
753 498392 case TYPED_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg);
754 ✗ case FLAT_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg);
755 ✗ case CEVAL_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg);
756 else arg;
757 end match;
758 end foldExp;
759
760 function containsExp
761 input Binding binding;
762 input PredFunc predFn;
763 output Boolean res;
764
765 partial function PredFunc
766 input Expression exp;
767 output Boolean res;
768 end PredFunc;
769 algorithm
770 res := match binding
771 ✗ case UNTYPED_BINDING() then Expression.contains(binding.bindingExp, predFn);
772 ✗ case TYPED_BINDING() then Expression.contains(binding.bindingExp, predFn);
773 ✗ case FLAT_BINDING() then Expression.contains(binding.bindingExp, predFn);
774 ✗ case CEVAL_BINDING() then Expression.contains(binding.bindingExp, predFn);
775 else false;
776 end match;
777 end containsExp;
778
779 function update
780 input output Binding binding;
781 input Expression exp;
782 algorithm
783 binding := match binding
784
785 case WILD()
786 ✗ then TYPED_BINDING(
787 bindingExp = exp,
788 bindingType = Expression.typeOf(exp),
789 variability = Expression.variability(exp),
790 purity = Expression.purity(exp),
791 eachType = EachType.NOT_EACH,
792 evalState = if Expression.isConstNumber(exp)
793 then Mutable.create(EvalState.EVALUATED)
794 else Mutable.create(EvalState.NOT_EVALUATED),
795 isFlattened = true,
796 source = Source.BINDING,
797 confidence = NO_CONFIDENCE,
798 info = sourceInfo()
799 );
800
801 case UNBOUND()
802
2/2
✓ Branch 1 taken 273 times.
✓ Branch 2 taken 1593 times.
1866 then TYPED_BINDING(
803 bindingExp = exp,
804 bindingType = Expression.typeOf(exp),
805 variability = Expression.variability(exp),
806 purity = Expression.purity(exp),
807 eachType = EachType.NOT_EACH,
808 evalState = if Expression.isConstNumber(exp)
809 then Mutable.create(EvalState.EVALUATED)
810 else Mutable.create(EvalState.NOT_EVALUATED),
811 isFlattened = true,
812 source = Source.BINDING,
813 confidence = NO_CONFIDENCE,
814 info = sourceInfo()
815 );
816
817 case UNTYPED_BINDING() algorithm
818 ✗ binding.bindingExp := exp;
819 then binding;
820
821 case TYPED_BINDING() algorithm
822 155 binding.bindingExp := exp;
823 then binding;
824
825 case FLAT_BINDING() algorithm
826 9 binding.bindingExp := exp;
827 then binding;
828
829 case CEVAL_BINDING() algorithm
830 ✗ binding.bindingExp := exp;
831 then binding;
832
833 case INVALID_BINDING() algorithm
834 ✗ binding.binding := update(binding.binding, exp);
835 then binding;
836
837 case RAW_BINDING() algorithm
838 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because a raw binding cannot be updated."});
839 ✗ then fail();
840
841 else algorithm
842 ✗ Error.addMessage(Error.INTERNAL_ERROR, {getInstanceName() + " failed."});
843 ✗ then fail();
844
845 end match;
846 end update;
847
848 function setAttr
849 "sets a specific attribute value and adds it if it does not exist"
850 input output list<tuple<String, Binding>> ty_attr;
851 input String attr_name;
852 input Binding attr_value;
853 algorithm
854 ty_attr := match ty_attr
855 local
856 tuple<String, Binding> at;
857 list<tuple<String, Binding>> rest;
858 String name;
859 ✗ case (name, _ ) :: rest guard(name == attr_name) then (attr_name, attr_value) :: rest;
860 132 case at :: rest then at :: setAttr(rest, attr_name, attr_value);
861 118 case {} then {(attr_name, attr_value)};
862 end match;
863 end setAttr;
864
865 function propagate
866 "Propagates a modifier through an element, given as a list of split subscript."
867 input output Binding binding;
868 input list<Subscript> subs;
869 algorithm
870 () := match binding
871 case RAW_BINDING()
872 algorithm
873 1827186 binding.subs := listAppend(binding.subs, subs);
874
875
1/2
✓ Branch 0 taken 1827186 times.
✗ Branch 1 not taken.
1827186 if binding.source <> Source.TYPE then
876 1827186 binding.source := Source.MODIFIER;
877 end if;
878 then
879 ();
880
881 else ();
882 end match;
883 end propagate;
884
885 function unpropagate
886 input output Binding binding;
887 input InstNode node;
888 algorithm
889 () := match binding
890 case RAW_BINDING()
891 algorithm
892
4/6
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25 times.
75 binding.subs := list(s for s guard not Subscript.isSplitFromOrigin(s, node) in binding.subs);
893 then
894 ();
895
896 else ();
897 end match;
898 end unpropagate;
899
900 function source
901 input Binding binding;
902 output Source source;
903 algorithm
904 source := match binding
905 ✗ case RAW_BINDING() then binding.source;
906 ✗ case UNTYPED_BINDING() then binding.source;
907 215410 case TYPED_BINDING() then binding.source;
908 34013 case FLAT_BINDING() then binding.source;
909 else Source.BINDING;
910 end match;
911 end source;
912
913 function setSource
914 input Source source;
915 input output Binding binding;
916 algorithm
917 () := match binding
918 1293580 case RAW_BINDING() algorithm binding.source := source; then ();
919 ✗ case UNTYPED_BINDING() algorithm binding.source := source; then ();
920 ✗ case TYPED_BINDING() algorithm binding.source := source; then ();
921 ✗ case FLAT_BINDING() algorithm binding.source := source; then ();
922 else ();
923 end match;
924 end setSource;
925
926 function setConfidence
927 input Integer confidence;
928 input output Binding binding;
929 algorithm
930 () := match binding
931 1293580 case RAW_BINDING() algorithm binding.confidence := confidence; then ();
932 ✗ case UNTYPED_BINDING() algorithm binding.confidence := confidence; then ();
933 ✗ case TYPED_BINDING() algorithm binding.confidence := confidence; then ();
934 ✗ case FLAT_BINDING() algorithm binding.confidence := confidence; then ();
935 else ();
936 end match;
937 end setConfidence;
938
939 function makeUntyped
940 input Expression exp;
941 input InstNode scope;
942 input EachType eachType;
943 input Source source;
944 input SourceInfo info;
945 input Integer confidence = NO_CONFIDENCE;
946 output Binding binding;
947 algorithm
948 607 binding := UNTYPED_BINDING(exp, false, InstNode.scopeRef(scope), eachType, source, confidence, info);
949 end makeUntyped;
950
951 function makeTyped
952 input Expression exp;
953 input EachType eachType;
954 input Source source;
955 input SourceInfo info;
956 input EvalState state = EvalState.NOT_EVALUATED;
957 input Integer confidence = NO_CONFIDENCE;
958 output Binding binding;
959 algorithm
960 66 binding := TYPED_BINDING(exp, Expression.typeOf(exp),
961 Expression.variability(exp), Expression.purity(exp),
962 eachType, Mutable.create(state), false, source, confidence, info);
963 end makeTyped;
964
965 function makeFlat
966 input Expression exp;
967 input Variability var;
968 input Source source;
969 input Integer confidence = NO_CONFIDENCE;
970 output Binding binding;
971 algorithm
972 364751 binding := FLAT_BINDING(exp, var, source, confidence);
973 end makeFlat;
974
975 function isEvaluated
976 input Binding binding;
977 output Boolean evaluated;
978 algorithm
979 evaluated := match binding
980 case TYPED_BINDING()
981 36 then Mutable.access(binding.evalState) == EvalState.EVALUATED;
982 case CEVAL_BINDING() then true;
983 else false;
984 end match;
985 end isEvaluated;
986
987 function hasTypeOrigin
988 input Binding binding;
989 output Boolean res;
990 algorithm
991 res := match binding
992 case RAW_BINDING()
993 guard not listEmpty(binding.subs)
994 32 then Subscript.isSplitClassProxy(listHead(binding.subs));
995
996 else false;
997 end match;
998 end hasTypeOrigin;
999
1000 function expandEach
1001 "Expands the raw binding with each for a component x into
1002 fill(binding, size(x, 1), size(x, 2), ...)"
1003 input output Binding binding;
1004 input InstNode node;
1005 protected
1006 list<Absyn.Exp> args;
1007 Absyn.Exp node_exp;
1008 constant Absyn.ComponentRef size_name = Absyn.ComponentRef.CREF_IDENT("size", {});
1009 constant Absyn.ComponentRef fill_name = Absyn.ComponentRef.CREF_IDENT("fill", {});
1010 algorithm
1011 () := match binding
1012 case RAW_BINDING(eachType = EachType.EACH)
1013 algorithm
1014 ✗ node_exp := Absyn.Exp.CREF(Absyn.ComponentRef.CREF_IDENT(InstNode.name(node), {}));
1015 args := {};
1016
1017 ✗ for i in InstNode.dimensionCount(node):-1:1 loop
1018 ✗ args := AbsynUtil.makeCall(size_name, {node_exp, Absyn.Exp.INTEGER(i)}) :: args;
1019 end for;
1020
1021 ✗ args := binding.bindingExp :: args;
1022 ✗ binding.bindingExp := AbsynUtil.makeCall(fill_name, args);
1023 then
1024 ();
1025
1026 else ();
1027 end match;
1028 end expandEach;
1029
1030 function isClockOrSampleFunction
1031 input Binding binding;
1032 output Boolean b;
1033 algorithm
1034 b := match getExpOpt(binding)
1035 local
1036 Expression exp;
1037 2993 case SOME(exp) then Expression.isClockOrSampleFunction(exp);
1038 else false;
1039 end match;
1040 end isClockOrSampleFunction;
1041
1042 function confidence
1043 "Returns the confidence of a binding, i.e. on what level of the instance
1044 tree it was set."
1045 input Binding binding;
1046 output Integer confidence;
1047 algorithm
1048 confidence := match binding
1049 ✗ case RAW_BINDING() then binding.confidence;
1050 ✗ case UNTYPED_BINDING() then binding.confidence;
1051 199674 case TYPED_BINDING() then binding.confidence;
1052 34017 case FLAT_BINDING() then binding.confidence;
1053 else NO_CONFIDENCE;
1054 end match;
1055 end confidence;
1056
1057 function isFromType
1058 "Returns true if the binding is an attribute modifier of a type rather than
1059 of a component."
1060 input Binding binding;
1061 output Boolean fromType = source(binding) == Source.TYPE;
1062 end isFromType;
1063
1064 function compareStartConfidence
1065 "Compares two start attributes by MLS 8.6.2 priority: a start set on a
1066 component beats one set by its type, then the lower actual confidence wins,
1067 then the lower raw confidence. Negative if b1 is stronger, 0 if tied."
1068 input Binding b1;
1069 input Binding b2;
1070 output Integer cmp;
1071 algorithm
1072
2/2
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 28 times.
39 if isFromType(b1) <> isFromType(b2) then
1073
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 10 times.
11 cmp := if isFromType(b1) then 1 else -1;
1074 else
1075 28 cmp := actualConfidence(b1) - actualConfidence(b2);
1076
1077
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 21 times.
28 if cmp == 0 then
1078 21 cmp := confidence(b1) - confidence(b2);
1079 end if;
1080 end if;
1081 end compareStartConfidence;
1082
1083 function actualConfidence
1084 "Returns the actual confidence for a binding, which if the binding consists
1085 of a single parameter is the highest confidence (lowest number) of the
1086 binding itself and the actual confidence of the parameter's binding, as
1087 per 8.6.2. For any other kind of binding, and for the attribute modifiers
1088 of a type, the actual confidence is just the confidence stored in the
1089 binding."
1090 input Binding binding;
1091 output Integer conf = NO_CONFIDENCE;
1092 protected
1093 Binding b = binding;
1094 Expression exp;
1095 ComponentRef cref;
1096 InstNode node;
1097 Component comp;
1098 Variable var;
1099 algorithm
1100
2/2
✓ Branch 1 taken 60514 times.
✓ Branch 2 taken 12 times.
60526 if isFromType(binding) then
1101 12 conf := confidence(binding);
1102 12 return;
1103 end if;
1104
1105
2/2
✓ Branch 1 taken 64134 times.
✓ Branch 2 taken 60514 times.
124648 while hasExp(b) loop
1106 64134 conf := min(conf, confidence(b));
1107 64134 exp := getExp(b);
1108 b := NFBinding.EMPTY_BINDING;
1109
1110 () := match exp
1111 case Expression.CREF()
1112 guard ComponentRef.isCref(exp.cref)
1113 algorithm
1114 4112 node := InstNode.resolveInner(ComponentRef.node(exp.cref));
1115
1116 () := match node
1117 // crefs lowered by the new backend point to variables, not components
1118 case InstNode.VAR_NODE()
1119 algorithm
1120 57 var := Pointer.access(PointerWeak.upgrade(node.varPointer));
1121
1122
2/2
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 6 times.
57 if Variable.variability(var) < Variability.DISCRETE then
1123 51 b := var.binding;
1124 end if;
1125 then
1126 ();
1127
1128 else
1129 algorithm
1130
1/2
✓ Branch 1 taken 4055 times.
✗ Branch 2 not taken.
4055 if InstNode.isComponent(node) then
1131 4055 comp := InstNode.component(node);
1132
1133
1/2
✓ Branch 1 taken 4055 times.
✗ Branch 2 not taken.
4055 if Component.variability(comp) < Variability.DISCRETE then
1134 4055 b := Component.getBinding(comp);
1135 end if;
1136 end if;
1137 then
1138 ();
1139 end match;
1140 then
1141 ();
1142
1143 else ();
1144 end match;
1145 end while;
1146 end actualConfidence;
1147
1148 annotation(__OpenModelica_Interface="nf_frontend");
1149 end NFBinding;
1150