Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 67.2% 961 / 0 / 1429
Functions: -% 0 / 1 / 1
Branches: 56.8% 403 / 0 / 710

OMCompiler/Compiler/FrontEnd/Types.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 Types
37 " file: Types.mo
38 package: Types
39 description: Type system
40
41
42 This file specifies the type system, as defined in the modelica specification.
43 It contains an MetaModelica Compiler (MMC) type called Type which defines types.
44 It also contains functions for determining subtyping etc.
45
46 There are a few known problems with this module.
47 It currently depends on SCode.Attributes, which in turn depends on Absyn.ArrayDim.
48 However, the only things used from those modules are constants that could be moved to their own modules.
49
50 "
51
52 public import ClassInf;
53 public import Absyn;
54 public import AbsynUtil;
55 public import DAE;
56 public import InstTypes;
57 public import TypesDump;
58 public import Values;
59 public import SCode;
60
61 protected type Binding = DAE.Binding;
62 protected type Const = DAE.Const;
63 protected type EqualityConstraint = DAE.EqualityConstraint;
64 protected type FuncArg = DAE.FuncArg;
65 protected type Properties = DAE.Properties;
66 protected type TupleConst = DAE.TupleConst;
67 protected type Type = DAE.Type;
68 protected type Var = DAE.Var;
69 protected type EqMod = DAE.EqMod;
70
71 protected import ComponentReference;
72 protected import ComponentReferenceBasics;
73 protected import Config;
74 protected import Dump;
75 protected import Debug;
76 protected import Error;
77 protected import Expression;
78 protected import ExpressionSimplify;
79 protected import Flags;
80 protected import List;
81 protected import Print;
82 protected import Util;
83 protected import System;
84 protected import ValuesDump;
85 protected import ValuesUtil;
86 protected import DAEUtil;
87 protected import MetaModelica.Dangerous.listReverseInPlace;
88 protected import ClassInfUtil;
89 protected import ExpressionBasics;
90
91 public function discreteType "Succeeds for all the discrete types, Integer, String, Boolean and enumeration."
92 input DAE.Type inType;
93 algorithm
94 ✗ true := isDiscreteType(inType);
95 end discreteType;
96
97 public function isDiscreteType
98 input DAE.Type inType;
99 output Boolean outIsDiscrete;
100 algorithm
101 outIsDiscrete := match inType
102 case DAE.T_INTEGER() then true;
103 case DAE.T_STRING() then true;
104 case DAE.T_BOOL() then true;
105 case DAE.T_CLOCK() then true;
106 case DAE.T_ENUMERATION() then true;
107 ✗ case DAE.T_SUBTYPE_BASIC() then isDiscreteType(inType.complexType);
108 else false;
109 end match;
110 end isDiscreteType;
111
112 public function propsAnd "Function for merging a list of properties, currently only working on DAE.PROP() and not TUPLE_DAE.PROP()."
113 input list<DAE.Properties> inProps;
114 output DAE.Properties outProp;
115 algorithm outProp := match inProps
116 local
117 Properties prop;
118 Const c,c2;
119 Type ty,ty2;
120 list<DAE.Properties> props;
121
122 case prop::{} then prop;
123 case (DAE.PROP(ty,c))::props
124 algorithm
125
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 379 times.
379 DAE.PROP(ty2,c2) := propsAnd(props);
126 379 c := constAnd(c,c2);
127
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 379 times.
379 true := equivtypes(ty,ty2);
128 379 then
129 DAE.PROP(ty,c);
130 end match;
131 end propsAnd;
132
133 public function makePropsNotConst
134 "returns the same Properties but with the const flag set to Var"
135 input DAE.Properties inProperties;
136 output DAE.Properties outProperties;
137 algorithm outProperties := match inProperties
138 local
139 Type t;
140 ✗ case DAE.PROP(type_=t) then DAE.PROP(t,DAE.C_VAR());
141 end match;
142 end makePropsNotConst;
143
144 // stefan
145 public function getConstList
146 "retrieves a list of Consts from a list of Properties"
147 input list<DAE.Properties> inPropertiesList;
148 output list<DAE.Const> outConstList;
149 algorithm
150 outConstList := match inPropertiesList
151 local
152 Const c;
153 list<DAE.Const> ccdr;
154 list<DAE.Properties> pcdr;
155 TupleConst tc;
156 case {} then {};
157 case DAE.PROP(constFlag=c) :: pcdr
158 algorithm
159 3293 ccdr := getConstList(pcdr);
160 then
161 c :: ccdr;
162 case DAE.PROP_TUPLE(tupleConst=tc) :: pcdr
163 algorithm
164 ✗ c := propertiesListToConst2(tc);
165 ✗ ccdr := getConstList(pcdr);
166 then
167 c :: ccdr;
168 end match;
169 end getConstList;
170
171
172 public function propertiesListToConst "this function elaborates on a DAE.Properties and return the DAE.Const value."
173 input list<DAE.Properties> p;
174 output DAE.Const c;
175 algorithm
176 c := match p
177 local
178 list<DAE.Properties> pps;
179 Const c1,c2;
180 TupleConst tc1;
181
182 case {} then DAE.C_CONST();
183
184 case (DAE.PROP(_,c1))::pps
185 algorithm
186 4690 c2 := propertiesListToConst(pps);
187 4690 c1 := constAnd(c1, c2);
188 then
189 c1;
190
191 case (DAE.PROP_TUPLE(_,tc1))::pps
192 algorithm
193 ✗ c1 := propertiesListToConst2(tc1);
194 ✗ c2 := propertiesListToConst(pps);
195 ✗ c1 := constAnd(c1, c2);
196 then
197 c1;
198 end match;
199 end propertiesListToConst;
200
201 protected function propertiesListToConst2 ""
202 input DAE.TupleConst t;
203 output DAE.Const c;
204 algorithm
205 c := match t
206 local
207 Const c1,c2;
208 list<TupleConst> tcxl;
209 TupleConst tc1;
210
211 case DAE.SINGLE_CONST(c1) then c1;
212
213 case DAE.TUPLE_CONST(tc1::tcxl)
214 algorithm
215 ✗ c1 := propertiesListToConst2(tc1);
216 ✗ c2 := tupleConstListToConst(tcxl);
217 ✗ c1 := constAnd(c1, c2);
218 then
219 c1;
220 end match;
221 end propertiesListToConst2;
222
223 public function tupleConstListToConst ""
224 input list<DAE.TupleConst> t;
225 output DAE.Const c;
226 algorithm
227 c := match t
228 local
229 TupleConst p1;
230 Const c1,c2;
231 list<TupleConst> tcxl;
232
233 case {} then DAE.C_CONST();
234
235 case (DAE.SINGLE_CONST(c1))::tcxl
236 algorithm
237 6097 c2 := tupleConstListToConst(tcxl);
238 6097 c1 := constAnd(c1, c2);
239 then
240 c1;
241
242 case (p1 as DAE.TUPLE_CONST(_))::tcxl
243 algorithm
244 ✗ c1 := propertiesListToConst2(p1);
245 ✗ c2 := tupleConstListToConst(tcxl);
246 ✗ c1 := constAnd(c1, c2);
247 then
248 c1;
249 end match;
250 end tupleConstListToConst;
251
252 public function externalObjectType
253 "author: PA
254 Succeeds if type is ExternalObject"
255 input DAE.Type inType;
256 algorithm
257 () := match inType
258 case DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(_)) then ();
259 end match;
260 end externalObjectType;
261
262 public function varBinding
263 input DAE.Var inVar;
264 output DAE.Binding outBinding;
265 algorithm
266 212 DAE.TYPES_VAR(binding = outBinding) := inVar;
267 end varBinding;
268
269 public function varEqualName
270 input DAE.Var inVar1;
271 input DAE.Var inVar2;
272 output Boolean outEqual;
273 protected
274 String name1, name2;
275 algorithm
276 234 DAE.TYPES_VAR(name = name1) := inVar1;
277 234 DAE.TYPES_VAR(name = name2) := inVar2;
278
2/4
✓ Branch 0 taken 234 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 234 times.
234 outEqual := name1 == name2;
279 end varEqualName;
280
281 public function externalObjectConstructorType "author: PA
282 Succeeds if type is ExternalObject constructor function"
283 input DAE.Type inType;
284 algorithm
285 () := match inType
286 local Type tp;
287 case DAE.T_FUNCTION(funcResultType = tp)
288 algorithm
289 3 externalObjectType(tp);
290 then ();
291 end match;
292 end externalObjectConstructorType;
293
294 public function simpleType "author: PA
295 Succeeds for all the builtin types, Integer, String, Real, Boolean"
296 input DAE.Type inType;
297 algorithm
298 ✗ true := isSimpleType(inType);
299 end simpleType;
300
301 public function isSimpleType
302 "Returns true for all the builtin types, Integer, String, Real, Boolean"
303 input DAE.Type inType;
304 output Boolean b;
305 algorithm
306 b := match inType
307 local DAE.Type t;
308 case DAE.T_REAL() then true;
309 case DAE.T_INTEGER() then true;
310 case DAE.T_STRING() then true;
311 case DAE.T_BOOL() then true;
312 // BTH
313 case DAE.T_CLOCK() then true;
314 case DAE.T_ENUMERATION() then true;
315 ✗ case DAE.T_SUBTYPE_BASIC(complexType = t) then isSimpleType(t);
316 ✗ case DAE.T_FUNCTION(funcResultType = t) then isSimpleType(t);
317 else false;
318 end match;
319 end isSimpleType;
320
321 public function isSimpleNumericType
322 "Returns true for simple numeric builtin types, Integer and Real"
323 input DAE.Type inType;
324 output Boolean b;
325 algorithm
326 b := match inType
327 local DAE.Type t;
328 case DAE.T_REAL() then true;
329 case DAE.T_INTEGER() then true;
330 ✗ case DAE.T_SUBTYPE_BASIC(complexType = t) then isSimpleNumericType(t);
331 ✗ case DAE.T_FUNCTION(funcResultType = t) then isSimpleNumericType(t);
332 else false;
333 end match;
334 end isSimpleNumericType;
335
336 public function isNumericType "This function checks if the element type is Numeric type or array of Numeric type."
337 input DAE.Type inType;
338 output Boolean outBool;
339 algorithm
340 outBool := match inType
341 local Type ty;
342
343 ✗ case DAE.T_ARRAY(ty = ty) then isNumericType(ty);
344 ✗ case DAE.T_SUBTYPE_BASIC(complexType = ty) then isNumericType(ty);
345 ✗ case DAE.T_FUNCTION(funcResultType = ty) then isNumericType(ty);
346 ✗ else isSimpleNumericType(inType);
347
348 end match;
349 end isNumericType;
350
351 public function isConnector
352 "Returns true if the given type is a connector type, otherwise false."
353 input DAE.Type inType;
354 output Boolean outIsConnector;
355 algorithm
356 outIsConnector := match inType
357 case DAE.T_COMPLEX(complexClassType = ClassInf.CONNECTOR()) then true;
358 case DAE.T_SUBTYPE_BASIC(complexClassType = ClassInf.CONNECTOR()) then true;
359 else false;
360 end match;
361 end isConnector;
362
363 public function isComplexConnector
364 "Returns true if the given type is a complex connector type, i.e. a connector
365 with components, otherwise false."
366 input DAE.Type inType;
367 output Boolean outIsComplexConnector;
368 algorithm
369 outIsComplexConnector := match inType
370 case DAE.T_COMPLEX(complexClassType = ClassInf.CONNECTOR()) then true;
371 else false;
372 end match;
373 end isComplexConnector;
374
375 public function isComplexExpandableConnector
376 "Returns true if the given type is an expandable connector, otherwise false."
377 input DAE.Type inType;
378 output Boolean outResult;
379 algorithm
380 outResult := match inType
381 case DAE.T_COMPLEX(complexClassType =
382 ClassInf.CONNECTOR(isExpandable = true)) then true;
383 case DAE.T_SUBTYPE_BASIC(complexClassType =
384 ClassInf.CONNECTOR(isExpandable = true)) then true;
385 else false;
386 end match;
387 end isComplexExpandableConnector;
388
389 public function isComplexType "
390 Author: BZ, 2008-11
391 This function checks wheter a type is complex AND not extending a base type."
392 input DAE.Type ity;
393 output Boolean b;
394 algorithm
395 b := match ity
396 local Type ty;
397 3413 case DAE.T_SUBTYPE_BASIC(complexType = ty) then isComplexType(ty);
398 44 case DAE.T_FUNCTION(funcResultType = ty) then isComplexType(ty);
399 case DAE.T_COMPLEX(varLst = _::_) then true; // not derived from baseclass
400 else false;
401 end match;
402 end isComplexType;
403
404 public function isExternalObject "Returns true if type is COMPLEX and external object (ClassInf)"
405 input DAE.Type tp;
406 output Boolean b;
407 algorithm
408 b := match tp
409 case DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(_)) then true;
410 else false;
411 end match;
412 end isExternalObject;
413
414 public function expTypetoTypesType
415 " Converts a DAE.Type to a DAE.Type
416 NOTE: This function should not be used in general, since it is not recommended to translate DAE.Type into DAE.Type."
417 input DAE.Type inType;
418 output DAE.Type oType;
419 algorithm
420 oType := matchcontinue inType
421 local
422 Type ty,tty;
423 Type at;
424 DAE.Dimensions ad;
425 DAE.Dimension dim;
426 list<DAE.Var> vars;
427 ClassInf.State CIS;
428 DAE.EqualityConstraint ec;
429
430 // convert just the array!
431 case DAE.T_ARRAY(at,{dim})
432 algorithm
433 669 ty := expTypetoTypesType(at);
434 669 tty := DAE.T_ARRAY(ty,{dim});
435 then
436 tty;
437 case DAE.T_ARRAY(at,dim::ad)
438 algorithm
439 103 ty := expTypetoTypesType(DAE.T_ARRAY(at,ad));
440 103 tty := DAE.T_ARRAY(ty,{dim});
441 then
442 tty;
443
444 case DAE.T_COMPLEX(CIS, vars, ec)
445 algorithm
446 3 vars := List.map(vars, convertFromExpToTypesVar);
447 3 then
448 DAE.T_COMPLEX(CIS, vars, ec, inType.usedExternally);
449
450 case DAE.T_SUBTYPE_BASIC(CIS, vars, ty, ec)
451 algorithm
452 ✗ vars := List.map(vars, convertFromExpToTypesVar);
453 ✗ ty := expTypetoTypesType(ty);
454 ✗ then DAE.T_SUBTYPE_BASIC(CIS, vars, ty, ec);
455
456 case DAE.T_METABOXED(ty)
457 algorithm
458 ✗ ty := expTypetoTypesType(ty);
459 ✗ then DAE.T_METABOXED(ty);
460
461 // the rest fall in line!
462 else inType;
463
464 end matchcontinue;
465 end expTypetoTypesType;
466
467 protected function convertFromExpToTypesVar ""
468 input DAE.Var inVar;
469 output DAE.Var outVar;
470 algorithm
471 outVar := inVar;
472 7 outVar.ty := expTypetoTypesType(inVar.ty);
473 end convertFromExpToTypesVar;
474
475 public function isTuple "Returns true if type is TUPLE"
476 input DAE.Type tp;
477 output Boolean b;
478 algorithm
479 b := match tp
480 case DAE.T_TUPLE() then true;
481 else false;
482 end match;
483 end isTuple;
484
485 public function isMetaTuple "Returns true if type is TUPLE"
486 input DAE.Type tp;
487 output Boolean b;
488 algorithm
489 b := match tp
490 case DAE.T_METATUPLE() then true;
491 else false;
492 end match;
493 end isMetaTuple;
494
495 public function isRecord "Returns true if type is COMPLEX and a record (ClassInf)"
496 input DAE.Type tp;
497 output Boolean b;
498 algorithm
499 b := match tp
500 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)) then true;
501 else false;
502 end match;
503 end isRecord;
504
505 public function recordHasConstVar
506 "Returns true if an record has at least one component of type CONST.
507 Fails if input type ty is not an record."
508 input DAE.Type ty;
509 output Boolean hasConstType = false;
510 algorithm
511 () := match ty
512 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)) algorithm
513
2/2
✓ Branch 0 taken 24593 times.
✓ Branch 1 taken 8010 times.
32603 for var in ty.varLst loop
514
2/2
✓ Branch 1 taken 24588 times.
✓ Branch 2 taken 5 times.
24593 if DAEUtil.isConstVar(var) then
515 hasConstType := true;
516 break;
517 end if;
518 end for;
519 then();
520 else algorithm
521 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because input type is not a record."});
522 ✗ then fail();
523 end match;
524 end recordHasConstVar;
525
526 public function getRecordPath "gets the record path"
527 input DAE.Type tp;
528 output Absyn.Path p;
529 algorithm
530 p := match tp
531 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(p))
532 then p;
533 end match;
534 end getRecordPath;
535
536 public function isRecordWithOnlyReals "Returns true if type is a record only containing Reals"
537 input DAE.Type tp;
538 output Boolean b;
539 algorithm
540 b := match tp
541 local
542 list<DAE.Var> varLst;
543
544 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_),varLst = varLst)
545 ✗ then List.all(List.map(varLst, getVarType), isReal);
546
547 // otherwise false
548 else false;
549 end match;
550 end isRecordWithOnlyReals;
551
552 public function getVarType "Return the Type of a Var"
553 input DAE.Var v;
554 output DAE.Type tp;
555 algorithm
556 tp := match v
557 case DAE.TYPES_VAR(ty = tp) then tp;
558 else
559 algorithm
560 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"Types.getVarType failed"});
561 ✗ then fail();
562 end match;
563 end getVarType;
564
565 public function varIsVariable
566 input DAE.Var v;
567 output Boolean b;
568 algorithm
569 b := match v
570 case DAE.TYPES_VAR(attributes=DAE.ATTR(variability=SCode.VAR())) then true;
571 case DAE.TYPES_VAR(attributes=DAE.ATTR(variability=SCode.DISCRETE())) then true;
572 else false;
573 end match;
574 end varIsVariable;
575
576 public function isReal "Returns true if type is Real"
577 input DAE.Type tp;
578 output Boolean res;
579 algorithm
580 29991494 res := isScalarReal(arrayElementType(tp));
581 end isReal;
582
583 public function isScalarReal
584 input DAE.Type inType;
585 output Boolean outIsScalarReal;
586 algorithm
587 outIsScalarReal := match inType
588 local
589 Type ty;
590
591 case DAE.T_REAL() then true;
592 11 case DAE.T_SUBTYPE_BASIC(complexType = ty) then isScalarReal(ty);
593 else false;
594 end match;
595 end isScalarReal;
596
597 public function isRealOrSubTypeReal "
598 Author BZ 2008-05
599 This function verifies if it is some kind of a Real type we are working with."
600 input DAE.Type inType;
601 output Boolean b;
602 protected
603 Boolean lb1, lb2;
604 algorithm
605 29513909 lb1 := isReal(inType);
606 29513909 lb2 := equivtypes(inType, DAE.T_REAL_DEFAULT);
607 29513909 b := lb1 or lb2;
608 end isRealOrSubTypeReal;
609
610 public function isIntegerOrSubTypeInteger "
611 Author BZ 2009-02
612 This function verifies if it is some kind of an Integer type we are working with."
613 input DAE.Type inType;
614 output Boolean b;
615 protected
616 Boolean lb1, lb2;
617 algorithm
618 54236 lb1 := isInteger(inType);
619 54236 lb2 := equivtypes(inType, DAE.T_INTEGER_DEFAULT);
620 54236 b := lb1 or lb2;
621 end isIntegerOrSubTypeInteger;
622
623 public function isEnumerationOrSubTypeEnumeration "
624 This function verifies if it is some kind of an Enumeration type we are working with."
625 input DAE.Type inType;
626 output Boolean b;
627 protected
628 Boolean lb1, lb2;
629 algorithm
630 ✗ lb1 := isEnumeration(inType);
631 ✗ lb2 := equivtypes(inType, DAE.T_ENUMERATION_DEFAULT);
632 ✗ b := lb1 or lb2;
633 end isEnumerationOrSubTypeEnumeration;
634
635 protected function isClockOrSubTypeClock1
636 input DAE.Type inType;
637 output Boolean b;
638 protected
639 Boolean lb1, lb2, lb3;
640 algorithm
641 172184 lb1 := isClock(inType);
642 172184 lb2 := equivtypes(inType, DAE.T_CLOCK_DEFAULT);
643 172184 lb3 := not equivtypes(inType, DAE.T_UNKNOWN_DEFAULT);
644
3/4
✓ Branch 0 taken 171459 times.
✓ Branch 1 taken 725 times.
✓ Branch 2 taken 171459 times.
✗ Branch 3 not taken.
172184 b := lb1 or (lb2 and lb3);
645 end isClockOrSubTypeClock1;
646
647 public function isClockOrSubTypeClock
648 input DAE.Type inType;
649 output Boolean b;
650 algorithm
651 b := match inType
652 local
653 DAE.Type ty;
654 case DAE.T_FUNCTION(funcResultType=ty)
655 ✗ then isClockOrSubTypeClock1(ty);
656 172184 else isClockOrSubTypeClock1(inType);
657 end match;
658 end isClockOrSubTypeClock;
659
660 public function isBooleanOrSubTypeBoolean
661 "@author: adrpo
662 This function verifies if it is some kind of a Boolean type we are working with."
663 input DAE.Type inType;
664 output Boolean b;
665 protected
666 Boolean lb1, lb2;
667 algorithm
668 259 lb1 := isBoolean(inType);
669 259 lb2 := equivtypes(inType, DAE.T_BOOL_DEFAULT);
670 259 b := lb1 or lb2;
671 end isBooleanOrSubTypeBoolean;
672
673 public function isStringOrSubTypeString
674 "@author: adrpo
675 This function verifies if it is some kind of a String type we are working with."
676 input DAE.Type inType;
677 output Boolean b;
678 protected
679 Boolean lb1, lb2;
680 algorithm
681 4 lb1 := isString(inType);
682 4 lb2 := equivtypes(inType, DAE.T_STRING_DEFAULT);
683 4 b := lb1 or lb2;
684 end isStringOrSubTypeString;
685
686 public function isIntegerOrRealOrSubTypeOfEither
687 "Checks if a type is either some Integer or Real type."
688 input DAE.Type t;
689 output Boolean b;
690 algorithm
691 b := match t
692 case _ guard isRealOrSubTypeReal(t) then true;
693 case _ guard isIntegerOrSubTypeInteger(t) then true;
694 else false;
695 end match;
696 end isIntegerOrRealOrSubTypeOfEither;
697
698 public function isIntegerOrRealOrBooleanOrSubTypeOfEither
699 "Checks if a type is either some Integer or Real type."
700 input DAE.Type t;
701 output Boolean b;
702 algorithm
703 b := match t
704 case _ guard isRealOrSubTypeReal(t) then true;
705 case _ guard isIntegerOrSubTypeInteger(t) then true;
706 case _ guard isBooleanOrSubTypeBoolean(t) then true;
707 else false;
708 end match;
709 end isIntegerOrRealOrBooleanOrSubTypeOfEither;
710
711 public function isClock
712 input DAE.Type tp;
713 output Boolean res;
714 algorithm
715 172184 res := isScalarClock(arrayElementType(tp));
716 end isClock;
717
718 public function isScalarClock
719 input DAE.Type inType;
720 output Boolean res;
721 algorithm
722 res := match inType
723 local
724 Type ty;
725 case DAE.T_CLOCK() then true;
726 ✗ case DAE.T_SUBTYPE_BASIC(complexType = ty) then isScalarClock(ty);
727 else false;
728 end match;
729 end isScalarClock;
730
731 public function isInteger "Returns true if type is Integer"
732 input DAE.Type tp;
733 output Boolean res;
734 algorithm
735 231941 res := isScalarInteger(arrayElementType(tp));
736 end isInteger;
737
738 public function isScalarInteger
739 input DAE.Type inType;
740 output Boolean outIsScalarInteger;
741 algorithm
742 outIsScalarInteger := match inType
743 local
744 Type ty;
745
746 case DAE.T_INTEGER() then true;
747 2 case DAE.T_SUBTYPE_BASIC(complexType = ty) then isScalarInteger(ty);
748 else false;
749 end match;
750 end isScalarInteger;
751
752 public function isBoolean "Returns true if type is Boolean"
753 input DAE.Type tp;
754 output Boolean res;
755 algorithm
756 27374 res := isScalarBoolean(arrayElementType(tp));
757 end isBoolean;
758
759 public function isScalarBoolean
760 input DAE.Type inType;
761 output Boolean outIsScalarBoolean;
762 algorithm
763 outIsScalarBoolean := match inType
764 local
765 Type ty;
766
767 case DAE.T_BOOL() then true;
768 ✗ case DAE.T_SUBTYPE_BASIC(complexType = ty) then isScalarBoolean(ty);
769 else false;
770 end match;
771 end isScalarBoolean;
772
773 public function integerOrReal "author: PA
774 Succeeds for the builtin types Integer and Real
775 (including classes extending the basetype Integer or Real)."
776 input DAE.Type inType;
777 algorithm
778 () := match inType
779 local Type tp;
780 case DAE.T_REAL() then ();
781 case DAE.T_INTEGER() then ();
782 case DAE.T_SUBTYPE_BASIC(complexType = tp)
783 algorithm
784 ✗ integerOrReal(tp);
785 then ();
786 end match;
787 end integerOrReal;
788
789 public function isNonscalarArray
790 "Returns true if Type is an nonscalar array (array of arrays)."
791 input DAE.Type inType;
792 input DAE.Dimensions inDims;
793 output Boolean outBoolean;
794 algorithm
795 outBoolean := matchcontinue (inType,inDims)
796 local
797 Type t;
798 list<Type> tys;
799 Boolean b;
800 // several (at least 2) dimensions means array!
801 case (_, _::_::_) then true;
802 // if the type is an array, then is an array
803 case (DAE.T_ARRAY(),_) then true;
804 // if is a type extending basic type
805 ✗ case (DAE.T_SUBTYPE_BASIC(complexType = t),_) then isNonscalarArray(t, {});
806 case (DAE.T_TUPLE(types = tys), _)
807 algorithm
808 ✗ b := List.applyAndFold1(tys, boolOr, isNonscalarArray, {}, false);
809 then
810 b;
811 else false;
812 end matchcontinue;
813 end isNonscalarArray;
814
815 public function isArray
816 "Returns true if the given type is an array type."
817 input DAE.Type inType;
818 output Boolean outIsArray;
819 algorithm
820 outIsArray := match inType
821 case DAE.T_ARRAY() then true;
822 196 case DAE.T_SUBTYPE_BASIC() then isArray(inType.complexType);
823 5 case DAE.T_FUNCTION() then isArray(inType.funcResultType);
824 else false;
825 end match;
826 end isArray;
827
828 public function isEmptyArray
829 input DAE.Type inType;
830 output Boolean outBoolean;
831 algorithm
832 outBoolean := match inType
833 case DAE.T_ARRAY(dims = {DAE.DIM_INTEGER(0)}) then true;
834 else false;
835 end match;
836 end isEmptyArray;
837
838 public function isString "Return true if Type is the builtin String type."
839 input DAE.Type inType;
840 output Boolean outBoolean;
841 algorithm
842 outBoolean := match inType
843 case DAE.T_STRING() then true;
844 else false;
845 end match;
846 end isString;
847
848 public function isEnumeration "Return true if Type is the enumeration type."
849 input DAE.Type inType;
850 output Boolean outBoolean;
851 algorithm
852 outBoolean := match arrayElementType(inType)
853 case DAE.T_ENUMERATION() then true;
854 else false;
855 end match;
856 end isEnumeration;
857
858 public function isArrayOrString "Return true if Type is array or the builtin String type."
859 input DAE.Type inType;
860 output Boolean outBoolean;
861 algorithm
862 outBoolean := match inType
863 local Type ty;
864 case ty guard isArray(ty) then true;
865 case ty guard isString(ty) then true;
866 else false;
867 end match;
868 end isArrayOrString;
869
870 public function numberOfDimensions "Return the number of dimensions of a Type."
871 input DAE.Type inType;
872 output Integer outInteger;
873 algorithm
874 outInteger := match inType
875 local
876 Integer n;
877 Type t;
878 DAE.Dimensions dims;
879
880 case DAE.T_ARRAY(ty = t, dims = dims)
881 algorithm
882 4075882 n := numberOfDimensions(t);
883 4075882 n := n + listLength(dims);
884 then
885 n;
886 case DAE.T_SUBTYPE_BASIC(complexType = t)
887 algorithm
888 32 n := numberOfDimensions(t);
889 then n;
890 else 0;
891 end match;
892 end numberOfDimensions;
893
894 public function dimensionsKnown
895 "Returns true if the dimensions of the type is known."
896 input DAE.Type inType;
897 output Boolean outRes;
898 algorithm
899 outRes := match inType
900 local
901 DAE.Dimension d;
902 DAE.Dimensions dims;
903 Type tp;
904
905 case DAE.T_ARRAY(dims = d::dims, ty = tp) guard Expression.dimensionKnown(d) and dimensionsKnown(DAE.T_ARRAY(tp, dims))
906 then
907 true;
908
909 case DAE.T_ARRAY(dims = {}, ty = tp) guard dimensionsKnown(tp)
910 then
911 true;
912
913 case DAE.T_ARRAY()
914 then false;
915
916 case DAE.T_SUBTYPE_BASIC(complexType = tp)
917 ✗ then dimensionsKnown(tp);
918
919 else true;
920 end match;
921 end dimensionsKnown;
922
923 public function getDimensionSizes "Return the dimension sizes of a Type."
924 input DAE.Type inType;
925 output list<Integer> outIntegerLst;
926 algorithm
927 outIntegerLst := matchcontinue inType
928 local
929 list<Integer> res;
930 DAE.Dimension d;
931 DAE.Dimensions dims;
932 Integer i;
933 Type tp;
934
935 case DAE.T_ARRAY(dims = d::dims,ty = tp)
936 algorithm
937 15151 i := Expression.dimensionSize(d);
938 14966 res := getDimensionSizes(DAE.T_ARRAY(tp, dims));
939 then
940 (i :: res);
941
942 case DAE.T_ARRAY(dims = _::dims, ty = tp)
943 algorithm
944 185 res := getDimensionSizes(DAE.T_ARRAY(tp, dims));
945 then
946 (0 :: res);
947
948 case DAE.T_ARRAY(dims = {},ty = tp)
949 algorithm
950 14913 res := getDimensionSizes(tp);
951 then
952 res;
953
954 case DAE.T_SUBTYPE_BASIC(complexType=tp)
955 56 then getDimensionSizes(tp);
956
957 else
958 algorithm
959
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 380501 times.
380501 false := arrayType(inType);
960 then
961 {};
962 end matchcontinue;
963 end getDimensionSizes;
964
965 public function getDimensionProduct "Return the dimension sizes of a Type."
966 input DAE.Type inType;
967 output Integer sz;
968 algorithm
969 sz := match inType
970 local
971 DAE.Dimensions dims;
972 Type tp;
973
974 case DAE.T_ARRAY(dims = dims,ty = tp)
975
4/4
✓ Branch 0 taken 82107 times.
✓ Branch 1 taken 75776 times.
✓ Branch 2 taken 82107 times.
✓ Branch 3 taken 75776 times.
157883 then product(Expression.dimensionSize(d) for d in dims) * getDimensionProduct(tp);
976
977 case DAE.T_SUBTYPE_BASIC(complexType=tp)
978 ✗ then getDimensionProduct(tp);
979
980 else
981 algorithm
982
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1432965 times.
1432965 false := arrayType(inType);
983 then 1;
984 end match;
985 end getDimensionProduct;
986
987 public function getDimensionNth
988 input DAE.Type inType;
989 input Integer inDim;
990 output DAE.Dimension outDimension;
991 algorithm
992 outDimension := matchcontinue(inType, inDim)
993 local
994 DAE.Dimension dim;
995 DAE.Type t;
996 Integer d, dc;
997 DAE.Dimensions dims;
998
999 case (DAE.T_ARRAY(dims = dims), d)
1000 algorithm
1001 7267 dim := listGet(dims, d);
1002 then
1003 dim;
1004
1005 case (DAE.T_ARRAY(ty = t, dims = dims), d)
1006 algorithm
1007 762 dc := listLength(dims);
1008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 762 times.
762 true := (d > dc);
1009 762 then
1010 getDimensionNth(t, d - dc);
1011
1012 case (DAE.T_SUBTYPE_BASIC(complexType = t), d)
1013 4 then getDimensionNth(t, d);
1014
1015 end matchcontinue;
1016 end getDimensionNth;
1017
1018 public function setDimensionNth
1019 "Sets the nth dimension of an array type to the given dimension."
1020 input DAE.Type inType;
1021 input DAE.Dimension inDim;
1022 input Integer inDimNth;
1023 output DAE.Type outType;
1024 algorithm
1025 outType := match(inType, inDimNth)
1026 local
1027 DAE.Dimension dim;
1028 DAE.Type ty;
1029
1030 case (DAE.T_ARRAY(dims = {_}, ty = ty), 1)
1031 69 then DAE.T_ARRAY(ty, {inDim});
1032
1033 case (DAE.T_ARRAY(dims = {dim}, ty = ty), _)
1034 algorithm
1035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 true := inDimNth > 1;
1036 2 ty := setDimensionNth(ty, inDim, inDimNth - 1);
1037 2 then
1038 DAE.T_ARRAY(ty, {dim});
1039
1040 end match;
1041 end setDimensionNth;
1042
1043 public function valuesToVars "Translates a list of Values.Value to a Var list, using a list
1044 of identifiers as component names.
1045 Used e.g. when retrieving the type of a record value."
1046 input list<Values.Value> inValuesValueLst;
1047 input list<DAE.Ident> inExpIdentLst;
1048 output list<DAE.Var> outVarLst;
1049 algorithm
1050 outVarLst := matchcontinue (inValuesValueLst,inExpIdentLst)
1051 local
1052 Type tp;
1053 list<DAE.Var> rest;
1054 Values.Value v;
1055 list<Values.Value> vs;
1056 String id;
1057 list<String> ids;
1058
1059 case ({},{}) then {};
1060 case ((v :: vs),(id :: ids))
1061 algorithm
1062 113659 tp := typeOfValue(v);
1063 113659 rest := valuesToVars(vs, ids);
1064 113659 then
1065 (DAE.TYPES_VAR(id, DAE.dummyAttrVar, tp, DAE.UNBOUND(), false, NONE()) :: rest);
1066
1067 else
1068 algorithm
1069 ✗ true := Flags.isSet(Flags.FAILTRACE);
1070 ✗ Debug.trace("-values_to_vars failed\n");
1071 ✗ then
1072 fail();
1073 end matchcontinue;
1074 end valuesToVars;
1075
1076 public function typeOfValue "author: PA
1077 Returns the type of a Values.Value.
1078 Some information is lost in the translation, like attributes
1079 of the builtin type."
1080 input Values.Value inValue;
1081 output DAE.Type outType;
1082 algorithm
1083 outType := matchcontinue inValue
1084 local
1085 Type tp;
1086 Integer dim1,index;
1087 Values.Value v;
1088 list<Values.Value> vs,vl;
1089 list<DAE.Type> ts;
1090 list<DAE.Var> vars;
1091 String str;
1092 Absyn.Path cname,path,utPath;
1093 list<String> ids;
1094 list<DAE.Exp> explist;
1095 Values.Value valType;
1096
1097
1098 ✗ case Values.EMPTY(ty = valType) then typeOfValue(valType);
1099
1100 case Values.INTEGER() then (DAE.T_INTEGER_DEFAULT);
1101 case Values.REAL() then (DAE.T_REAL_DEFAULT);
1102 case Values.STRING() then (DAE.T_STRING_DEFAULT);
1103 case Values.BOOL() then (DAE.T_BOOL_DEFAULT);
1104 case Values.ENUM_LITERAL(name = path, index = index)
1105 algorithm
1106 1996 path := AbsynUtil.pathPrefix(path);
1107 1996 then DAE.T_ENUMERATION(SOME(index), path, {}, {}, {});
1108
1109 case Values.ARRAY(valueLst = (v :: vs))
1110 algorithm
1111 1746 tp := typeOfValue(v);
1112 1746 dim1 := listLength((v :: vs));
1113 3492 then
1114 DAE.T_ARRAY(tp, {DAE.DIM_INTEGER(dim1)});
1115
1116 case Values.ARRAY(valueLst = ({}))
1117 algorithm
1118 then
1119 DAE.T_ARRAY(DAE.T_UNKNOWN_DEFAULT, {DAE.DIM_INTEGER(0)});
1120
1121 case Values.TUPLE(valueLst = vs)
1122 algorithm
1123 ✗ ts := List.map(vs, typeOfValue);
1124 ✗ then DAE.T_TUPLE(ts,NONE());
1125
1126 case Values.RECORD(record_ = cname,orderd = vl,comp = ids, index = -1)
1127 algorithm
1128 1899 vars := valuesToVars(vl, ids);
1129 1899 then DAE.T_COMPLEX(ClassInf.RECORD(cname),vars,NONE(), false);
1130
1131 // MetaModelica Uniontype
1132 case Values.RECORD(record_ = cname,orderd = vl,comp = ids, index = index)
1133 algorithm
1134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92283 times.
92283 true := index >= 0;
1135 92283 vars := valuesToVars(vl, ids);
1136 92283 utPath := AbsynUtil.stripLast(cname);
1137 92283 then DAE.T_METARECORD(cname, utPath, {} /* typeVar? */, index, vars, false /*We simply do not know...*/);
1138
1139 // MetaModelica list type
1140 case Values.LIST(vl)
1141 algorithm
1142 22203 explist := List.map(vl, function ValuesUtil.valueExp(originalExp=NONE()));
1143 22203 ts := List.map(vl, typeOfValue);
1144 22203 (_,tp) := listMatchSuperType(explist, ts, true);
1145 22203 tp := boxIfUnboxedType(tp);
1146 22203 then DAE.T_METALIST(tp);
1147
1148 case Values.OPTION(NONE())
1149 algorithm
1150 tp := DAE.T_METAOPTION(DAE.T_UNKNOWN_DEFAULT);
1151 then tp;
1152
1153 case Values.OPTION(SOME(v))
1154 algorithm
1155 1303 tp := boxIfUnboxedType(typeOfValue(v));
1156 1303 tp := DAE.T_METAOPTION(tp);
1157 then tp;
1158
1159 case Values.META_TUPLE(valueLst = vs)
1160 algorithm
1161 19278 ts := List.mapMap(vs, typeOfValue, boxIfUnboxedType);
1162 19278 then DAE.T_METATUPLE(ts);
1163
1164 case Values.META_ARRAY(valueLst = (v :: _))
1165 algorithm
1166 ✗ tp := boxIfUnboxedType(typeOfValue(v));
1167 ✗ tp := DAE.T_METAARRAY(tp);
1168 then tp;
1169
1170 case Values.META_ARRAY(valueLst = {})
1171 algorithm
1172 tp := DAE.T_METAARRAY(DAE.T_UNKNOWN_DEFAULT);
1173 then tp;
1174
1175 case Values.META_BOX(v)
1176 algorithm
1177 ✗ tp := typeOfValue(v);
1178 ✗ then boxIfUnboxedType(tp);
1179
1180 case Values.NORETCALL() then DAE.T_NORETCALL_DEFAULT;
1181
1182 case Values.CODE(A=Absyn.C_TYPENAME())
1183 then DAE.T_CODE(DAE.C_TYPENAME());
1184
1185 case Values.CODE(A=Absyn.C_VARIABLENAME())
1186 then DAE.T_CODE(DAE.C_VARIABLENAME());
1187
1188 case Values.CODE(A=Absyn.C_EXPRESSION())
1189 then DAE.T_CODE(DAE.C_EXPRESSION());
1190
1191 case Values.CODE(A=Absyn.C_MODIFICATION())
1192 then DAE.T_CODE(DAE.C_MODIFICATION());
1193
1194 case v
1195 algorithm
1196 ✗ str := "- Types.typeOfValue failed: " + ValuesDump.valString(v);
1197 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
1198 ✗ then
1199 fail();
1200 end matchcontinue;
1201 end typeOfValue;
1202
1203 public function basicType "Test whether a type is one of the builtin types."
1204 input DAE.Type inType;
1205 output Boolean outBoolean;
1206 algorithm
1207 outBoolean := match inType
1208 case DAE.T_INTEGER() then true;
1209 case DAE.T_REAL() then true;
1210 case DAE.T_STRING() then true;
1211 case DAE.T_BOOL() then true;
1212 // BTH
1213 case DAE.T_CLOCK() then true;
1214 case DAE.T_ENUMERATION() then true;
1215 else false;
1216 end match;
1217 end basicType;
1218
1219 public function extendsBasicType "Test whether a type extends one of the builtin types."
1220 input DAE.Type inType;
1221 output Boolean outBoolean;
1222 algorithm
1223 outBoolean := match inType
1224 case DAE.T_SUBTYPE_BASIC() then true;
1225 else false;
1226 end match;
1227 end extendsBasicType;
1228
1229 public function derivedBasicType
1230 "Returns the actual type of a type extending one of the builtin types."
1231 input DAE.Type inType;
1232 output DAE.Type outType;
1233 algorithm
1234 outType := match inType
1235 1 case DAE.T_SUBTYPE_BASIC() then derivedBasicType(inType.complexType);
1236 else inType;
1237 end match;
1238 end derivedBasicType;
1239
1240 public function arrayType "Test whether a type is an array type."
1241 input DAE.Type inType;
1242 output Boolean outBoolean;
1243 algorithm
1244 outBoolean := match inType
1245 case DAE.T_ARRAY() then true;
1246 else false;
1247 end match;
1248 end arrayType;
1249
1250 public function setVarInput "Sets a DAE.Var to input"
1251 input DAE.Var var;
1252 output DAE.Var outV;
1253 protected
1254 DAE.Attributes attrs;
1255 algorithm
1256 outV := var;
1257 ✗ attrs := outV.attributes;
1258 ✗ attrs.direction := Absyn.INPUT();
1259 ✗ outV.attributes := attrs;
1260
1261 // outV.attributes.direction := Absyn.INPUT();
1262 end setVarInput;
1263
1264 public function setVarDefaultInput "Sets a DAE.Var to input"
1265 input DAE.Var var;
1266 output DAE.Var outV;
1267 protected
1268 DAE.Attributes attrs;
1269 algorithm
1270 outV := var;
1271
1272 32334 attrs := outV.attributes;
1273 32334 attrs.connectorType := DAE.NON_CONNECTOR();
1274 attrs.variability := SCode.VAR();
1275 attrs.direction := Absyn.INPUT();
1276 attrs.innerOuter := Absyn.NOT_INNER_OUTER();
1277 attrs.visibility := SCode.PUBLIC();
1278 32334 outV.attributes := attrs;
1279
1280 /*
1281 outV.attributes.connectorType := DAE.NON_CONNECTOR();
1282 outV.attributes.variability := SCode.VAR();
1283 outV.attributes.direction := Absyn.INPUT();
1284 outV.attributes.innerOuter := Absyn.NOT_INNER_OUTER();
1285 outV.attributes.visibility := SCode.PUBLIC();
1286 */
1287 end setVarDefaultInput;
1288
1289 public function setVarProtected "Sets a DAE.Var to input"
1290 input DAE.Var var;
1291 output DAE.Var outV;
1292 protected
1293 DAE.Attributes attrs;
1294 algorithm
1295 outV := var;
1296 1324 attrs := outV.attributes;
1297 1324 attrs.visibility := SCode.PROTECTED();
1298 1324 outV.attributes := attrs;
1299 // outV.attributes.visibility := SCode.PROTECTED();
1300 end setVarProtected;
1301
1302 protected function setVarType "Sets a DAE.Var's type"
1303 input DAE.Var var;
1304 input DAE.Type ty;
1305 output DAE.Var outV = var;
1306 algorithm
1307 668441 outV.ty := ty;
1308 end setVarType;
1309
1310 public function semiEquivTypes
1311 "This function checks whether two types are semi-equal...
1312 With 'semi' we mean that they have the same base type, and if both are arrays
1313 the numbers of dimensions are equal, not necessarily equal dimension-sizes."
1314 input DAE.Type inType1;
1315 input DAE.Type inType2;
1316 output Boolean outEquiv;
1317 protected
1318 DAE.Type ty1, ty2;
1319 list<DAE.Dimension> dims1, dims2;
1320 algorithm
1321 ✗ if arrayType(inType1) and arrayType(inType2) then
1322 ✗ (ty1, dims1) := TypesDump.flattenArrayType(inType1);
1323 ✗ (ty2, dims2) := TypesDump.flattenArrayType(inType2);
1324 ✗ outEquiv := equivtypes(inType1, inType2) and listLength(dims1) == listLength(dims2);
1325 elseif not arrayType(inType1) and not arrayType(inType2) then
1326 ✗ outEquiv := equivtypes(inType1, inType2);
1327 else
1328 outEquiv := false;
1329 end if;
1330 end semiEquivTypes;
1331
1332 public function equivtypes "This is the type equivalence function. It is defined in terms of
1333 the subtype function. Two types are considered equivalent if they
1334 are subtypes of each other."
1335 input DAE.Type t1;
1336 input DAE.Type t2;
1337 output Boolean outBoolean;
1338 algorithm
1339
3/4
✓ Branch 1 taken 29736617 times.
✓ Branch 2 taken 651886 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 29736617 times.
30388503 outBoolean := subtype(t1, t2) and subtype(t2, t1);
1340 end equivtypes;
1341
1342 public function equivtypesOrRecordSubtypeOf
1343 "Like equivtypes but accepts non-typeconverted records as well (for connections)."
1344 input DAE.Type t1;
1345 input DAE.Type t2;
1346 output Boolean outBoolean;
1347 algorithm
1348
3/4
✓ Branch 1 taken 80419 times.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 80419 times.
80421 outBoolean := subtype(t1, t2, false /* Allow record names to differ */) and subtype(t2, t1, false);
1349 end equivtypesOrRecordSubtypeOf;
1350
1351 public function subtype "Is the first type a subtype of the second type?
1352 This function specifies the rules for subtyping in Modelica."
1353 input DAE.Type inType1;
1354 input DAE.Type inType2;
1355 input Boolean requireRecordNamesEqual = true;
1356 output Boolean outBoolean;
1357 algorithm
1358 outBoolean := matchcontinue (inType1, inType2)
1359 local
1360 Boolean res, b1, b2;
1361 String l1,l2;
1362 list<DAE.Var> els1,els2;
1363 Absyn.Path p1,p2;
1364 DAE.Type t1,t2,tp2,tp1;
1365 ClassInf.State st1,st2;
1366 list<DAE.Type> type_list1,type_list2,tList1,tList2;
1367 list<String> names1, names2;
1368 DAE.Dimension dim1,dim2;
1369 DAE.Dimensions dlst1, dlst2;
1370 list<DAE.FuncArg> farg1,farg2;
1371 DAE.CodeType c1,c2;
1372
1373 case (DAE.T_ANYTYPE(), _) then true;
1374 case (_, DAE.T_ANYTYPE()) then true;
1375 case (DAE.T_INTEGER(), DAE.T_INTEGER()) then true;
1376 case (DAE.T_REAL(), DAE.T_REAL()) then true;
1377 case (DAE.T_STRING(), DAE.T_STRING()) then true;
1378 case (DAE.T_BOOL(), DAE.T_BOOL()) then true;
1379 // BTH
1380 case (DAE.T_CLOCK(), DAE.T_CLOCK()) then true;
1381
1382 case (DAE.T_ENUMERATION(names = {}), DAE.T_ENUMERATION()) then true;
1383 case (DAE.T_ENUMERATION(), DAE.T_ENUMERATION(names = {})) then true;
1384
1385 case (DAE.T_ENUMERATION(names = names1),
1386 DAE.T_ENUMERATION(names = names2))
1387 algorithm
1388 39216 res := List.isEqualOnTrue(names1, names2, stringEq);
1389 then
1390 res;
1391
1392 case (DAE.T_ARRAY(dims = dlst1 as _::_::_, ty = t1),
1393 DAE.T_ARRAY(dims = dlst2 as _::_::_, ty = t2))
1394 algorithm
1395
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6120 times.
6120 true := Expression.dimsEqual(dlst1, dlst2);
1396
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6120 times.
6120 true := subtype(t1, t2, requireRecordNamesEqual);
1397 then
1398 true;
1399
1400 // try dims as list vs. dims as tree
1401 // T_ARRAY(a::b::c) vs. T_ARRAY(a, T_ARRAY(b, T_ARRAY(c)))
1402 case (DAE.T_ARRAY(dims = {dim1}, ty = t1),
1403 DAE.T_ARRAY(dims = dim2::(dlst2 as _::_), ty = t2))
1404 algorithm
1405
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 292 times.
292 true := Expression.dimensionsEqual(dim1, dim2);
1406
2/2
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 248 times.
292 true := subtype(t1, DAE.T_ARRAY(t2, dlst2), requireRecordNamesEqual);
1407 then
1408 true;
1409
1410 // try subtype of dimension list vs. dimension tree
1411 case (DAE.T_ARRAY(dims = dim1::(dlst1 as _::_), ty = t1),
1412 DAE.T_ARRAY(dims = {dim2}, ty = t2))
1413 algorithm
1414
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 504 times.
504 true := Expression.dimensionsEqual(dim1, dim2);
1415
2/2
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 482 times.
504 true := subtype(DAE.T_ARRAY(t1, dlst1), t2, requireRecordNamesEqual);
1416 then
1417 true;
1418
1419 case (DAE.T_ARRAY(ty = t1),DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()}, ty = t2))
1420 algorithm
1421
2/2
✓ Branch 1 taken 229733 times.
✓ Branch 2 taken 8777 times.
238510 true := subtype(t1, t2, requireRecordNamesEqual);
1422 then
1423 true;
1424
1425 case (DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()}, ty = t1),DAE.T_ARRAY(ty = t2))
1426 algorithm
1427
2/2
✓ Branch 1 taken 107783 times.
✓ Branch 2 taken 27911 times.
135694 true := subtype(t1, t2, requireRecordNamesEqual);
1428 then
1429 true;
1430
1431 case (DAE.T_ARRAY(dims = {DAE.DIM_EXP()}, ty = t1),
1432 DAE.T_ARRAY(dims = {DAE.DIM_EXP()}, ty = t2))
1433 algorithm
1434 /* HUGE TODO: FIXME: After MSL is updated? */
1435 // true = ExpressionBasics.expEqual(e1,e2);
1436
2/2
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 116 times.
159 true := subtype(t1, t2, requireRecordNamesEqual);
1437 then
1438 true;
1439
1440 case (DAE.T_ARRAY(ty = t1),
1441 DAE.T_ARRAY(dims = {DAE.DIM_EXP()}, ty = t2))
1442 algorithm
1443
2/2
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 3 times.
191 true := subtype(t1, t2, requireRecordNamesEqual);
1444 then
1445 true;
1446
1447 case (DAE.T_ARRAY(dims = {DAE.DIM_EXP()}, ty = t1),
1448 DAE.T_ARRAY(ty = t2))
1449 algorithm
1450
2/2
✓ Branch 1 taken 279 times.
✓ Branch 2 taken 5 times.
284 true := subtype(t1, t2, requireRecordNamesEqual);
1451 then
1452 true;
1453
1454 // Array
1455 case (DAE.T_ARRAY(dims = {dim1}, ty = t1),DAE.T_ARRAY(dims = {dim2}, ty = t2))
1456 algorithm
1457 /*
1458 true = boolOr(Expression.dimensionsKnownAndEqual(dim1, dim2),
1459 Expression.dimensionsEqualAllowZero(dim1, dim2));
1460 */
1461
2/2
✓ Branch 1 taken 335212 times.
✓ Branch 2 taken 389657 times.
724869 true := Expression.dimensionsKnownAndEqual(dim1, dim2);
1462
2/2
✓ Branch 1 taken 59787 times.
✓ Branch 2 taken 329870 times.
389657 true := subtype(t1, t2, requireRecordNamesEqual);
1463 then
1464 true;
1465
1466 // External objects use a nominal type system
1467 case (DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(p1)),
1468 DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(p2)))
1469 644 then
1470 AbsynUtil.pathEqual(p1,p2);
1471
1472 // Complex type
1473 case (DAE.T_COMPLEX(complexClassType = st1,varLst = els1),
1474 DAE.T_COMPLEX(complexClassType = st2,varLst = els2))
1475 algorithm
1476
3/4
✓ Branch 1 taken 14260 times.
✓ Branch 2 taken 44190 times.
✓ Branch 3 taken 14260 times.
✗ Branch 4 not taken.
58450 true := classTypeEqualIfRecord(st1, st2) or not requireRecordNamesEqual "We need to add a cast from one record to another";
1477
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 44190 times.
44190 true := listLength(els1) == listLength(els2);
1478
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 44190 times.
44190 true := subtypeVarlist(els1, els2);
1479 then
1480 true;
1481
1482 // A complex type that extends a basic type is checked against the baseclass basic type
1483 case (DAE.T_SUBTYPE_BASIC(complexType = tp1),tp2)
1484 algorithm
1485 16336 res := subtype(tp1, tp2, requireRecordNamesEqual);
1486 then
1487 res;
1488
1489 // A complex type that extends a basic type is checked against the baseclass basic type
1490 case (tp1,DAE.T_SUBTYPE_BASIC(complexType = tp2))
1491 algorithm
1492 14237 res := subtype(tp1, tp2, requireRecordNamesEqual);
1493 then
1494 res;
1495
1496 // Check of tuples, similar to complex. Just that identifier name do not have to be checked. Only types are checked.
1497 case (DAE.T_TUPLE(types = type_list1),
1498 DAE.T_TUPLE(types = type_list2))
1499 algorithm
1500
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 804 times.
804 true := subtypeTypelist(type_list1, type_list2, requireRecordNamesEqual);
1501 then
1502 true;
1503
1504 // Part of MetaModelica extension. KS
1505 24553 case (DAE.T_METALIST(ty = t1),DAE.T_METALIST(ty = t2)) then subtype(t1,t2);
1506 199 case (DAE.T_METAARRAY(ty = t1),DAE.T_METAARRAY(ty = t2)) then subtype(t1,t2);
1507 case (DAE.T_METATUPLE(types = tList1),DAE.T_METATUPLE(types = tList2))
1508 algorithm
1509 24102 res := subtypeTypelist(tList1,tList2,requireRecordNamesEqual);
1510 then res;
1511 case (DAE.T_METAOPTION(ty = t1),DAE.T_METAOPTION(ty = t2))
1512 15873 then subtype(t1,t2,requireRecordNamesEqual);
1513
1514 case (DAE.T_METABOXED(ty = t1),DAE.T_METABOXED(ty = t2))
1515 9029 then subtype(t1,t2,requireRecordNamesEqual);
1516
2/2
✓ Branch 1 taken 38086 times.
✓ Branch 2 taken 6591 times.
44677 case (DAE.T_METABOXED(ty = t1),t2) algorithm true := isBoxedType(t2); then subtype(t1,t2,requireRecordNamesEqual);
1517
2/2
✓ Branch 1 taken 73654 times.
✓ Branch 2 taken 15 times.
73669 case (t1,DAE.T_METABOXED(ty = t2)) algorithm true := isBoxedType(t1); then subtype(t1,t2,requireRecordNamesEqual);
1518
1519
4/4
✓ Branch 0 taken 3305 times.
✓ Branch 1 taken 64 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3301 times.
3369 case (DAE.T_METAPOLYMORPHIC(name = l1),DAE.T_METAPOLYMORPHIC(name = l2)) then l1 == l2;
1520 case (DAE.T_UNKNOWN(),_) then true;
1521 case (_,DAE.T_UNKNOWN()) then true;
1522 case (DAE.T_NORETCALL(),DAE.T_NORETCALL()) then true;
1523
1524 // MM Function Reference
1525 case (DAE.T_FUNCTION(funcArg = farg1,funcResultType = t1),DAE.T_FUNCTION(funcArg = farg2,funcResultType = t2))
1526 algorithm
1527
4/4
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 186 times.
✓ Branch 2 taken 238 times.
✓ Branch 3 taken 186 times.
424 tList1 := list(traverseType(funcArgType(t), 1, unboxedTypeTraverseHelper) for t in farg1);
1528
4/4
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 186 times.
✓ Branch 2 taken 238 times.
✓ Branch 3 taken 186 times.
424 tList2 := list(traverseType(funcArgType(t), 1, unboxedTypeTraverseHelper) for t in farg2);
1529 186 t1 := traverseType(t1, 1, unboxedTypeTraverseHelper);
1530 186 t2 := traverseType(t2, 1, unboxedTypeTraverseHelper);
1531
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 184 times.
186 true := subtypeTypelist(tList1,tList2,requireRecordNamesEqual);
1532
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 184 times.
184 true := subtype(t1,t2,requireRecordNamesEqual);
1533 then true;
1534
1535 case (DAE.T_FUNCTION_REFERENCE_VAR(functionType = t1),DAE.T_FUNCTION_REFERENCE_VAR(functionType = t2))
1536 ✗ then subtype(t1,t2);
1537
1538 case (DAE.T_METARECORD(path=p1),DAE.T_METARECORD(path=p2))
1539 42953 then AbsynUtil.pathEqual(p1,p2);
1540
1541 case (DAE.T_METAUNIONTYPE(path = p1),DAE.T_METARECORD(utPath=p2))
1542
1/2
✓ Branch 1 taken 35152 times.
✗ Branch 2 not taken.
35152 then if AbsynUtil.pathEqual(p1,p2) then subtypeTypelist(inType1.typeVars,inType2.typeVars,requireRecordNamesEqual) else false;
1543
1544 // If the record is the only one in the uniontype, of course their types match
1545 case (DAE.T_METARECORD(knownSingleton=b1,utPath = p1),DAE.T_METAUNIONTYPE(knownSingleton=b2,path=p2))
1546
3/4
✓ Branch 1 taken 6556 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5284 times.
✓ Branch 4 taken 1272 times.
6556 then if AbsynUtil.pathEqual(p1,p2) and (b1 or b2) /*Values.mo loses knownSingleton information */ then subtypeTypelist(inType1.typeVars,inType2.typeVars,requireRecordNamesEqual) else false;
1547
1548 // <uniontype> = <uniontype>
1549 case (DAE.T_METAUNIONTYPE(path = p1), DAE.T_METAUNIONTYPE(path = p2))
1550
1/2
✓ Branch 1 taken 60250 times.
✗ Branch 2 not taken.
60250 then if AbsynUtil.pathEqual(p1,p2) then subtypeTypelist(inType1.typeVars,inType2.typeVars,requireRecordNamesEqual) else false;
1551 /*case (DAE.T_METAUNIONTYPE(path = p1), DAE.T_COMPLEX(complexClassType=ClassInf.META_UNIONTYPE(_), source = {p2}))
1552 then AbsynUtil.pathEqual(p1,p2); // TODO: Remove?
1553 case(DAE.T_COMPLEX(complexClassType=ClassInf.META_UNIONTYPE(_), source = {p2}), DAE.T_METAUNIONTYPE(path = p1))
1554 then AbsynUtil.pathEqual(p1,p2); // TODO: Remove?*/
1555
1556 2488 case (DAE.T_CODE(ty = c1),DAE.T_CODE(ty = c2)) then valueEq(c1,c2);
1557
1558 ✗ case (DAE.T_METATYPE(ty = t1),DAE.T_METATYPE(ty = t2)) then subtype(t1,t2,requireRecordNamesEqual);
1559 ✗ case (t1,DAE.T_METATYPE(ty = t2)) then subtype(t1,t2,requireRecordNamesEqual);
1560 ✗ case (DAE.T_METATYPE(ty = t1),t2) then subtype(t1,t2,requireRecordNamesEqual);
1561
1562 else
1563 algorithm
1564 /* Uncomment for debugging
1565 l1 = TypesDump.unparseType(t1);
1566 l2 = TypesDump.unparseType(t2);
1567 l1 = stringAppendList({"- Types.subtype failed:\n t1=",l1,"\n t2=",l2});
1568 print(l1);
1569 */
1570 then false;
1571 end matchcontinue;
1572 end subtype;
1573
1574 protected function subtypeTypelist "PR. function: subtypeTypelist
1575 This function checks if the both Type lists matches types, element by element."
1576 input list<DAE.Type> inTypeLst1;
1577 input list<DAE.Type> inTypeLst2;
1578 input Boolean requireRecordNamesEqual;
1579 output Boolean outBoolean;
1580 algorithm
1581 outBoolean := match (inTypeLst1, inTypeLst2)
1582 local
1583 Type t1,t2;
1584 list<DAE.Type> rest1,rest2;
1585
1586 case ({}, {}) then true;
1587 case ((t1 :: rest1), (t2 :: rest2)) guard subtype(t1, t2, requireRecordNamesEqual)
1588 50658 then subtypeTypelist(rest1, rest2, requireRecordNamesEqual);
1589 else false; /* default */
1590 end match;
1591 end subtypeTypelist;
1592
1593 protected function subtypeVarlist "This function checks if the Var list in the first list is a
1594 subset of the list in the second argument. More precisely, it
1595 checks if, for each Var in the second list there is a Var in
1596 the first list with a type that is a subtype of the Var in the
1597 second list."
1598 input list<DAE.Var> inVarLst1;
1599 input list<DAE.Var> inVarLst2;
1600 output Boolean outBoolean;
1601 algorithm
1602 outBoolean := matchcontinue (inVarLst1,inVarLst2)
1603 local
1604 DAE.Type t1,t2;
1605 list<DAE.Var> l,vs;
1606 String n;
1607
1608 case (_,{}) then true;
1609
1610 case (l,(DAE.TYPES_VAR(name = n,ty = t2) :: vs))
1611 algorithm
1612 240792 DAE.TYPES_VAR(ty = t1) := varlistLookup(l, n);
1613
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 240792 times.
240792 true := subtype(t1, t2, false);
1614 240792 then subtypeVarlist(l, vs);
1615
1616 else false; /* default */
1617 end matchcontinue;
1618 end subtypeVarlist;
1619
1620 public function varlistLookup "Given a list of Var and a name, this function finds any Var with the given name."
1621 input list<DAE.Var> inVarLst;
1622 input String inIdent;
1623 output DAE.Var outVar;
1624 protected
1625 String name;
1626 algorithm
1627
1/2
✓ Branch 0 taken 1941920 times.
✗ Branch 1 not taken.
1941920 for var in inVarLst loop
1628 1941920 DAE.TYPES_VAR(name = name) := var;
1629
1630
4/4
✓ Branch 0 taken 433321 times.
✓ Branch 1 taken 1508599 times.
✓ Branch 3 taken 240792 times.
✓ Branch 4 taken 192529 times.
1941920 if name == inIdent then
1631 outVar := var;
1632 240792 return;
1633 end if;
1634 end for;
1635
1636 ✗ fail();
1637 end varlistLookup;
1638
1639 public function lookupComponent "This function finds a subcomponent by name."
1640 input DAE.Type inType;
1641 input String inIdent;
1642 output DAE.Var outVar;
1643 algorithm
1644 outVar := matchcontinue (inType,inIdent)
1645 local
1646 DAE.Var v;
1647 DAE.Type t,ty;
1648 String n,id;
1649 list<DAE.Var> cs;
1650 DAE.Dimension dim;
1651
1652 case (t,n)
1653 algorithm
1654 ✗ true := basicType(t);
1655 ✗ v := lookupInBuiltin(t, n);
1656 then
1657 v;
1658
1659 case (DAE.T_COMPLEX(varLst = cs),id)
1660 algorithm
1661 ✗ v := lookupComponent2(cs, id);
1662 then
1663 v;
1664
1665 case (DAE.T_SUBTYPE_BASIC(varLst = cs),id)
1666 algorithm
1667 ✗ v := lookupComponent2(cs, id);
1668 then
1669 v;
1670
1671 case (DAE.T_ARRAY(dims = {dim},ty = DAE.T_COMPLEX(varLst = cs)),id)
1672 algorithm
1673 ✗ v := lookupComponent2(cs, id);
1674 ✗ v.ty := DAE.T_ARRAY(v.ty,{dim});
1675 then
1676 v;
1677
1678 case (DAE.T_ARRAY(dims = {dim},ty = DAE.T_SUBTYPE_BASIC(varLst = cs)),id)
1679 algorithm
1680 ✗ v := lookupComponent2(cs, id);
1681 ✗ v.ty := DAE.T_ARRAY(v.ty,{dim});
1682 then
1683 v;
1684
1685 else
1686 algorithm
1687 // Print.printBuf("- Looking up " + id + " in noncomplex type\n");
1688 then fail();
1689 end matchcontinue;
1690 end lookupComponent;
1691
1692 protected function lookupInBuiltin "Since builtin types are not represented as DAE.T_COMPLEX, special care
1693 is needed to be able to lookup the attributes (*start* etc) in
1694 them.
1695
1696 This is not a complete solution. The current way of mapping the
1697 both the Modelica type Real and the simple type RealType to
1698 DAE.T_REAL is a bit problematic, since it does not make a
1699 difference between Real and RealType, which makes the
1700 translator accept things like x.start.start.start."
1701 input DAE.Type inType;
1702 input String inIdent;
1703 output DAE.Var outVar;
1704 algorithm
1705 outVar := match (inType,inIdent)
1706 local
1707 DAE.Var v;
1708 list<DAE.Var> cs;
1709 String id;
1710
1711 case (DAE.T_REAL(varLst = cs),id) /* Real */
1712 algorithm
1713 ✗ v := lookupComponent2(cs, id);
1714 then
1715 v;
1716
1717 case (DAE.T_INTEGER(varLst = cs),id)
1718 algorithm
1719 ✗ v := lookupComponent2(cs, id);
1720 then
1721 v;
1722
1723 case (DAE.T_STRING(varLst = cs),id)
1724 algorithm
1725 ✗ v := lookupComponent2(cs, id);
1726 then
1727 v;
1728
1729 case (DAE.T_BOOL(varLst = cs),id)
1730 algorithm
1731 ✗ v := lookupComponent2(cs, id);
1732 then
1733 v;
1734
1735 case (DAE.T_ENUMERATION(index = SOME(_)),"quantity")
1736 then DAE.TYPES_VAR("quantity", DAE.dummyAttrParam,DAE.T_STRING_DEFAULT,DAE.VALBOUND(Values.STRING(""),DAE.BINDING_FROM_DEFAULT_VALUE()),false,NONE());
1737
1738 // Should be bound to the first element of DAE.T_ENUMERATION list higher up in the call chain
1739 case (DAE.T_ENUMERATION(index = SOME(_)),"min")
1740 then DAE.TYPES_VAR("min", DAE.dummyAttrParam,DAE.T_ENUMERATION(SOME(1),Absyn.IDENT(""),{"min,max"},{},{}),DAE.UNBOUND(),false,NONE());
1741
1742 // Should be bound to the last element of DAE.T_ENUMERATION list higher up in the call chain
1743 case (DAE.T_ENUMERATION(index = SOME(_)),"max")
1744 then DAE.TYPES_VAR("max", DAE.dummyAttrParam,DAE.T_ENUMERATION(SOME(2),Absyn.IDENT(""),{"min,max"},{},{}),DAE.UNBOUND(),false,NONE());
1745
1746 // Should be bound to the last element of DAE.T_ENUMERATION list higher up in the call chain
1747 case (DAE.T_ENUMERATION(index = SOME(_)),"start")
1748 then DAE.TYPES_VAR("start", DAE.dummyAttrParam,DAE.T_BOOL_DEFAULT,DAE.UNBOUND(),false,NONE());
1749
1750 // Needs to be set to true/false higher up the call chain depending on variability of instance
1751 case (DAE.T_ENUMERATION(index = SOME(_)),"fixed")
1752 then DAE.TYPES_VAR("fixed", DAE.dummyAttrParam,DAE.T_BOOL_DEFAULT,DAE.UNBOUND(),false,NONE());
1753 case (DAE.T_ENUMERATION(index = SOME(_)),"enable") then DAE.TYPES_VAR("enable", DAE.dummyAttrParam,DAE.T_BOOL_DEFAULT,DAE.VALBOUND(Values.BOOL(true),DAE.BINDING_FROM_DEFAULT_VALUE()),false,NONE());
1754 end match;
1755 end lookupInBuiltin;
1756
1757 protected function lookupComponent2 "This function finds a named Var in a list of Vars, comparing
1758 the name against the second argument to this function."
1759 input list<DAE.Var> inVarLst;
1760 input String inIdent;
1761 output DAE.Var outVar;
1762 algorithm
1763 outVar := match (inVarLst,inIdent)
1764 local
1765 DAE.Var v;
1766 String n,m;
1767 list<DAE.Var> vs;
1768
1769 case (((v as DAE.TYPES_VAR(name = n)) :: _),m) guard stringEq(n, m)
1770 then
1771 v;
1772
1773 case ((_ :: vs),n)
1774 algorithm
1775 ✗ v := lookupComponent2(vs, n);
1776 then
1777 v;
1778 end match;
1779 end lookupComponent2;
1780
1781 public function makeArray "This function makes an array type given a Type and an Absyn.ArrayDim"
1782 input DAE.Type inType;
1783 input Absyn.ArrayDim inArrayDim;
1784 output DAE.Type outType;
1785 algorithm
1786 outType := match (inType,inArrayDim)
1787 local
1788 Type t;
1789 Integer len;
1790 list<Absyn.Subscript> l;
1791 case (t,{}) then t;
1792 case (t,l)
1793 algorithm
1794 ✗ len := listLength(l);
1795 ✗ then
1796 DAE.T_ARRAY(t,{DAE.DIM_INTEGER(len)});
1797 end match;
1798 end makeArray;
1799
1800 public function makeArraySubscripts " This function makes an array type given a Type and a list of DAE.Subscript"
1801 input DAE.Type inType;
1802 input list<DAE.Subscript> lst;
1803 output DAE.Type outType;
1804 algorithm
1805 outType := matchcontinue (inType,lst)
1806 local
1807 Type t;
1808 Integer i;
1809 list<DAE.Subscript> rest;
1810 case (t,{}) then t;
1811 case (t,DAE.WHOLEDIM()::rest)
1812 algorithm
1813 ✗ t := makeArraySubscripts(DAE.T_ARRAY(t,{DAE.DIM_UNKNOWN()}),rest);
1814 then
1815 t;
1816 case (t,DAE.SLICE(_)::rest)
1817 algorithm
1818 ✗ t := makeArraySubscripts(DAE.T_ARRAY(t,{DAE.DIM_UNKNOWN()}),rest);
1819 then
1820 t;
1821 case (t,DAE.WHOLE_NONEXP(_)::rest)
1822 algorithm
1823 ✗ t := makeArraySubscripts(DAE.T_ARRAY(t,{DAE.DIM_UNKNOWN()}),rest);
1824 then
1825 t;
1826
1827 case (t,DAE.INDEX(DAE.ICONST(i))::rest)
1828 algorithm
1829 ✗ t := makeArraySubscripts(DAE.T_ARRAY(t,{DAE.DIM_INTEGER(i)}),rest);
1830 then
1831 t;
1832 case (t,DAE.INDEX(_)::rest)
1833 algorithm
1834 ✗ t := makeArraySubscripts(DAE.T_ARRAY(t,{DAE.DIM_UNKNOWN()}),rest);
1835 then
1836 t;
1837 end matchcontinue;
1838 end makeArraySubscripts;
1839
1840 public function liftArray "This function turns a type into an array of that type.
1841 If the type already is an array, another dimension is simply added."
1842 input DAE.Type inType;
1843 input DAE.Dimension inDimension;
1844 output DAE.Type outType;
1845 algorithm
1846 79662 outType := DAE.T_ARRAY(inType, {inDimension});
1847 end liftArray;
1848
1849 public function liftList "This function turns a type into a list of that type.
1850 If the type already is a list, another dimension is simply added."
1851 input DAE.Type inType;
1852 input DAE.Dimension inDimension;
1853 output DAE.Type outType;
1854 algorithm
1855 119 outType := DAE.T_METALIST(inType);
1856 end liftList;
1857
1858 public function liftArrayListDims "
1859 This function turns a type into an array of that type."
1860 input DAE.Type inType;
1861 input DAE.Dimensions inDimensions;
1862 output DAE.Type outType = inType;
1863 algorithm
1864
2/2
✓ Branch 2 taken 18142 times.
✓ Branch 3 taken 37393 times.
55535 for dim in listReverse(inDimensions) loop
1865 18142 outType := DAE.T_ARRAY(outType, {dim});
1866 end for;
1867 end liftArrayListDims;
1868
1869 public function liftArrayListDimsReverse
1870 "Turns a type into an array of that type, with the dimensions in the reverse order."
1871 input DAE.Type inType;
1872 input DAE.Dimensions dims;
1873 output DAE.Type ty = inType;
1874 algorithm
1875
2/2
✓ Branch 1 taken 2916 times.
✓ Branch 2 taken 6624 times.
9540 for dim in dims loop
1876 2916 ty := DAE.T_ARRAY(ty, {dim});
1877 end for;
1878 end liftArrayListDimsReverse;
1879
1880 public function liftTypeWithDims "
1881 mahge: This function turns a type into an array of that type
1882 by appening the new dimension at the end. "
1883 input DAE.Type inType;
1884 input DAE.Dimensions inDims;
1885 output DAE.Type outType;
1886 algorithm
1887
2/2
✓ Branch 0 taken 16746 times.
✓ Branch 1 taken 849 times.
17595 if listEmpty(inDims) then
1888 outType := inType;
1889 16746 return;
1890 end if;
1891
1892 outType := match inType
1893 local
1894 list<DAE.Dimension> dims;
1895 DAE.Type ty;
1896
1897 case DAE.T_ARRAY(ty=DAE.T_ARRAY())
1898 algorithm
1899 ✗ print("Can not handle this yet!!");
1900 ✗ then fail();
1901
1902 7 case DAE.T_ARRAY(ty, dims) then DAE.T_ARRAY(ty, listAppend(dims, inDims));
1903
1904 842 else DAE.T_ARRAY(inType, inDims);
1905
1906 end match;
1907 end liftTypeWithDims;
1908
1909 public function liftTypeWithDimExps "
1910 This function turns a type into an array of that type."
1911 input DAE.Type inType;
1912 input list<DAE.Exp> inDimExps;
1913 output DAE.Type outType;
1914 algorithm
1915 // outType := liftTypeWithDims(inType, list(DAE.DIM_EXP(e) for e in inDimExps));
1916
1917 outType := match (inType,inDimExps)
1918 local
1919 Type ty;
1920 DAE.Exp d;
1921 list<DAE.Exp> rest;
1922 case (ty,{}) then ty;
1923 24 case (ty,d::rest) then liftArray(liftTypeWithDimExps(ty,rest),DAE.DIM_EXP(d));
1924 end match;
1925 end liftTypeWithDimExps;
1926
1927 public function liftArrayRight "This function adds an array dimension to *the right* of the passed type."
1928 input DAE.Type inType;
1929 input DAE.Dimension inIntegerOption;
1930 output DAE.Type outType;
1931 algorithm
1932 outType := match (inType,inIntegerOption)
1933 local
1934 Type ty_1,ty;
1935 DAE.Dimension dim;
1936 DAE.Dimension d;
1937 ClassInf.State ci;
1938 list<DAE.Var> varlst;
1939 EqualityConstraint ec;
1940 Type tty;
1941
1942 case (DAE.T_ARRAY(dims = {dim},ty = ty),d)
1943 algorithm
1944 1 ty_1 := liftArrayRight(ty, d);
1945 1 then
1946 DAE.T_ARRAY(ty_1, {dim});
1947
1948 case(DAE.T_SUBTYPE_BASIC(ci,varlst,ty,ec),d) guard not listEmpty(TypesDump.getDimensions(ty))
1949 algorithm
1950 ✗ ty_1 := liftArrayRight(ty,d);
1951 ✗ then DAE.T_SUBTYPE_BASIC(ci,varlst,ty_1,ec);
1952
1953 case (tty,d)
1954 5 then
1955 DAE.T_ARRAY(tty,{d});
1956 end match;
1957 end liftArrayRight;
1958
1959 public function unliftArray "This function turns an array of a type into that type."
1960 input DAE.Type inType;
1961 output DAE.Type outType;
1962 algorithm
1963 outType := match inType
1964 local Type ty;
1965 case DAE.T_ARRAY(ty = ty) then ty;
1966 ✗ case DAE.T_SUBTYPE_BASIC(complexType = ty) then unliftArray(ty);
1967 // adrpo: handle also functions returning arrays!
1968 ✗ case DAE.T_FUNCTION(funcResultType= ty) then unliftArray(ty);
1969 end match;
1970 end unliftArray;
1971
1972 public function unliftArrayOrList
1973 input DAE.Type inType;
1974 output DAE.Type outType;
1975 output DAE.Dimension dim;
1976 algorithm
1977 (outType,dim) := match inType
1978 local
1979 Type ty;
1980 140 case DAE.T_METALIST(ty = ty) then (boxIfUnboxedType(ty),DAE.DIM_UNKNOWN());
1981 1 case DAE.T_METAARRAY(ty = ty) then (boxIfUnboxedType(ty),DAE.DIM_UNKNOWN());
1982 case DAE.T_ARRAY(dims = {dim},ty = ty) then (ty,dim);
1983 case DAE.T_SUBTYPE_BASIC(complexType = ty)
1984 algorithm
1985 ✗ (ty,dim) := unliftArrayOrList(ty);
1986 then (ty,dim);
1987 case DAE.T_FUNCTION(funcResultType = ty)
1988 ✗ then unliftArrayOrList(ty);
1989 end match;
1990 end unliftArrayOrList;
1991
1992 public function arrayElementType "This function turns an array into the element type of the array."
1993 input DAE.Type inType;
1994 output DAE.Type outType;
1995 algorithm
1996 outType := match inType
1997 3575914 case DAE.T_ARRAY() then arrayElementType(inType.ty);
1998
1999 case DAE.T_SUBTYPE_BASIC()
2000
2/2
✓ Branch 1 taken 10864 times.
✓ Branch 2 taken 172 times.
11036 then if listEmpty(TypesDump.getDimensions(inType.complexType)) then
2001 inType else arrayElementType(inType.complexType);
2002
2003 818 case DAE.T_FUNCTION() then arrayElementType(inType.funcResultType);
2004
2005 else inType;
2006 end match;
2007 end arrayElementType;
2008
2009 public function setArrayElementType
2010 input DAE.Type inType;
2011 input DAE.Type inBaseType;
2012 output DAE.Type outType;
2013 algorithm
2014 outType := match inType
2015 local
2016 DAE.Type ty;
2017 DAE.Dimensions dims;
2018
2019 case DAE.T_ARRAY(ty, dims)
2020 algorithm
2021 101 ty := setArrayElementType(ty, inBaseType);
2022 101 then
2023 DAE.T_ARRAY(ty, dims);
2024
2025 else inBaseType;
2026
2027 end match;
2028 end setArrayElementType;
2029
2030 public function makeFunctionType "author: LS
2031 Creates a function type from a function name an a list of input and
2032 output variables."
2033 input Absyn.Path p;
2034 input list<DAE.Var> vl;
2035 input DAE.FunctionAttributes functionAttributes;
2036 output DAE.Type outType;
2037 protected
2038 list<DAE.Var> invl,outvl;
2039 list<DAE.FuncArg> fargs;
2040 Type rettype;
2041 algorithm
2042 69216 invl := getInputVars(vl);
2043 69216 outvl := getOutputVars(vl);
2044 69216 fargs := makeFargsList(invl);
2045 69216 rettype := makeReturnType(outvl);
2046 69216 outType := DAE.T_FUNCTION(fargs,rettype,functionAttributes,p);
2047 end makeFunctionType;
2048
2049 public function extendsFunctionTypeArgs
2050 "function: extandFunctionType
2051 Extends function argument list adding var for element list."
2052 input DAE.Type inType;
2053 input list<DAE.Element> inElementLst;
2054 input list<DAE.Element> inOutputElementLst;
2055 input list<Boolean> inBooltLst;
2056 output DAE.Type outType;
2057 protected
2058 Absyn.Path tysrc;
2059 list<DAE.FuncArg> fargs, fargs1, newfargs;
2060 DAE.Type rettype;
2061 DAE.FunctionAttributes functionAttributes;
2062 algorithm
2063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 DAE.T_FUNCTION(fargs,rettype,functionAttributes,tysrc) := inType;
2064 77 (fargs1, _) := List.splitOnBoolList(fargs, inBooltLst);
2065 77 newfargs := List.threadMap(inElementLst, fargs1, makeElementFarg);
2066 77 newfargs := listAppend(fargs, newfargs);
2067 // The type of DAE.Element.VAR seems to be wrong,
2068 // but the original type should be also correct
2069 //rettype := makeElementReturnType(inOutputElementLst);
2070 77 outType := DAE.T_FUNCTION(newfargs,rettype,functionAttributes,tysrc);
2071 end extendsFunctionTypeArgs;
2072
2073 public function setFunctionNoReturn
2074 "Marks a function type as never returning normally, so that callers can treat
2075 calls to it as terminating."
2076 input output DAE.Type ty;
2077 algorithm
2078 ty := match ty
2079 local
2080 list<DAE.FuncArg> fargs;
2081 DAE.Type rettype;
2082 Absyn.Path p;
2083 DAE.InlineType inl;
2084 Boolean ge, fp;
2085 DAE.Purity pu;
2086 DAE.FunctionBuiltin bi;
2087 DAE.FunctionParallelism par;
2088 case DAE.T_FUNCTION(fargs, rettype, DAE.FUNCTION_ATTRIBUTES(inl,ge,pu,fp,bi,par,_), p)
2089
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
30 then DAE.T_FUNCTION(fargs, rettype, DAE.FUNCTION_ATTRIBUTES(inl,ge,pu,fp,bi,par,DAE.NoReturn.NORETURN), p);
2090 else ty;
2091 end match;
2092 end setFunctionNoReturn;
2093
2094 protected function makeElementReturnType "
2095 Create a return type from a list of Element output variables.
2096 Depending on the length of the output variable list, different
2097 kinds of return types are created."
2098 input list<DAE.Element> inElementLst;
2099 output DAE.Type outType;
2100 algorithm
2101 outType := match inElementLst
2102 local
2103 Type ty;
2104 DAE.Element element;
2105 list<DAE.Element> elements;
2106 list<Type> types;
2107 list<String> names;
2108 Option<list<String>> namesOpt;
2109
2110
2111 case {} then DAE.T_NORETCALL();
2112
2113 case {element}
2114 algorithm
2115 ✗ ty := makeElementReturnTypeSingle(element);
2116 then
2117 ty;
2118
2119 case elements
2120 algorithm
2121 types := {};
2122 names := {};
2123 ✗ for element in elements loop
2124 ✗ types := makeElementReturnTypeSingle(element)::types;
2125 ✗ names := DAEUtil.varName(element)::names;
2126 end for;
2127 ✗ if listEmpty(names) then
2128 namesOpt := NONE();
2129 else
2130 ✗ namesOpt := SOME(listReverse(names));
2131 end if;
2132 ✗ then DAE.T_TUPLE(listReverse(types), namesOpt);
2133 end match;
2134 end makeElementReturnType;
2135
2136 protected function makeElementReturnTypeSingle
2137 "Create the return type from an Element for a single return value."
2138 input DAE.Element inElement;
2139 output DAE.Type outType;
2140 algorithm
2141 outType := match inElement
2142 local
2143 Type ty;
2144
2145 case DAE.VAR(ty = ty) then ty;
2146 end match;
2147 end makeElementReturnTypeSingle;
2148
2149 public function getNthEnumLiteral
2150 "Returns the n:th literal of an enumeration type."
2151 input DAE.Type ty;
2152 input Integer n;
2153 output DAE.Exp literalExp;
2154 algorithm
2155 literalExp := match ty
2156 case DAE.T_ENUMERATION()
2157 546 then DAE.ENUM_LITERAL(AbsynUtil.joinPaths(ty.path, Absyn.IDENT(listGet(ty.names, n))), n);
2158
2159 // Not sure if this is correct, maybe it would be more correct to
2160 // use the path in the ClassInf.State inside the subtype?
2161 case DAE.T_SUBTYPE_BASIC()
2162 ✗ then getNthEnumLiteral(ty.complexType, n);
2163 end match;
2164 end getNthEnumLiteral;
2165
2166 public function makeEnumerationType
2167 "Creates an enumeration type from a name and an enumeration type containing
2168 the literal variables."
2169 input Absyn.Path inPath;
2170 input DAE.Type inType;
2171 output DAE.Type outType;
2172 algorithm
2173 outType := matchcontinue inType
2174 local
2175 Absyn.Path p;
2176 list<String> names, attr_names;
2177 list<DAE.Var> vars, attrs;
2178 Type ty;
2179
2180 case DAE.T_ENUMERATION(index = NONE(), path = p, names = names, literalVarLst = vars, attributeLst = attrs)
2181 algorithm
2182 7599 vars := makeEnumerationType1(p, vars, names, 1);
2183 7599 attr_names := List.map(vars, TypesDump.getVarName);
2184 7599 attrs := makeEnumerationType1(p, attrs, attr_names, 1);
2185 7599 then (DAE.T_ENUMERATION(NONE(), p, names, vars, attrs));
2186
2187 case DAE.T_ARRAY(ty = ty)
2188 1706 then makeEnumerationType(inPath, ty);
2189
2190 else
2191 algorithm
2192 ✗ true := Flags.isSet(Flags.FAILTRACE);
2193 ✗ Debug.traceln("- Types.makeEnumerationType failed on " + TypesDump.printTypeStr(inType));
2194 ✗ then
2195 fail();
2196 end matchcontinue;
2197 end makeEnumerationType;
2198
2199 public function makeEnumerationType1
2200 "Helper function to makeEnumerationType. Updates a list of enumeration
2201 literals with the correct index and type."
2202 input Absyn.Path inPath;
2203 input list<DAE.Var> inVarLst;
2204 input list<String> inNames;
2205 input Integer inIdx;
2206 output list<DAE.Var> outVarLst;
2207 algorithm
2208 outVarLst := match (inPath,inVarLst,inNames,inIdx)
2209 local
2210 list<String> names;
2211 Absyn.Path p;
2212 String name;
2213 list<DAE.Var> xs,vars;
2214 DAE.Type t;
2215 Integer idx;
2216 DAE.Attributes attributes;
2217 DAE.Binding binding;
2218 Boolean bsrc;
2219 DAE.Var var;
2220 Option<DAE.Const> cnstForRange;
2221
2222 case (p,DAE.TYPES_VAR(name,attributes,_,binding,bsrc,cnstForRange) :: xs,names,idx)
2223 algorithm
2224 42645 vars := makeEnumerationType1(p, xs, names, idx+1);
2225 42645 t := DAE.T_ENUMERATION(SOME(idx),p,names,{},{});
2226
1/2
✓ Branch 0 taken 42645 times.
✗ Branch 1 not taken.
85290 var := DAE.TYPES_VAR(name,attributes,t,binding,bsrc,cnstForRange);
2227 then
2228 (var :: vars);
2229 case (_,{},_,_) then {};
2230 end match;
2231 end makeEnumerationType1;
2232
2233 protected function getInputVars "author: LS
2234 Retrieve all the input variables from a list of variables."
2235 input list<DAE.Var> vl;
2236 output list<DAE.Var> vl_1;
2237 algorithm
2238 69216 vl_1 := List.select(vl, isInputVar);
2239 end getInputVars;
2240
2241 protected function getOutputVars "Retrieve all output variables from a list of variables."
2242 input list<DAE.Var> vl;
2243 output list<DAE.Var> vl_1;
2244 algorithm
2245 69216 vl_1 := List.select(vl, isOutputVar);
2246 end getOutputVars;
2247
2248 public function getFixedVarAttributeParameterOrConstant
2249 "Returns the value of the fixed attribute of a builtin type.
2250 If there is no fixed in the tyep it returns true"
2251 input DAE.Type tp;
2252 output Boolean fix;
2253 algorithm
2254 try
2255 // there is a fixed!
2256 1273 fix := getFixedVarAttribute(tp);
2257 else
2258 // there is no fixed!
2259 fix := true;
2260 end try;
2261 end getFixedVarAttributeParameterOrConstant;
2262
2263 public function getFixedVarAttribute "Returns the value of the fixed attribute of a builtin type"
2264 input DAE.Type tp;
2265 output Boolean fixed;
2266 algorithm
2267 fixed := matchcontinue tp
2268 local
2269 Type ty;
2270 Boolean result;
2271 list<DAE.Var> vars;
2272
2273 case DAE.T_REAL(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.VALBOUND(valBound = Values.BOOL(fixed)))::_) then fixed;
2274 case DAE.T_REAL(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.EQBOUND(evaluatedExp = SOME(Values.BOOL(fixed))))::_) then fixed;
2275 case DAE.T_REAL(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.EQBOUND(exp = DAE.BCONST(fixed)))::_) then fixed;
2276 case DAE.T_REAL(varLst = _::vars) algorithm
2277 575 fixed := getFixedVarAttribute(DAE.T_REAL(vars));
2278 then fixed;
2279
2280 case DAE.T_INTEGER(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.VALBOUND(valBound = Values.BOOL(fixed)))::_) then fixed;
2281 case DAE.T_INTEGER(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.EQBOUND(evaluatedExp = SOME(Values.BOOL(fixed))))::_) then fixed;
2282 case DAE.T_INTEGER(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.EQBOUND(exp = DAE.BCONST(fixed)))::_) then fixed;
2283 case DAE.T_INTEGER(varLst = _::vars) algorithm
2284 4 fixed := getFixedVarAttribute(DAE.T_INTEGER(vars));
2285 then fixed;
2286
2287 case DAE.T_BOOL(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.VALBOUND(valBound = Values.BOOL(fixed)))::_) then fixed;
2288 case DAE.T_BOOL(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.EQBOUND(evaluatedExp = SOME(Values.BOOL(fixed))))::_) then fixed;
2289 case DAE.T_BOOL(varLst = DAE.TYPES_VAR(name = "fixed",binding = DAE.EQBOUND(exp = DAE.BCONST(fixed)))::_) then fixed;
2290 case DAE.T_BOOL(varLst = _::vars) algorithm
2291 ✗ fixed := getFixedVarAttribute(DAE.T_BOOL(vars));
2292 then fixed;
2293
2294 case DAE.T_ARRAY(ty = ty)
2295 algorithm
2296 695 result := getFixedVarAttribute(ty);
2297 then
2298 result;
2299 end matchcontinue;
2300 end getFixedVarAttribute;
2301
2302 public function getConnectorVars
2303 "Returns the list of variables in a connector, or fails if the type is not a
2304 connector."
2305 input DAE.Type inType;
2306 output list<DAE.Var> outVars;
2307 algorithm
2308 outVars := match inType
2309 local list<DAE.Var> vars;
2310 case DAE.T_COMPLEX(
2311 complexClassType = ClassInf.CONNECTOR(),
2312 varLst = vars)
2313 then vars;
2314 end match;
2315 end getConnectorVars;
2316
2317 public function isInputVar
2318 "Succeds if variable is an input variable."
2319 input DAE.Var inVar;
2320 output Boolean b;
2321 algorithm
2322 b := match inVar
2323 local
2324 DAE.Attributes attr;
2325
2326 case DAE.TYPES_VAR(attributes = attr)
2327
3/4
✓ Branch 1 taken 189770 times.
✓ Branch 2 taken 121773 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 189770 times.
311543 then isInputAttr(attr) and isPublicAttr(attr);
2328 end match;
2329 end isInputVar;
2330
2331 public function isOutputVar
2332 "Succeds if variable is an output variable."
2333 input DAE.Var inVar;
2334 output Boolean b;
2335 algorithm
2336 b := match inVar
2337 local
2338 DAE.Attributes attr;
2339
2340 case DAE.TYPES_VAR(attributes = attr)
2341
3/4
✓ Branch 1 taken 135315 times.
✓ Branch 2 taken 248242 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 135315 times.
383557 then isOutputAttr(attr) and isPublicAttr(attr);
2342 end match;
2343 end isOutputVar;
2344
2345 public function isInputAttr "Returns true if the Attributes of a variable indicates
2346 that the variable is input."
2347 input DAE.Attributes inAttributes;
2348 output Boolean outBoolean;
2349 algorithm
2350 outBoolean := match inAttributes
2351 case DAE.ATTR(direction = Absyn.INPUT()) then true;
2352 else false;
2353 end match;
2354 end isInputAttr;
2355
2356 public function isOutputAttr "Returns true if the Attributes of a variable indicates
2357 that the variable is output."
2358 input DAE.Attributes inAttributes;
2359 output Boolean outBoolean;
2360 algorithm
2361 outBoolean := match inAttributes
2362 case DAE.ATTR(direction = Absyn.OUTPUT()) then true;
2363 else false;
2364 end match;
2365 end isOutputAttr;
2366
2367 public function isBidirAttr "Returns true if the Attributes of a variable indicates that the variable
2368 is bidirectional, i.e. neither input nor output."
2369 input DAE.Attributes inAttributes;
2370 output Boolean outBoolean;
2371 algorithm
2372 outBoolean := match inAttributes
2373 case DAE.ATTR(direction = Absyn.BIDIR()) then true;
2374 else false;
2375 end match;
2376 end isBidirAttr;
2377
2378 public function isPublicAttr
2379 input DAE.Attributes inAttributes;
2380 output Boolean outIsPublic;
2381 algorithm
2382 outIsPublic := match inAttributes
2383 case DAE.ATTR(visibility = SCode.PUBLIC()) then true;
2384 else false;
2385 end match;
2386 end isPublicAttr;
2387
2388 public function isConstAttr
2389 input DAE.Attributes inAttributes;
2390 output Boolean outIsPublic;
2391 algorithm
2392 outIsPublic := match inAttributes
2393 case DAE.ATTR(variability = SCode.CONST()) then true;
2394 else false;
2395 end match;
2396 end isConstAttr;
2397
2398 public function isPublicVar
2399 input DAE.Var inVar;
2400 output Boolean b;
2401 algorithm
2402 b := match inVar
2403 78995 case DAE.TYPES_VAR() then isPublicAttr(inVar.attributes);
2404 end match;
2405 end isPublicVar;
2406
2407 public function isConstVar
2408 input DAE.Var inVar;
2409 output Boolean b;
2410 algorithm
2411 b := match inVar
2412 76835 case DAE.TYPES_VAR() then isConstAttr(inVar.attributes);
2413 end match;
2414 end isConstVar;
2415
2416 // This used in creation of record constructors to decide wether a variable should be
2417 // part of the constructor signature or not. If a var is modifiable from outside then
2418 // it is part of the construvtor signature.
2419 public function isModifiableTypesVar
2420 input DAE.Var inVar;
2421 output Boolean b;
2422 algorithm
2423
2424 // protected vars are not modifiable from outside.
2425
2/2
✓ Branch 1 taken 242 times.
✓ Branch 2 taken 76835 times.
77077 if not isPublicVar(inVar) then
2426
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 242 times.
242 if isNone(getBindingExpOptional(inVar)) then
2427 // TYPES_VAR has no info. For now this suffices.
2428 ✗ Error.addSourceMessage(Error.MISSING_BINDING_PROTECTED_RECORD_VAR, {TypesDump.getVarName(inVar)}, Absyn.dummyInfo);
2429 end if;
2430
2431 b := false;
2432 242 return;
2433 end if;
2434
2435 // const vars which already have binding are not modifiable from outside.
2436
4/6
✓ Branch 1 taken 1324 times.
✓ Branch 2 taken 75511 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1324 times.
✓ Branch 8 taken 1324 times.
✗ Branch 9 not taken.
76835 if isConstVar(inVar) and isSome(getBindingExpOptional(inVar)) then
2437 b := false;
2438 1324 return;
2439 end if;
2440
2441 // otherwise modifiable
2442 b := true;
2443 end isModifiableTypesVar;
2444
2445 public function getBindingExpOptional
2446 input DAE.Var inVar;
2447 output Option<DAE.Exp> outExp;
2448 algorithm
2449 outExp := match inVar
2450 local
2451 DAE.Exp exp;
2452 case DAE.TYPES_VAR(binding=DAE.EQBOUND(exp=exp)) then SOME(exp);
2453 else NONE();
2454 end match;
2455 end getBindingExpOptional;
2456
2457 // This should be removed. It is used in cevalScript now. cevalScript should be updated
2458 // and this removed.
2459 public function getBindingExp
2460 input DAE.Var inVar;
2461 input Absyn.Path inPath;
2462 output DAE.Exp outExp;
2463 algorithm
2464 outExp := match inVar
2465 local
2466 DAE.Exp exp;
2467 String str;
2468 String name;
2469
2470 case DAE.TYPES_VAR(binding=DAE.EQBOUND(exp=exp)) then exp;
2471 case DAE.TYPES_VAR(name=name, binding=DAE.UNBOUND())
2472 algorithm
2473 ✗ str := "Record '" + AbsynUtil.pathString(inPath) + "' member '" + name + "' has no default value and is not modifiable by a constructor function.\n";
2474 ✗ Error.addCompilerWarning(str);
2475 then
2476 DAE.ICONST(0);
2477 end match;
2478 end getBindingExp;
2479
2480 public function makeFargsList
2481 "Makes a function argument list from a list of variables."
2482 input list<DAE.Var> vars;
2483 output list<DAE.FuncArg> fargs;
2484 annotation(__OpenModelica_EarlyInline=true);
2485 algorithm
2486 7028 fargs := List.map(vars,makeFarg);
2487 end makeFargsList;
2488
2489 protected function makeFarg
2490 "Makes a function argument list from a variable."
2491 input DAE.Var variable;
2492 output DAE.FuncArg farg;
2493 algorithm
2494 farg := match variable
2495 local
2496 String n;
2497 DAE.Type ty;
2498 DAE.Binding bnd;
2499 DAE.Const c;
2500 DAE.VarParallelism p;
2501 SCode.Variability var;
2502 SCode.Parallelism par;
2503 Option<DAE.Exp> oexp;
2504
2505 case DAE.TYPES_VAR(name = n,attributes = DAE.ATTR(variability = var, parallelism = par),ty = ty,binding = bnd)
2506 algorithm
2507 182956 c := variabilityToConst(var);
2508 182956 p := DAEUtil.scodePrlToDaePrl(par);
2509 182956 oexp := DAEUtil.bindingExp(bnd);
2510 182956 then DAE.FUNCARG(n,ty,c,p,oexp);
2511 end match;
2512 end makeFarg;
2513
2514 protected function makeElementFarg
2515 "Makes a function argument list from a variable."
2516 input DAE.Element inElement;
2517 input DAE.FuncArg inFarg;
2518 output DAE.FuncArg farg;
2519 algorithm
2520 farg := match inElement
2521 local
2522 String name;
2523 DAE.ComponentRef cref;
2524
2525 case DAE.VAR(componentRef=cref)
2526 algorithm
2527 168 name := ComponentReferenceBasics.crefLastIdent(cref);
2528 168 then setFuncArgName(inFarg, name);
2529 end match;
2530 end makeElementFarg;
2531
2532 protected function makeReturnType "author: LS
2533 Create a return type from a list of output variables.
2534 Depending on the length of the output variable list, different
2535 kinds of return types are created."
2536 input list<DAE.Var> inVarLst;
2537 output DAE.Type outType;
2538 algorithm
2539 outType := match inVarLst
2540 local
2541 Type ty;
2542 Var var;
2543 list<DAE.Var> vl;
2544
2545 case {} then DAE.T_NORETCALL();
2546
2547 case {var}
2548 algorithm
2549 63310 ty := makeReturnTypeSingle(var);
2550 then
2551 ty;
2552
2553 case vl
2554
8/8
✓ Branch 0 taken 4675 times.
✓ Branch 1 taken 1867 times.
✓ Branch 2 taken 4675 times.
✓ Branch 3 taken 1867 times.
✓ Branch 5 taken 4675 times.
✓ Branch 6 taken 1867 times.
✓ Branch 7 taken 4675 times.
✓ Branch 8 taken 1867 times.
11217 then DAE.T_TUPLE(
2555 list(makeReturnTypeSingle(v) for v in vl),
2556 SOME(list(TypesDump.getVarName(v) for v in vl)));
2557 end match;
2558 end makeReturnType;
2559
2560 protected function makeReturnTypeSingle "author: LS
2561 Create the return type for a single return value."
2562 input DAE.Var inVar;
2563 output DAE.Type outType;
2564 algorithm
2565 outType := match inVar
2566 local
2567 Type ty;
2568
2569 case DAE.TYPES_VAR(ty = ty) then ty;
2570 end match;
2571 end makeReturnTypeSingle;
2572
2573 public function isParameterVar "author: LS
2574 Succeds if a variable is a parameter."
2575 input DAE.Var inVar;
2576 algorithm
2577 ✗ DAE.TYPES_VAR(attributes = DAE.ATTR(variability = SCode.PARAM(),visibility = SCode.PUBLIC())) := inVar;
2578 end isParameterVar;
2579
2580 public function isConstant
2581 "Returns true of c is C_CONST."
2582 input DAE.Const c;
2583 output Boolean b;
2584 algorithm
2585 b := match c
2586 case DAE.C_CONST() then true;
2587 else false;
2588 end match;
2589 end isConstant;
2590
2591 public function isParameter
2592 "Returns true if c is C_PARAM."
2593 input DAE.Const c;
2594 output Boolean b;
2595 algorithm
2596 b := match c
2597 case DAE.C_PARAM() then true;
2598 else false;
2599 end match;
2600 end isParameter;
2601
2602 public function isParameterOrConstant "returns true if Const is PARAM or CONST"
2603 input DAE.Const c;
2604 output Boolean b;
2605 algorithm
2606 b := match c
2607 case DAE.C_CONST() then true;
2608 case DAE.C_PARAM() then true;
2609 else false;
2610 end match;
2611 end isParameterOrConstant;
2612
2613 public function isVar
2614 input DAE.Const inConst;
2615 output Boolean outIsVar;
2616 algorithm
2617 outIsVar := match inConst
2618 case DAE.C_VAR() then true;
2619 else false;
2620 end match;
2621 end isVar;
2622
2623 public function propsContainReal
2624 "Returns true if any of the given properties contains a Real type."
2625 input list<DAE.Properties> inProperties;
2626 output Boolean outHasReal = false;
2627 algorithm
2628
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 for prop in inProperties loop
2629
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 20 times.
22 if isReal(getPropType(prop)) then
2630 outHasReal := true;
2631 break;
2632 end if;
2633 end for;
2634 end propsContainReal;
2635
2636 public function containReal
2637 "Returns true if a builtin type, or array-type is Real."
2638 input list<DAE.Type> inTypes;
2639 output Boolean outHasReal;
2640 algorithm
2641
2/2
✓ Branch 0 taken 3338 times.
✓ Branch 1 taken 208 times.
3546 for ty in inTypes loop
2642
2/2
✓ Branch 1 taken 437 times.
✓ Branch 2 taken 2901 times.
3338 if isReal(ty) then
2643 outHasReal := true;
2644 437 return;
2645 end if;
2646 end for;
2647 outHasReal := false;
2648 end containReal;
2649
2650 public function propAllConst "author: LS
2651 If PROP_TUPLE, returns true if all of the flags are constant."
2652 input DAE.Properties inProperties;
2653 output DAE.Const outConst;
2654 algorithm
2655 outConst := matchcontinue inProperties
2656 local
2657 DAE.Const c,res;
2658 DAE.TupleConst constant_;
2659 String str;
2660 DAE.Properties prop;
2661 case DAE.PROP(constFlag = c) then c;
2662 case DAE.PROP_TUPLE(tupleConst = constant_)
2663 algorithm
2664 2285 res := propTupleAllConst(constant_);
2665 then
2666 res;
2667 case prop
2668 algorithm
2669 ✗ true := Flags.isSet(Flags.FAILTRACE);
2670 ✗ Debug.trace("- prop_all_const failed: ");
2671 ✗ str := printPropStr(prop);
2672 ✗ Debug.traceln(str);
2673 ✗ then
2674 fail();
2675 end matchcontinue;
2676 end propAllConst;
2677
2678 public function propAnyConst "author: LS
2679 If PROP_TUPLE, returns true if any of the flags are true"
2680 input DAE.Properties inProperties;
2681 output DAE.Const outConst;
2682 algorithm
2683 outConst := matchcontinue inProperties
2684 local
2685 DAE.Const constant_,res;
2686 String str;
2687 DAE.Properties prop;
2688 DAE.TupleConst tconstant_;
2689 case DAE.PROP(constFlag = constant_) then constant_;
2690 case DAE.PROP_TUPLE(tupleConst = tconstant_)
2691 algorithm
2692 ✗ res := propTupleAnyConst(tconstant_);
2693 then
2694 res;
2695 case prop
2696 algorithm
2697 ✗ true := Flags.isSet(Flags.FAILTRACE);
2698 ✗ Debug.trace("- prop_any_const failed: ");
2699 ✗ str := printPropStr(prop);
2700 ✗ Debug.traceln(str);
2701 ✗ then
2702 fail();
2703 end matchcontinue;
2704 end propAnyConst;
2705
2706 protected function propTupleAnyConst "author: LS
2707 Helper function to prop_any_const."
2708 input DAE.TupleConst inTupleConst;
2709 output DAE.Const outConst;
2710 algorithm
2711 outConst := matchcontinue inTupleConst
2712 local
2713 DAE.Const c,res;
2714 DAE.TupleConst first,const;
2715 list<DAE.TupleConst> rest;
2716 String str;
2717 case DAE.SINGLE_CONST(const = c) then c;
2718 case DAE.TUPLE_CONST(tupleConstLst = (first :: _))
2719 algorithm
2720 ✗ DAE.C_CONST() := propTupleAnyConst(first);
2721 then
2722 DAE.C_CONST();
2723 case DAE.TUPLE_CONST(tupleConstLst = (first :: {}))
2724 algorithm
2725 ✗ DAE.C_PARAM() := propTupleAnyConst(first);
2726 then
2727 DAE.C_PARAM();
2728 case DAE.TUPLE_CONST(tupleConstLst = (first :: {}))
2729 algorithm
2730 ✗ DAE.C_VAR() := propTupleAnyConst(first);
2731 then
2732 DAE.C_VAR();
2733 case DAE.TUPLE_CONST(tupleConstLst = (first :: rest))
2734 algorithm
2735 ✗ DAE.C_PARAM() := propTupleAnyConst(first);
2736 ✗ res := propTupleAnyConst(DAE.TUPLE_CONST(rest));
2737 then
2738 res;
2739 case DAE.TUPLE_CONST(tupleConstLst = (first :: rest))
2740 algorithm
2741 ✗ DAE.C_VAR() := propTupleAnyConst(first);
2742 ✗ res := propTupleAnyConst(DAE.TUPLE_CONST(rest));
2743 then
2744 res;
2745 case const
2746 algorithm
2747 ✗ true := Flags.isSet(Flags.FAILTRACE);
2748 ✗ Debug.trace("- prop_tuple_any_const failed: ");
2749 ✗ str := TypesDump.printTupleConstStr(const);
2750 ✗ Debug.traceln(str);
2751 ✗ then
2752 fail();
2753 end matchcontinue;
2754 end propTupleAnyConst;
2755
2756 public function propTupleAllConst "author: LS
2757 Helper function to propAllConst."
2758 input DAE.TupleConst inTupleConst;
2759 output DAE.Const outConst;
2760 algorithm
2761 outConst := matchcontinue inTupleConst
2762 local
2763 DAE.Const c,res;
2764 DAE.TupleConst first,const;
2765 list<DAE.TupleConst> rest;
2766 String str;
2767 case DAE.SINGLE_CONST(const = c) then c;
2768 case DAE.TUPLE_CONST(tupleConstLst = (first :: _))
2769 algorithm
2770
2/2
✓ Branch 1 taken 2585 times.
✓ Branch 2 taken 18 times.
2603 DAE.C_PARAM() := propTupleAllConst(first);
2771 then
2772 DAE.C_PARAM();
2773 case DAE.TUPLE_CONST(tupleConstLst = (first :: _))
2774 algorithm
2775
2/2
✓ Branch 1 taken 438 times.
✓ Branch 2 taken 2147 times.
2585 DAE.C_VAR() := propTupleAllConst(first);
2776 then
2777 DAE.C_VAR();
2778 case DAE.TUPLE_CONST(tupleConstLst = (first :: {}))
2779 algorithm
2780
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 166 times.
166 DAE.C_CONST() := propTupleAllConst(first);
2781 then
2782 DAE.C_CONST();
2783 case DAE.TUPLE_CONST(tupleConstLst = (first :: rest))
2784 algorithm
2785
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
272 DAE.C_CONST() := propTupleAllConst(first);
2786 272 res := propTupleAllConst(DAE.TUPLE_CONST(rest));
2787 then
2788 res;
2789 case const
2790 algorithm
2791 ✗ true := Flags.isSet(Flags.FAILTRACE);
2792 ✗ Debug.trace("- prop_tuple_all_const failed: ");
2793 ✗ str := TypesDump.printTupleConstStr(const);
2794 ✗ Debug.traceln(str);
2795 ✗ then
2796 fail();
2797 end matchcontinue;
2798 end propTupleAllConst;
2799
2800 public function isPropTupleArray "This function will check all elements in the tuple if anyone is an array, return true.
2801 As for now it will not check tuple of tuples ie. no recursion."
2802 input DAE.Properties p;
2803 output Boolean ob;
2804 protected
2805 Boolean b1,b2;
2806 algorithm
2807 37698 b1 := isPropTuple(p);
2808 37698 b2 := isPropArray(p);
2809 37698 ob := boolOr(b1,b2);
2810 end isPropTupleArray;
2811
2812 public function isPropTuple
2813 "Checks if Properties is a tuple or not."
2814 input DAE.Properties p;
2815 output Boolean b;
2816 algorithm
2817 b := matchcontinue p
2818 case _
2819 algorithm
2820
2/2
✓ Branch 1 taken 39125 times.
✓ Branch 2 taken 86 times.
39211 DAE.T_TUPLE() := getPropType(p);
2821 then
2822 true;
2823 else false;
2824 end matchcontinue;
2825 end isPropTuple;
2826
2827 public function isPropArray "Return true if properties contain an array type."
2828 input DAE.Properties p;
2829 output Boolean b;
2830 protected
2831 Type t;
2832 algorithm
2833 72804 t := getPropType(p);
2834 72804 b := isArray(t);
2835 end isPropArray;
2836
2837 public function propTupleFirstProp
2838 "Returns the first property from a tuple's properties or fails."
2839 input DAE.Properties inTupleProp;
2840 output DAE.Properties outFirstProp;
2841 protected
2842 Type ty;
2843 DAE.Const c;
2844 algorithm
2845
6/12
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
2 DAE.PROP_TUPLE(type_ = DAE.T_TUPLE(types = ty :: _),
2846 tupleConst = DAE.TUPLE_CONST(tupleConstLst = DAE.SINGLE_CONST(const = c) :: _)) := inTupleProp;
2847 2 outFirstProp := DAE.PROP(ty, c);
2848 end propTupleFirstProp;
2849
2850 public function propTuplePropList
2851 "Splits a PROP_TUPLE into a list of PROPs."
2852 input DAE.Properties prop_tuple;
2853 output list<DAE.Properties> prop_list;
2854 algorithm
2855 prop_list := match prop_tuple
2856 local
2857 list<DAE.Properties> pl;
2858 list<DAE.Type> tl;
2859 list<TupleConst> cl;
2860 case DAE.PROP_TUPLE(type_ = DAE.T_TUPLE(types = tl),
2861 tupleConst = DAE.TUPLE_CONST(tupleConstLst = cl))
2862 algorithm
2863 66 pl := propTuplePropList2(tl, cl);
2864 then
2865 pl;
2866 end match;
2867 end propTuplePropList;
2868
2869 protected function propTuplePropList2
2870 "Helper function to propTuplePropList"
2871 input list<DAE.Type> tl;
2872 input list<TupleConst> cl;
2873 output list<DAE.Properties> pl;
2874 algorithm
2875 pl := match(tl, cl)
2876 local
2877 Type t;
2878 list<DAE.Type> t_rest;
2879 Const c;
2880 list<TupleConst> c_rest;
2881 list<DAE.Properties> p_rest;
2882 case ({}, {}) then {};
2883 case (t :: t_rest, DAE.SINGLE_CONST(c) :: c_rest)
2884 algorithm
2885 132 p_rest := propTuplePropList2(t_rest, c_rest);
2886 132 then
2887 (DAE.PROP(t, c) :: p_rest);
2888 end match;
2889 end propTuplePropList2;
2890
2891 public function getPropConst "author: adrpo
2892 Return the const from Properties (no tuples!)."
2893 input DAE.Properties inProperties;
2894 output DAE.Const outConst;
2895 algorithm
2896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 681 times.
681 DAE.PROP(constFlag = outConst) := inProperties;
2897 end getPropConst;
2898
2899 public function getPropType "author: LS
2900 Return the Type from Properties."
2901 input DAE.Properties inProperties;
2902 output DAE.Type outType;
2903 algorithm
2904 outType := match inProperties
2905 1405172 case DAE.PROP() then inProperties.type_;
2906 881 case DAE.PROP_TUPLE() then inProperties.type_;
2907 end match;
2908 end getPropType;
2909
2910 public function setPropType "Set the Type from Properties."
2911 input DAE.Properties inProperties;
2912 input DAE.Type ty;
2913 output DAE.Properties outProperties;
2914 algorithm
2915 outProperties := match inProperties
2916 34082 case DAE.PROP() then DAE.PROP(ty, inProperties.constFlag);
2917 108 case DAE.PROP_TUPLE() then DAE.PROP_TUPLE(ty, inProperties.tupleConst);
2918 end match;
2919 end setPropType;
2920
2921 public function createEmptyTypeMemory
2922 "@author: adrpo
2923 creates an array, with one element for each record in TType!
2924 Note: This has to be at least 4 larger than the number of records in DAE.Type,
2925 due to the way bootstrapping indexes records."
2926 output InstTypes.TypeMemoryEntryListArray tyMemory;
2927 algorithm
2928 ✗ tyMemory := arrayCreate(30, {});
2929 end createEmptyTypeMemory;
2930
2931 public function simplifyType
2932 "@author: adrpo
2933 simplifies the given type, to be used in an expression or component reference"
2934 input DAE.Type inType;
2935 output DAE.Type outExpType;
2936 algorithm
2937 outExpType := matchcontinue inType
2938 local
2939 String str;
2940 Type t;
2941 DAE.Type t_1;
2942 DAE.Dimensions dims;
2943 list<DAE.Type> tys;
2944 list<DAE.Var> varLst;
2945 ClassInf.State CIS;
2946 DAE.EqualityConstraint ec;
2947
2948 1826 case DAE.T_FUNCTION() then DAE.T_FUNCTION_REFERENCE_VAR(inType);
2949
2950 320845 case DAE.T_METAUNIONTYPE() then DAE.T_METATYPE(inType);
2951 5460 case DAE.T_METARECORD() then DAE.T_METATYPE(inType);
2952 11847 case DAE.T_METAPOLYMORPHIC() then DAE.T_METATYPE(inType);
2953 65995 case DAE.T_METALIST() then DAE.T_METATYPE(inType);
2954 2500 case DAE.T_METAARRAY() then DAE.T_METATYPE(inType);
2955 20144 case DAE.T_METAOPTION() then DAE.T_METATYPE(inType);
2956 3542 case DAE.T_METATUPLE() then DAE.T_METATYPE(inType);
2957
2958 case DAE.T_UNKNOWN() then DAE.T_UNKNOWN_DEFAULT;
2959 case DAE.T_ANYTYPE() then DAE.T_UNKNOWN_DEFAULT;
2960
2961 case t as DAE.T_ARRAY()
2962 algorithm
2963 1517901 (t,dims) := TypesDump.flattenArrayType(t);
2964 1517901 t_1 := simplifyType(t);
2965 1517901 then
2966 DAE.T_ARRAY(t_1,dims);
2967
2968 // do NOT simplify out equality constraint
2969 case DAE.T_SUBTYPE_BASIC(equalityConstraint = SOME(_)) then inType;
2970 16454 case DAE.T_SUBTYPE_BASIC(complexType = t) then simplifyType(t);
2971
2972 case DAE.T_INTEGER() then DAE.T_INTEGER_DEFAULT;
2973 case DAE.T_REAL() then DAE.T_REAL_DEFAULT;
2974 case DAE.T_BOOL() then DAE.T_BOOL_DEFAULT;
2975 // BTH watch out: Due to simplification some type info is lost here
2976 case DAE.T_CLOCK() then DAE.T_CLOCK_DEFAULT;
2977 case DAE.T_STRING() then DAE.T_STRING_DEFAULT;
2978 case DAE.T_NORETCALL() then DAE.T_NORETCALL_DEFAULT;
2979 case DAE.T_TUPLE(types = tys)
2980 algorithm
2981 1710 tys := List.map(tys, simplifyType);
2982 1710 then DAE.T_TUPLE(tys, inType.names);
2983
2984 case DAE.T_ENUMERATION() then inType;
2985
2986 // for metamodelica we need this for some reson!
2987 case DAE.T_COMPLEX(CIS, varLst, ec)
2988 algorithm
2989
2/2
✓ Branch 1 taken 900428 times.
✓ Branch 2 taken 3126 times.
903554 true := Config.acceptMetaModelicaGrammar();
2990
4/4
✓ Branch 0 taken 726 times.
✓ Branch 1 taken 3126 times.
✓ Branch 2 taken 726 times.
✓ Branch 3 taken 3126 times.
3852 varLst := list(simplifyVar(v) for v in varLst);
2991 3126 then
2992 DAE.T_COMPLEX(CIS, varLst, ec, inType.usedExternally);
2993
2994 // do this for records too, otherwise:
2995 // frame.R = Modelica.Mechanics.MultiBody.Frames.Orientation({const_matrix);
2996 // does not get expanded into the component equations.
2997 case DAE.T_COMPLEX(CIS as ClassInf.RECORD(), varLst, ec)
2998 algorithm
2999
4/4
✓ Branch 0 taken 3250250 times.
✓ Branch 1 taken 316361 times.
✓ Branch 2 taken 3250250 times.
✓ Branch 3 taken 316361 times.
3566611 varLst := list(simplifyVar(v) for v in varLst);
3000 316361 then
3001 DAE.T_COMPLEX(CIS, varLst, ec, inType.usedExternally);
3002
3003 // otherwise just return the same!
3004 case DAE.T_COMPLEX() then inType;
3005
3006 case DAE.T_METABOXED(ty = t)
3007 algorithm
3008 939 t_1 := simplifyType(t);
3009 939 then DAE.T_METABOXED(t_1);
3010
3011 // This is the case when the type is currently UNTYPED
3012 case _
3013 algorithm
3014 /*
3015 print(" untyped ");
3016 print(TypesDump.unparseType(inType));
3017 print("\n");
3018 */
3019 then DAE.T_UNKNOWN_DEFAULT;
3020
3021 else
3022 algorithm
3023 ✗ str := "Types.simplifyType failed for: " + TypesDump.unparseType(inType);
3024 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
3025 ✗ then fail();
3026 end matchcontinue;
3027 end simplifyType;
3028
3029 protected function simplifyVar
3030 input DAE.Var inVar;
3031 output DAE.Var outVar = inVar;
3032 algorithm
3033 outVar := match outVar
3034 case DAE.TYPES_VAR()
3035 algorithm
3036 3250976 outVar.ty := simplifyType(outVar.ty);
3037 then
3038 outVar;
3039 end match;
3040 end simplifyVar;
3041
3042 public function complicateType
3043 "Does the opposite of simplifyType, as far as it's possible."
3044 input DAE.Type inType;
3045 output DAE.Type outType = inType;
3046 algorithm
3047 outType := match outType
3048 local
3049 DAE.Type ty;
3050 list<DAE.Dimension> dims;
3051
3052 case DAE.T_ARRAY(dims = _ :: _)
3053 algorithm
3054 4296 (ty, dims) := TypesDump.flattenArrayType(outType);
3055 4296 then
3056 liftArrayListDims(ty, dims);
3057
3058 ✗ case DAE.T_FUNCTION_REFERENCE_VAR() then outType.functionType;
3059 ✗ case DAE.T_METATYPE() then outType.ty;
3060
3061 case DAE.T_TUPLE()
3062 algorithm
3063 ✗ outType.types := list(complicateType(t) for t in outType.types);
3064 then
3065 outType;
3066
3067 case DAE.T_COMPLEX()
3068 algorithm
3069 ✗ if isRecord(inType) or Config.acceptMetaModelicaGrammar() then
3070 ✗ outType.varLst := list(complicateVar(v) for v in outType.varLst);
3071 end if;
3072 then
3073 outType;
3074
3075 case DAE.T_METABOXED()
3076 algorithm
3077 ✗ outType.ty := complicateType(outType.ty);
3078 then
3079 outType;
3080
3081 else outType;
3082 end match;
3083 end complicateType;
3084
3085 protected function complicateVar
3086 input DAE.Var inVar;
3087 output DAE.Var outVar = inVar;
3088 algorithm
3089 outVar := match outVar
3090 case DAE.TYPES_VAR()
3091 algorithm
3092 ✗ outVar.ty := complicateType(outVar.ty);
3093 then
3094 outVar;
3095 end match;
3096 end complicateVar;
3097
3098 protected function typeMemoryEntryEq
3099 input DAE.Type inType1;
3100 input tuple<DAE.Type, DAE.Type> inType2;
3101 output Boolean outEq;
3102 protected
3103 DAE.Type ty2;
3104 algorithm
3105 ✗ (ty2, _) := inType2;
3106 ✗ outEq := typesElabEquivalent(inType1, ty2);
3107 end typeMemoryEntryEq;
3108
3109 public function typesElabEquivalent
3110 "This function checks if two types will result in the same elaborated type.
3111 Used by simplifyType to check if a matching elaborated type already exists."
3112 input DAE.Type inType1;
3113 input DAE.Type inType2;
3114 output Boolean isEqual;
3115 algorithm
3116 try
3117 ✗ isEqual := ttypesElabEquivalent(inType1, inType2);
3118 else
3119 isEqual := false;
3120 end try;
3121 end typesElabEquivalent;
3122
3123 protected function ttypesElabEquivalent
3124 "Helper function to typesElabEquivalent. Checks if two TType will result in
3125 the same elaborated type."
3126 input DAE.Type inType1;
3127 input DAE.Type inType2;
3128 output Boolean isEqual;
3129 algorithm
3130 isEqual := match(inType1, inType2)
3131 local
3132 ClassInf.State cty1, cty2;
3133 list<DAE.Var> vars1, vars2;
3134 DAE.Dimension ad1, ad2;
3135 DAE.Type ty1, ty2;
3136 Absyn.Path p1, p2;
3137 list<String> names1, names2;
3138 list<DAE.Type> types1, types2;
3139
3140 case (DAE.T_COMPLEX(complexClassType = cty1, varLst = vars1),
3141 DAE.T_COMPLEX(complexClassType = cty2, varLst = vars2))
3142 algorithm
3143 ✗ true := AbsynUtil.pathEqual(ClassInfUtil.getStateName(cty1),
3144 ClassInfUtil.getStateName(cty2));
3145 ✗ true := List.isEqualOnTrue(vars1, vars2,
3146 varsElabEquivalent);
3147 then
3148 true;
3149
3150 case (DAE.T_ARRAY(dims = {ad1}, ty = ty1),
3151 DAE.T_ARRAY(dims = {ad2}, ty = ty2))
3152 algorithm
3153 ✗ true := valueEq(ad1, ad2);
3154 ✗ true := typesElabEquivalent(ty1, ty2);
3155 then
3156 true;
3157
3158 case (DAE.T_ENUMERATION(path = p1, names = names1),
3159 DAE.T_ENUMERATION(path = p2, names = names2))
3160 algorithm
3161 ✗ true := AbsynUtil.pathEqual(p1, p2);
3162 ✗ true := List.isEqualOnTrue(names1, names2, stringEqual);
3163 then
3164 true;
3165
3166 case (DAE.T_TUPLE(types = types1),
3167 DAE.T_TUPLE(types = types2))
3168 ✗ then List.isEqualOnTrue(types1, types2,
3169 typesElabEquivalent);
3170
3171 case (DAE.T_METABOXED(ty = ty1),
3172 DAE.T_METABOXED(ty = ty2))
3173 ✗ then typesElabEquivalent(ty1, ty2);
3174
3175 ✗ else valueEq(inType1, inType2);
3176
3177 end match;
3178 end ttypesElabEquivalent;
3179
3180 protected function varsElabEquivalent
3181 "Helper function to ttypesElabEquivalent. Check if two DAE.Var will result in
3182 the same DAE.Var after elaboration."
3183 input DAE.Var inVar1;
3184 input DAE.Var inVar2;
3185 output Boolean isEqual;
3186 algorithm
3187 isEqual := match(inVar1, inVar2)
3188 local
3189 DAE.Ident id1, id2;
3190 DAE.Type ty1, ty2;
3191
3192 case (DAE.TYPES_VAR(name = id1, ty = ty1),
3193 DAE.TYPES_VAR(name = id2, ty = ty2)) guard stringEqual(id1, id2) and typesElabEquivalent(ty1, ty2)
3194 then
3195 true;
3196
3197 else false;
3198
3199 end match;
3200 end varsElabEquivalent;
3201
3202 public function matchProp
3203 "This is basically a wrapper aroune matchType.
3204 It matches an expression with properties with another set of properties.
3205 If necessary, the expression is modified to match.
3206 The only relevant property is the type."
3207 input DAE.Exp inExp;
3208 input DAE.Properties inActualType;
3209 input DAE.Properties inExpectedType;
3210 input Boolean printFailtrace;
3211 output DAE.Exp outExp;
3212 output DAE.Properties outProperties;
3213 algorithm
3214 (outExp,outProperties) := matchcontinue (inExp, inActualType, inExpectedType, printFailtrace)
3215 local
3216 DAE.Exp e_1,e;
3217 Type t_1,gt,et;
3218 Const c,c1,c2,c_1;
3219 TupleConst tc,tc1,tc2;
3220 Properties prop;
3221 case (e,DAE.PROP(type_ = gt,constFlag = c1),DAE.PROP(type_ = et,constFlag = c2),_)
3222 algorithm
3223 466101 (e_1,t_1) := matchType(e, gt, et, printFailtrace);
3224 439481 c := constAnd(c1, c2);
3225 439481 then
3226 (e_1,DAE.PROP(t_1,c));
3227 case (e,DAE.PROP_TUPLE(type_ = gt,tupleConst = tc1),DAE.PROP_TUPLE(type_ = et,tupleConst = tc2),_)
3228 algorithm
3229 46 (e_1,t_1) := matchType(e, gt, et, printFailtrace);
3230 46 tc := constTupleAnd(tc1, tc2);
3231 46 then
3232 (e_1,DAE.PROP_TUPLE(t_1,tc));
3233
3234 // The problem with MetaModelica tuple is that it is a datatype (should use PROP instead of PROP_TUPLE)
3235 // this case converts a TUPLE to META_TUPLE
3236 case (e,DAE.PROP_TUPLE(type_ = gt as DAE.T_TUPLE(),tupleConst = tc1), DAE.PROP(type_ = et as DAE.T_METATUPLE(),constFlag = c2),_)
3237 algorithm
3238 ✗ true := Config.acceptMetaModelicaGrammar();
3239 ✗ (e_1,t_1) := matchType(e, gt, et, printFailtrace);
3240 ✗ c_1 := propTupleAllConst(tc1);
3241 ✗ c := constAnd(c_1, c2);
3242 ✗ then
3243 (e_1,DAE.PROP(t_1,c));
3244 case (e,DAE.PROP_TUPLE(type_ = gt as DAE.T_TUPLE(),tupleConst = tc1), DAE.PROP(type_ = et as DAE.T_METABOXED(),constFlag = c2),_)
3245 algorithm
3246 ✗ true := Config.acceptMetaModelicaGrammar();
3247 ✗ (e_1,t_1) := matchType(e, gt, et, printFailtrace);
3248 ✗ c_1 := propTupleAllConst(tc1);
3249 ✗ c := constAnd(c_1, c2);
3250 ✗ then
3251 (e_1,DAE.PROP(t_1,c));
3252
3253 case (e,DAE.PROP(type_ = gt),DAE.PROP_TUPLE(),_)
3254 algorithm
3255 ✗ prop := propTupleFirstProp(inExpectedType);
3256 ✗ (e_1, prop) := matchProp(e, inActualType, prop, printFailtrace);
3257 ✗ gt := simplifyType(gt);
3258 ✗ e_1 := DAE.TSUB(e_1, 1, gt);
3259 ✗ then
3260 (e_1, prop);
3261
3262 case (e,DAE.PROP_TUPLE(),DAE.PROP(),_)
3263 algorithm
3264 ✗ prop as DAE.PROP(type_ = gt) := propTupleFirstProp(inActualType);
3265 ✗ (e_1, prop) := matchProp(e, prop, inExpectedType, printFailtrace);
3266 ✗ gt := simplifyType(gt);
3267 ✗ e_1 := DAE.TSUB(e_1, 1, gt);
3268 ✗ then
3269 (e_1, prop);
3270
3271 case(e, _, _, true)
3272 algorithm
3273 // activate on -d=types flag
3274
1/2
✓ Branch 1 taken 18204 times.
✗ Branch 2 not taken.
18204 true := Flags.isSet(Flags.TYPES);
3275 ✗ Debug.traceln("- Types.matchProp failed on exp: " + ExpressionBasics.printExpStr(e));
3276 ✗ Debug.traceln(printPropStr(inActualType) + " != ");
3277 ✗ Debug.traceln(printPropStr(inExpectedType));
3278 ✗ then fail();
3279 end matchcontinue;
3280 end matchProp;
3281
3282 public function matchTypeList
3283 input list<DAE.Exp> exps;
3284 input DAE.Type expType;
3285 input DAE.Type expectedType;
3286 input Boolean printFailtrace;
3287 output list<DAE.Exp> outExp = {};
3288 output list<DAE.Type> outTypeLst = {};
3289 protected
3290 list<DAE.Exp> expLstNew = exps;
3291 DAE.Exp exp, e_1;
3292 Type tp;
3293 algorithm
3294
2/2
✓ Branch 0 taken 293 times.
✓ Branch 1 taken 112 times.
405 while not listEmpty(expLstNew) loop
3295 293 exp::expLstNew := expLstNew;
3296 293 (e_1, tp) := matchType(exp, expType, expectedType, printFailtrace);
3297 outExp := e_1 :: outExp;
3298 293 outTypeLst := tp :: outTypeLst;
3299 end while;
3300 112 outExp := listReverseInPlace(outExp);
3301 112 outTypeLst := listReverseInPlace(outTypeLst);
3302 end matchTypeList;
3303
3304 public function matchTypeTuple
3305 "Transforms a list of expressions and types into a list of expressions
3306 of the expected types."
3307 input list<DAE.Exp> inExp1;
3308 input list<DAE.Type> inTypeLst2;
3309 input list<DAE.Type> inTypeLst3;
3310 input Boolean printFailtrace;
3311 output list<DAE.Exp> outExp;
3312 output list<DAE.Type> outTypeLst;
3313 algorithm
3314 (outExp,outTypeLst):=
3315 matchcontinue (inExp1,inTypeLst2,inTypeLst3,printFailtrace)
3316 local
3317 DAE.Exp e,e_1;
3318 list<DAE.Exp> rest, e_2;
3319 Type tp,t1,t2;
3320 list<DAE.Type> res,ts1,ts2;
3321 case ({},{},{},_) then ({},{});
3322 case (e::rest,(t1 :: ts1),(t2 :: ts2),_)
3323 algorithm
3324 152999 (e_1,tp) := matchType(e,t1,t2,printFailtrace);
3325 152999 (e_2,res) := matchTypeTuple(rest,ts1,ts2,printFailtrace);
3326 152999 then
3327 (e_1::e_2,(tp :: res));
3328 case (_,(t1 :: _),(t2 :: _),true)
3329 algorithm
3330 ✗ true := Flags.isSet(Flags.FAILTRACE);
3331 ✗ Debug.trace("- Types.matchTypeTuple failed:"+TypesDump.unparseType(t1)+" "+TypesDump.unparseType(t2)+"\n");
3332 ✗ then
3333 fail();
3334 end matchcontinue;
3335 end matchTypeTuple;
3336
3337 public function matchTypeTupleCall
3338 input DAE.Exp inExp1;
3339 input list<DAE.Type> inTypeLst2;
3340 input list<DAE.Type> inTypeLst3;
3341 algorithm
3342 () :=
3343 matchcontinue (inExp1,inTypeLst2,inTypeLst3)
3344 local
3345 DAE.Exp e;
3346 Type t1,t2;
3347 list<DAE.Type> ts1,ts2;
3348 case (_,_,{}) then ();
3349 case (e,(t1 :: ts1),(t2 :: ts2))
3350 algorithm
3351 // We cannot use matchType here because it does not cast tuple calls properly
3352
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 2023 times.
2024 true := subtype(t1, t2);
3353 /* (oe,_) = matchType(e, t1, t2, true);
3354 true = ExpressionBasics.expEqual(e,oe); */
3355 2023 matchTypeTupleCall(e, ts1, ts2);
3356 then ();
3357 case (_,(_ :: _),(_ :: _))
3358 algorithm
3359
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 true := Flags.isSet(Flags.FAILTRACE);
3360 ✗ Debug.trace("- matchTypeTupleCall failed\n");
3361 ✗ then
3362 fail();
3363 end matchcontinue;
3364 end matchTypeTupleCall;
3365
3366 public function vectorizableType "author: PA
3367 This function checks if a given type can be (converted and) vectorized to
3368 a expected type.
3369 For instance and argument of type Integer{:} can be vectorized to an
3370 argument type Real, using type coersion and vectorization of one dimension."
3371 input DAE.Exp inExp;
3372 input DAE.Type inExpType;
3373 input DAE.Type inExpectedType;
3374 input Option<Absyn.Path> fnPath;
3375 output DAE.Exp outExp;
3376 output DAE.Type outType;
3377 output DAE.Dimensions outArrayDimLst;
3378 output InstTypes.PolymorphicBindings outBindings;
3379 algorithm
3380 3710 (outExp,outType,outArrayDimLst,outBindings) := vectorizableType2(inExp,inExpType,inExpType,{},inExpectedType,fnPath);
3381 end vectorizableType;
3382
3383 protected function vectorizableType2
3384 input DAE.Exp inExp;
3385 input DAE.Type inExpType;
3386 input DAE.Type inCurrentType;
3387 input DAE.Dimensions inDims;
3388 input DAE.Type inExpectedType;
3389 input Option<Absyn.Path> fnPath;
3390 output DAE.Exp outExp;
3391 output DAE.Type outType;
3392 output DAE.Dimensions outDims;
3393 output InstTypes.PolymorphicBindings outBindings;
3394 protected
3395 Type vec_type, cur_type;
3396 DAE.Dimension dim;
3397 algorithm
3398 try
3399 6624 vec_type := liftArrayListDimsReverse(inExpectedType, inDims);
3400 6624 (outExp, outType, outBindings) :=
3401 matchTypePolymorphic(inExp, inExpType, vec_type, fnPath, {}, true);
3402 2885 outDims := listReverse(inDims);
3403 else
3404
4/6
✓ Branch 0 taken 825 times.
✓ Branch 1 taken 2914 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2914 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2914 times.
3739 DAE.T_ARRAY(ty = cur_type, dims = {dim}) := inCurrentType;
3405 2914 (outExp, outType, outDims, outBindings) :=
3406 vectorizableType2(inExp, inExpType, cur_type, dim :: inDims, inExpectedType, fnPath);
3407 end try;
3408 end vectorizableType2;
3409
3410 public function unflattenArrayType
3411 "transforms T_ARRAY(a::b::c) to T_ARRAY(a, T_ARRAY(b, T_ARRAY(c)))
3412 Always call it with "
3413 input DAE.Type inTy;
3414 output DAE.Type outTy;
3415 algorithm
3416 79520 outTy := unflattenArrayType2(inTy, false);
3417 end unflattenArrayType;
3418
3419 protected function unflattenArrayType2
3420 "transforms T_ARRAY(a::b::c) to T_ARRAY(a, T_ARRAY(b, T_ARRAY(c)))
3421 Always call it with "
3422 input DAE.Type inTy;
3423 input Boolean last;
3424 output DAE.Type outTy;
3425 algorithm
3426 outTy := matchcontinue(inTy, last)
3427 local
3428 DAE.Type ty, t;
3429 DAE.Dimensions dims;
3430 DAE.Dimension dim;
3431 ClassInf.State ci;
3432 list<DAE.Var> vl;
3433 EqualityConstraint eqc;
3434
3435 // subtype basic crap
3436 case (DAE.T_SUBTYPE_BASIC(ci, vl, ty, eqc), _)
3437 algorithm
3438 ✗ ty := unflattenArrayType(ty);
3439 ✗ then DAE.T_SUBTYPE_BASIC(ci, vl, ty, eqc);
3440
3441 // already in the way we want it
3442 case (DAE.T_ARRAY(t, {dim}), _)
3443 algorithm
3444 12573 t := unflattenArrayType(t);
3445 12573 then DAE.T_ARRAY(t, {dim});
3446
3447 // we might get here via true!
3448 case (DAE.T_ARRAY(t, {}), true)
3449 ✗ then unflattenArrayType(t);
3450
3451 // the usual case
3452 case (DAE.T_ARRAY(t, dim::dims), _)
3453 algorithm
3454 6290 ty := unflattenArrayType2(DAE.T_ARRAY(t, dims), true);
3455 6290 ty := DAE.T_ARRAY(ty, {dim});
3456 then ty;
3457
3458 case (ty, false) then ty;
3459 end matchcontinue;
3460 end unflattenArrayType2;
3461
3462 protected function typeConvert
3463 "This functions converts the expression in the first argument to
3464 the type specified in the third argument. The current type of the
3465 expression is given in the second argument.
3466 If no type conversion is possible, this function fails."
3467 input DAE.Exp inExp1;
3468 input DAE.Type actual;
3469 input DAE.Type expected;
3470 input Boolean printFailtrace;
3471 output DAE.Exp outExp;
3472 output DAE.Type outType;
3473 algorithm
3474 (outExp,outType):=
3475 matchcontinue (inExp1, actual, expected)
3476 local
3477 list<DAE.Exp> elist_1,elist,inputs;
3478 DAE.Type at,t;
3479 Boolean sc, a;
3480 Integer nmax, oi;
3481 DAE.Dimension dim1, dim2, dim11, dim22;
3482 DAE.Dimensions dims;
3483 Type ty1,ty2,t1,t2,t_1,t_2,ty0,ty;
3484 DAE.Exp begin_1,step_1,stop_1,begin,step,stop,e_1,e,exp;
3485 list<list<DAE.Exp>> ell_1,ell,elist_big;
3486 list<DAE.Type> tys_1,tys1,tys2;
3487 String name;
3488 list<String> l;
3489 list<DAE.Var> v;
3490 Absyn.Path path,path1,path2;
3491 list<Absyn.Path> pathList;
3492 DAE.ComponentRef cref;
3493 list<DAE.ComponentRef> crefList;
3494 list<DAE.Type> expTypes;
3495 DAE.Type et,ety1;
3496 list<DAE.MatchCase> cases;
3497 DAE.MatchType matchTy;
3498 list<DAE.Element> localDecls;
3499 list<DAE.Var> els1,els2;
3500 Absyn.Path p1,p2,tp;
3501 list<list<String>> aliases;
3502
3503 // For the types that cannot be type-converted, but may be subtypes of another type
3504 case (e, ty1, ty2)
3505 algorithm
3506
1/2
✓ Branch 1 taken 949540 times.
✗ Branch 2 not taken.
949540 true := subtype(ty1,ty2);
3507 ✗ then (e, ty2);
3508
3509 // if we expect notTuple and we get Tuple do DAE.TSUB(e, 1)
3510 // we try subtype of the first tuple element with the other type!
3511 case (e, DAE.T_TUPLE(types = ty1::_), ty2)
3512 algorithm
3513
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 false := Config.acceptMetaModelicaGrammar();
3514 ✗ false := isTuple(ty2);
3515 ✗ true := subtype(ty1, ty2);
3516 ✗ e := DAE.TSUB(e, 1, ty2);
3517 ✗ ty := ty2;
3518 ✗ then
3519 (e, ty);
3520
3521 // try dims as list T_ARRAY(a::b::c)
3522 case (e, DAE.T_ARRAY(dims = _::_::_), ty2)
3523 algorithm
3524 ✗ ty1 := unflattenArrayType(actual);
3525 ✗ ty2 := unflattenArrayType(ty2);
3526 ✗ (e, ty) := typeConvert(e, ty1, ty2, printFailtrace);
3527 then
3528 (e, ty);
3529
3530 // try dims as list T_ARRAY(a::b::c)
3531 case (e, ty1, DAE.T_ARRAY(dims = _::_::_))
3532 algorithm
3533 21 ty1 := unflattenArrayType(ty1);
3534 21 ty2 := unflattenArrayType(expected);
3535 21 (e, ty) := typeConvert(e, ty1, ty2, printFailtrace);
3536 then
3537 (e, ty);
3538
3539 // Array expressions: expression dimension [dim1], expected dimension [dim2]
3540 case (DAE.ARRAY(array = elist), DAE.T_ARRAY(dims = {dim1},ty = ty1), ty0 as DAE.T_ARRAY(dims = {dim2},ty = ty2))
3541 algorithm
3542
2/2
✓ Branch 1 taken 61339 times.
✓ Branch 2 taken 18058 times.
79397 true := Expression.dimensionsKnownAndEqual(dim1, dim2);
3543 18058 elist_1 := typeConvertArray(elist,ty1,ty2,printFailtrace);
3544 16660 at := simplifyType(ty0);
3545 16660 a := isArray(ty2);
3546 sc := boolNot(a);
3547
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 16616 times.
33364 then
3548 (DAE.ARRAY(at,sc,elist_1),DAE.T_ARRAY(ty2, {dim1}));
3549
3550 // Array expressions: expression dimension [:], expected dimension [dim2]
3551 /* ARRAYS HAVE KNOWN DIMENSIONS. WHO WROTE THIS :(
3552 case (DAE.ARRAY(array = elist),
3553 (DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()},ty = ty1),_),
3554 ty0 as (DAE.T_ARRAY(dims = {dim2},ty = ty2),p2),
3555 printFailtrace)
3556 algorithm
3557 true = Expression.dimensionKnown(dim2);
3558 elist_1 = typeConvertArray(elist,ty1,ty2,printFailtrace);
3559 at = simplifyType(ty0);
3560 a = isArray(ty2);
3561 sc = boolNot(a);
3562 then
3563 (DAE.ARRAY(at,sc,elist_1),(DAE.T_ARRAY(DAE.DIM_UNKNOWN(),ty2),p2));
3564 */
3565
3566 // Array expressions: expression dimension [dim1], expected dimension [:]
3567 case (DAE.ARRAY(array = elist), DAE.T_ARRAY(dims = {dim1},ty = ty1), DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()}, ty = ty2))
3568 algorithm
3569
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61338 times.
61338 true := Expression.dimensionKnown(dim1);
3570 61338 elist_1 := typeConvertArray(elist,ty1,ty2,printFailtrace);
3571 424 dims := Expression.arrayDimension(simplifyType(ty1));
3572 424 a := isArray(ty2);
3573 sc := boolNot(a);
3574 dims := dim1 :: dims;
3575 424 ty2 := arrayElementType(ty2);
3576 424 ety1 := simplifyType(ty2);
3577 424 ty2 := liftArrayListDims(ty2, dims);
3578 //TODO: Verify correctness of return value.
3579
2/2
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 356 times.
492 then
3580 (DAE.ARRAY(DAE.T_ARRAY(ety1, dims),sc,elist_1), ty2);
3581
3582 // Full range expressions, e.g. 1:2:10
3583 case (DAE.RANGE(start = begin,step = SOME(step),stop = stop), DAE.T_ARRAY(dims = {dim1},ty = ty1), DAE.T_ARRAY(dims = {dim2}, ty = ty2))
3584 algorithm
3585 ✗ true := Expression.dimensionsKnownAndEqual(dim1, dim2);
3586 ✗ (begin_1,_) := typeConvert(begin, ty1, ty2, printFailtrace);
3587 ✗ (step_1,_) := typeConvert(step, ty1, ty2, printFailtrace);
3588 ✗ (stop_1,_) := typeConvert(stop, ty1, ty2, printFailtrace);
3589 ✗ at := simplifyType(DAE.T_ARRAY(ty2, {dim1}));
3590 ✗ then
3591 (DAE.RANGE(at,begin_1,SOME(step_1),stop_1), DAE.T_ARRAY(ty2, {dim1}));
3592
3593 // Range expressions, e.g. 1:10
3594 case (DAE.RANGE(start = begin,step = NONE(),stop = stop), DAE.T_ARRAY(dims = {dim1}, ty = ty1), DAE.T_ARRAY(dims = {dim2}, ty = ty2))
3595 algorithm
3596
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 time.
7 true := Expression.dimensionsKnownAndEqual(dim1, dim2);
3597 1 (begin_1,_) := typeConvert(begin, ty1, ty2, printFailtrace);
3598 1 (stop_1,_) := typeConvert(stop, ty1, ty2, printFailtrace);
3599 1 at := simplifyType(DAE.T_ARRAY(ty2, {dim1}));
3600 2 then
3601 (DAE.RANGE(at,begin_1,NONE(),stop_1), DAE.T_ARRAY(ty2, {dim1}));
3602
3603 // Matrix expressions: expression dimension [dim1,dim11], expected dimension [dim2,dim22]
3604 case (DAE.MATRIX(integer = nmax,matrix = ell), DAE.T_ARRAY(dims = {dim1},ty = DAE.T_ARRAY(dims = {dim11},ty = t1)), ty0 as DAE.T_ARRAY(dims = {dim2},ty = DAE.T_ARRAY(dims = {dim22},ty = t2)))
3605 algorithm
3606
2/2
✓ Branch 1 taken 9494 times.
✓ Branch 2 taken 141 times.
9635 true := Expression.dimensionsKnownAndEqual(dim1, dim2);
3607
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 132 times.
141 true := Expression.dimensionsKnownAndEqual(dim11, dim22);
3608 132 ell_1 := typeConvertMatrix(ell,t1,t2,printFailtrace);
3609 122 at := simplifyType(ty0);
3610 366 then
3611 (DAE.MATRIX(at,nmax,ell_1),DAE.T_ARRAY(DAE.T_ARRAY(t2,{dim11}),{dim1}));
3612
3613 // Matrix expressions: expression dimension [dim1,dim11] expected dimension [:,dim22]
3614 case (DAE.MATRIX(integer = nmax,matrix = ell), DAE.T_ARRAY(dims = {dim1},ty = DAE.T_ARRAY(dims = {dim11},ty = t1)), DAE.T_ARRAY(dims = {dim2},ty = DAE.T_ARRAY(dims = {dim22},ty = t2)))
3615 guard not Expression.dimensionKnown(dim2)
3616 algorithm
3617
2/2
✓ Branch 1 taken 9489 times.
✓ Branch 2 taken 3 times.
9492 true := Expression.dimensionsKnownAndEqual(dim11, dim22);
3618 3 ell_1 := typeConvertMatrix(ell,t1,t2,printFailtrace);
3619 6 ty := DAE.T_ARRAY(DAE.T_ARRAY(t2,{dim11}),{dim1});
3620 3 at := simplifyType(ty);
3621 3 then
3622 (DAE.MATRIX(at,nmax,ell_1),ty);
3623
3624 // Arbitrary expressions, expression dimension [dim1], expected dimension [dim2]
3625 case (e, DAE.T_ARRAY(dims = {dim1},ty = ty1), DAE.T_ARRAY(dims = {dim2},ty = ty2))
3626 algorithm
3627
2/2
✓ Branch 1 taken 108688 times.
✓ Branch 2 taken 1556 times.
110244 true := Expression.dimensionsKnownAndEqual(dim1, dim2);
3628 1556 (e_1,t_1) := typeConvert(e, ty1, ty2, printFailtrace);
3629 133 e_1 := liftExpType(e_1,dim1);
3630 133 t_2 := DAE.T_ARRAY(t_1,{dim2});
3631 133 then
3632 (e_1,t_2);
3633
3634 // Arbitrary expressions, expression dimension [:], expected dimension [dim2]
3635 case (e, DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()},ty = ty1), DAE.T_ARRAY(dims = {_},ty = ty2))
3636 algorithm
3637 828 (e_1,t_1) := typeConvert(e, ty1, ty2, printFailtrace);
3638 22 e_1 := liftExpType(e_1,DAE.DIM_UNKNOWN());
3639 22 then
3640 (e_1,DAE.T_ARRAY(t_1,{DAE.DIM_UNKNOWN()}));
3641
3642 // Arbitrary expression, expression dimension [dim1] expected dimension [:]
3643 case (e, DAE.T_ARRAY(dims = {dim1},ty = ty1), DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()},ty = ty2))
3644 algorithm
3645 108662 (e_1,t_1) := typeConvert(e, ty1, ty2, printFailtrace);
3646 184 e_1 := liftExpType(e_1,dim1);
3647 184 then
3648 (e_1,DAE.T_ARRAY(t_1,{dim1}));
3649
3650 // Arbitrary expressions, expression dimension [:] expected dimension [:]
3651 case (e, DAE.T_ARRAY(dims = {dim1},ty = ty1), DAE.T_ARRAY(dims = {dim2},ty = ty2))
3652 algorithm
3653
2/2
✓ Branch 1 taken 109018 times.
✓ Branch 2 taken 887 times.
109905 false := Expression.dimensionKnown(dim1);
3654
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 887 times.
887 false := Expression.dimensionKnown(dim2);
3655 887 (e_1,t_1) := typeConvert(e, ty1, ty2, printFailtrace);
3656 ✗ e_1 := liftExpType(e_1,DAE.DIM_UNKNOWN());
3657 ✗ then
3658 (e_1,DAE.T_ARRAY(t_1,{DAE.DIM_UNKNOWN()}));
3659
3660 // Tuple
3661 case (DAE.TUPLE(PR = elist), DAE.T_TUPLE(types = tys1), DAE.T_TUPLE(types = tys2))
3662 algorithm
3663 ✗ (elist_1,tys_1) := typeConvertList(elist, tys1, tys2, printFailtrace);
3664 ✗ then
3665 (DAE.TUPLE(elist_1),DAE.T_TUPLE(tys_1,expected.names));
3666
3667 // Implicit conversion from Integer literal to an enumeration
3668 // This is not a valid Modelica conversion, but was widely used in the past,
3669 // by, for instance, Modelica.Electrical.Digital.
3670 // Enable with --intEnumConversion.
3671 case (exp as DAE.ICONST(oi), DAE.T_INTEGER(), t2 as DAE.T_ENUMERATION(path = tp, names = l))
3672 algorithm
3673
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 7 times.
8 true := Config.intEnumConversion();
3674 // It would be good to have the source location of exp here, so that we could pass it to typeConvertIntToEnumCheck.
3675
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 true := typeConvertIntToEnumCheck(exp, t2); // Will warn or report error depending on whether oi is out of range.
3676 // select from enum list:
3677 7 name := listGet(l, oi);
3678 7 tp := AbsynUtil.joinPaths(tp, Absyn.IDENT(name));
3679 7 then
3680 (DAE.ENUM_LITERAL(tp, oi),expected);
3681
3682 // Implicit conversion from Integer to Real
3683 case (e, DAE.T_INTEGER(), DAE.T_REAL())
3684 252963 then
3685 (DAE.CAST(DAE.T_REAL_DEFAULT,e),expected);
3686
3687 // Complex type inheriting primitive type
3688 case (e, DAE.T_SUBTYPE_BASIC(complexType = t1), t2) algorithm
3689 19 (e_1,t_1) := typeConvert(e,t1,t2,printFailtrace);
3690 then (e_1,t_1);
3691 case (e, t1, DAE.T_SUBTYPE_BASIC(complexType = t2)) algorithm
3692 1368 (e_1,t_1) := typeConvert(e,t1,t2,printFailtrace);
3693 then (e_1,t_1);
3694
3695 // Complex types (records) that need a cast
3696 case (e, DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(p1),varLst = els1), t2 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(p2),varLst = els2))
3697 algorithm
3698
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4602 times.
4602 false := AbsynUtil.pathEqual(p1,p2) "We need to add a cast from one record to another";
3699
2/4
✓ Branch 1 taken 4602 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4602 times.
4602 true := Flags.isSet(Flags.ALLOW_RECORD_TOO_MANY_FIELDS) or (listLength(els1) == listLength(els2));
3700
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4602 times.
4602 true := subtypeVarlist(els1, els2);
3701 4602 e := DAE.CAST(t2, e);
3702 4602 then (e, t2);
3703
3704 // MetaModelica Option
3705 case (DAE.META_OPTION(SOME(e)), DAE.T_METAOPTION(ty = t1), DAE.T_METAOPTION(t2)) guard Config.acceptMetaModelicaGrammar()
3706 algorithm
3707 ✗ (e_1, t_1) := matchType(e,t1,t2,printFailtrace);
3708 ✗ then
3709 (DAE.META_OPTION(SOME(e_1)),DAE.T_METAOPTION(t_1));
3710
3711 case (DAE.META_OPTION(NONE()), _, DAE.T_METAOPTION(t2)) guard Config.acceptMetaModelicaGrammar()
3712 ✗ then
3713 (DAE.META_OPTION(NONE()),DAE.T_METAOPTION(t2));
3714
3715 // MetaModelica Tuple
3716 case (DAE.TUPLE(elist), DAE.T_TUPLE(types = tys1), DAE.T_METATUPLE(tys2)) guard Config.acceptMetaModelicaGrammar()
3717 algorithm
3718 18 tys2 := List.map(tys2, boxIfUnboxedType);
3719 18 (elist_1,tys_1) := matchTypeTuple(elist, tys1, tys2, printFailtrace);
3720 18 then
3721 (DAE.META_TUPLE(elist_1),DAE.T_METATUPLE(tys_1));
3722
3723 case (DAE.MATCHEXPRESSION(matchTy,inputs,aliases,localDecls,cases,et), _, _)
3724 algorithm
3725
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 true := Config.acceptMetaModelicaGrammar();
3726 3 elist := resultExps(cases);
3727 3 (elist_1,_) := matchTypeList(elist, actual, expected, printFailtrace);
3728 3 cases:=fixCaseReturnTypes2(cases,elist_1,Absyn.dummyInfo);
3729 3 et:=simplifyType(expected);
3730 3 then
3731 (DAE.MATCHEXPRESSION(matchTy,inputs,aliases,localDecls,cases,et),expected);
3732
3733 case (DAE.META_TUPLE(elist), DAE.T_METATUPLE(types = tys1), DAE.T_METATUPLE(tys2))
3734 algorithm
3735 ✗ tys2 := List.map(tys2, boxIfUnboxedType);
3736 ✗ (elist_1,tys_1) := matchTypeTuple(elist, tys1, tys2, printFailtrace);
3737 ✗ then
3738 (DAE.META_TUPLE(elist_1),DAE.T_METATUPLE(tys_1));
3739
3740 case (DAE.TUPLE(elist), DAE.T_TUPLE(types = tys1), ty2 as DAE.T_METABOXED(ty = DAE.T_UNKNOWN()))
3741 algorithm
3742 ✗ true := Config.acceptMetaModelicaGrammar();
3743 ✗ tys2 := List.fill(ty2, listLength(tys1));
3744 ✗ (elist_1,tys_1) := matchTypeTuple(elist, tys1, tys2, printFailtrace);
3745 ✗ then
3746 (DAE.META_TUPLE(elist_1),DAE.T_METATUPLE(tys_1));
3747
3748 // The automatic type conversion will convert any array that can be
3749 // const-eval'ed to an DAE.ARRAY or DAE.MATRIX into a list of the same
3750 // type. The reason is that the syntax for the array and list constructor
3751 // is the same. However, the compiler can't distinguish between the two
3752 // cases below because a is expanded earlier in the compilation process:
3753 // Integer[3] a;
3754 // someListFunction(a); // Is expanded to the line below
3755 // someListFunction({a[1],a[2],a[3]});
3756 // / sjoelund 2009-08-13
3757 case (DAE.ARRAY(DAE.T_ARRAY(),_,elist), DAE.T_ARRAY(ty=t1), DAE.T_METALIST(t2))
3758 algorithm
3759
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
43 true := Config.acceptMetaModelicaGrammar();
3760 43 t2 := boxIfUnboxedType(t2);
3761 43 (elist_1, _) := matchTypeList(elist, t1, t2, printFailtrace);
3762 43 e_1 := DAE.LIST(elist_1);
3763 43 t2 := DAE.T_METALIST(t2);
3764 43 then (e_1, t2);
3765
3766 case (DAE.ARRAY(DAE.T_ARRAY(),_,elist), DAE.T_ARRAY(ty=t1), DAE.T_METABOXED(t2))
3767 algorithm
3768
2/2
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 21 times.
176 true := Config.acceptMetaModelicaGrammar();
3769 21 (elist_1, tys1) := matchTypeList(elist, t1, t2, printFailtrace);
3770 21 (elist_1, t2) := listMatchSuperType(elist_1, tys1, printFailtrace);
3771 21 t2 := boxIfUnboxedType(t2);
3772 21 (elist_1, _) := matchTypeList(elist_1, t1, t2, printFailtrace);
3773 21 e_1 := DAE.LIST(elist_1);
3774 21 t2 := DAE.T_METALIST(t2);
3775 21 then (e_1, t2);
3776
3777 case (DAE.MATRIX(DAE.T_ARRAY(),_,elist_big), t1, t2)
3778 algorithm
3779
2/2
✓ Branch 1 taken 37283 times.
✓ Branch 2 taken 12 times.
37295 true := Config.acceptMetaModelicaGrammar();
3780 12 (elist,ty2) := typeConvertMatrixToList(elist_big,t1,t2,printFailtrace);
3781 12 e_1 := DAE.LIST(elist);
3782 12 then (e_1,ty2);
3783
3784 case (DAE.LIST(elist), DAE.T_METALIST(ty = t1), DAE.T_METALIST(t2))
3785 algorithm
3786 ✗ true := Config.acceptMetaModelicaGrammar();
3787 ✗ (elist_1, tys1) := matchTypeList(elist, t1, t2, printFailtrace);
3788 ✗ (elist_1, t2) := listMatchSuperType(elist_1, tys1, printFailtrace);
3789 ✗ e_1 := DAE.LIST(elist_1);
3790 ✗ t2 := DAE.T_METALIST(t2);
3791 ✗ then (e_1, t2);
3792
3793 case (e, t1 as DAE.T_INTEGER(), DAE.T_METABOXED(ty = t2))
3794 algorithm
3795 20518 (e,t1) := matchType(e,t1,unboxedType(t2),printFailtrace);
3796 20518 t2 := DAE.T_METABOXED(t1);
3797 20518 e := Expression.boxExp(e);
3798 20518 then (e,t2);
3799
3800 case (e, t1 as DAE.T_BOOL(), DAE.T_METABOXED(ty = t2))
3801 algorithm
3802 13836 (e,t1) := matchType(e,t1,unboxedType(t2),printFailtrace);
3803 13836 t2 := DAE.T_METABOXED(t1);
3804 13836 e := Expression.boxExp(e);
3805 13836 then (e,t2);
3806
3807 case (e, t1 as DAE.T_REAL(), DAE.T_METABOXED(ty = t2))
3808 algorithm
3809 866 (e,t1) := matchType(e,t1,unboxedType(t2),printFailtrace);
3810 866 t2 := DAE.T_METABOXED(t1);
3811 866 e := Expression.boxExp(e);
3812 866 then (e,t2);
3813
3814 case (e, t1 as DAE.T_ENUMERATION(), DAE.T_METABOXED(ty = t2))
3815 algorithm
3816 964 (e, t1) := matchType(e, t1, unboxedType(t2), printFailtrace);
3817 964 t2 := DAE.T_METABOXED(t1);
3818 964 e := Expression.boxExp(e);
3819 964 then
3820 (e, t2);
3821
3822 case (e, t1 as DAE.T_ARRAY(), DAE.T_METABOXED(ty = t2))
3823 algorithm
3824 162 (e, t1) := matchType(e, t1, unboxedType(t2), printFailtrace);
3825 162 t2 := DAE.T_METABOXED(t1);
3826 162 e := Expression.boxExp(e);
3827 162 then
3828 (e, t2);
3829
3830 case (DAE.CALL(path = path1, expLst = elist), t1 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path2), varLst = v), DAE.T_METABOXED(ty = t2))
3831 algorithm
3832
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 true := subtype(t1,t2);
3833
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 true := AbsynUtil.pathEqual(path1, path2);
3834 2 t2 := DAE.T_METABOXED(t1);
3835 2 l := List.map(v, TypesDump.getVarName);
3836 2 tys1 := List.map(v, getVarType);
3837 2 tys2 := List.map(tys1, boxIfUnboxedType);
3838 2 (elist,_) := matchTypeTuple(elist, tys1, tys2, printFailtrace);
3839 2 e_1 := DAE.METARECORDCALL(path1, elist, l, -1, {});
3840 2 then (e_1,t2);
3841
3842 case (DAE.RECORD(path = path1, exps = elist), t1 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path2), varLst = v), DAE.T_METABOXED(ty = t2))
3843 algorithm
3844
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 true := subtype(t1,t2);
3845
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 true := AbsynUtil.pathEqual(path1, path2);
3846 8 t2 := DAE.T_METABOXED(t1);
3847 8 l := List.map(v, TypesDump.getVarName);
3848 8 tys1 := List.map(v, getVarType);
3849 8 tys2 := List.map(tys1, boxIfUnboxedType);
3850 8 (elist,_) := matchTypeTuple(elist, tys1, tys2, printFailtrace);
3851 8 e_1 := DAE.METARECORDCALL(path1, elist, l, -1, {});
3852 8 then (e_1,t2);
3853
3854 case (DAE.CREF(cref,_), t1 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path), varLst = v), DAE.T_METABOXED(ty = t2))
3855 algorithm
3856
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
21 true := subtype(t1,t2);
3857 21 t2 := DAE.T_METABOXED(t1);
3858 21 l := List.map(v, TypesDump.getVarName);
3859 21 tys1 := List.map(v, getVarType);
3860 21 tys2 := List.map(tys1, boxIfUnboxedType);
3861 21 expTypes := List.map(tys1, simplifyType);
3862 21 pathList := List.map(l, AbsynUtil.makeIdentPathFromString);
3863 21 crefList := List.map(pathList, ComponentReference.pathToCref);
3864 21 crefList := List.map1r(crefList, ComponentReference.joinCrefs, cref);
3865 21 elist := List.threadMap(crefList, expTypes, Expression.makeCrefExp);
3866 21 (elist,_) := matchTypeTuple(elist, tys1, tys2, printFailtrace);
3867 21 e_1 := DAE.METARECORDCALL(path, elist, l, -1, {});
3868 21 then (e_1,t2);
3869
3870 case (e, DAE.T_COMPLEX(complexClassType = ClassInf.RECORD()), DAE.T_METABOXED())
3871 algorithm
3872 ✗ true := Flags.isSet(Flags.FAILTRACE);
3873 ✗ Debug.trace("- Not yet implemented: Converting record into boxed records: "+ExpressionBasics.printExpStr(e)+"\n");
3874 ✗ then
3875 fail();
3876
3877 case (DAE.BOX(e), DAE.T_METABOXED(ty = t1), t2)
3878 algorithm
3879
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 511 times.
511 true := subtype(t1,t2);
3880 511 (e_1,t2) := matchType(e,t1,t2,printFailtrace);
3881 then (e_1,t2);
3882
3883 case (e, DAE.T_METABOXED(ty = t1), t2 as DAE.T_INTEGER())
3884 algorithm
3885
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 162 times.
177 true := subtype(t1,t2);
3886 162 matchType(e,t1,t2,printFailtrace);
3887 162 t := simplifyType(t2);
3888 162 then (DAE.UNBOX(e,t),t2);
3889
3890 case (e, DAE.T_METABOXED(ty = t1), t2 as DAE.T_REAL())
3891 algorithm
3892
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
68 true := subtype(t1,t2);
3893 68 matchType(e,t1,t2,printFailtrace);
3894 68 t := simplifyType(t2);
3895 68 then (DAE.UNBOX(e,t),t2);
3896
3897 case (e, DAE.T_METABOXED(ty = t1), t2 as DAE.T_BOOL())
3898 algorithm
3899
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 74 times.
74 true := subtype(t1,t2);
3900 74 matchType(e,t1,t2,printFailtrace);
3901 74 t := simplifyType(t2);
3902 74 then (DAE.UNBOX(e,t),t2);
3903
3904 case (e, DAE.T_METABOXED(ty = t1), t2 as DAE.T_ENUMERATION())
3905 algorithm
3906
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 true := subtype(t1, t2);
3907 ✗ matchType(e, t1, t2, printFailtrace);
3908 ✗ t := simplifyType(t2);
3909 ✗ then
3910 (DAE.UNBOX(e, t), t2);
3911
3912 case (e, DAE.T_METABOXED(ty = t1), t2 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)))
3913 algorithm
3914
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 true := subtype(t1,t2);
3915 2 (e_1,_) := matchType(e,t1,t2,printFailtrace);
3916 2 t := simplifyType(t2);
3917 2 then
3918 (DAE.CALL(Absyn.IDENT("mmc_unbox_record"),{e_1},DAE.CALL_ATTR(t,false,true,false,false,DAE.NO_INLINE(),DAE.NO_TAIL(),DAE.NoReturn.RETURNS)),t2);
3919
3920 end matchcontinue;
3921 end typeConvert;
3922
3923 protected function liftExpType "help function to typeConvert. Changes the DAE.Type stored
3924 in expression (which is typically a CAST) by adding a dimension to it, making it into an array
3925 type."
3926 input DAE.Exp ie;
3927 input DAE.Dimension dim;
3928 output DAE.Exp res;
3929 algorithm
3930 res := match ie
3931 local DAE.Type ty,ty1; DAE.Exp e;
3932 case DAE.CAST(ty,e)
3933 algorithm
3934 339 ty1 := Expression.liftArrayR(ty,dim);
3935 339 then DAE.CAST(ty1,e);
3936
3937 case e then e;
3938 end match;
3939 end liftExpType;
3940
3941 public function typeConvertArray
3942 "Calls typeConvert on a list of expressions."
3943 input list<DAE.Exp> inArray;
3944 input DAE.Type inActualType;
3945 input DAE.Type inExpectedType;
3946 input Boolean inPrintFailtrace;
3947 output list<DAE.Exp> outArray;
3948 algorithm
3949 outArray := match inArray
3950 local
3951 DAE.Exp e;
3952 list<DAE.Exp> expl;
3953
3954 // Empty array. Create a dummy expression and try to type convert that, to
3955 // make sure that empty arrays are type checked.
3956 case {}
3957 algorithm
3958 3496 e := makeDummyExpFromType(inActualType);
3959 3496 typeConvert(e, inActualType, inExpectedType, inPrintFailtrace);
3960 then
3961 {};
3962
3963 else
3964 algorithm
3965
2/2
✓ Branch 0 taken 70852 times.
✓ Branch 1 taken 5334 times.
147038 expl := List.map_2(inArray, function typeConvert(actual = inActualType, expected = inExpectedType, printFailtrace = inPrintFailtrace));
3966 then
3967 expl;
3968
3969 end match;
3970 end typeConvertArray;
3971
3972 protected function typeConvertMatrix "
3973 Helper function to type_convert. Handles matrix expressions.
3974 "
3975 input list<list<DAE.Exp>> inMatrix;
3976 input DAE.Type inActualType;
3977 input DAE.Type inExpectedType;
3978 input Boolean printFailtrace;
3979 output list<list<DAE.Exp>> outMatrix;
3980 algorithm
3981
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 30 times.
240 outMatrix := List.map3(inMatrix, typeConvertArray, inActualType,
3982 inExpectedType, printFailtrace);
3983 end typeConvertMatrix;
3984
3985 protected function typeConvertList "
3986 Helper function to type_convert.
3987 "
3988 input list<DAE.Exp> inExpExpLst1;
3989 input list<DAE.Type> inTypeLst2;
3990 input list<DAE.Type> inTypeLst3;
3991 input Boolean printFailtrace;
3992 output list<DAE.Exp> outExpExpLst;
3993 output list<DAE.Type> outTypeLst;
3994 algorithm
3995 (outExpExpLst,outTypeLst):=
3996 match (inExpExpLst1, inTypeLst2, inTypeLst3)
3997 local
3998 list<DAE.Exp> rest_1,rest;
3999 list<DAE.Type> tyrest_1,ty1rest,ty2rest;
4000 DAE.Exp first_1,first;
4001 Type ty_1,ty1,ty2;
4002 case ({}, _, _) then ({},{});
4003 case ((first :: rest), (ty1 :: ty1rest), (ty2 :: ty2rest))
4004 algorithm
4005 ✗ (rest_1,tyrest_1) := typeConvertList(rest, ty1rest, ty2rest,printFailtrace);
4006 ✗ (first_1,ty_1) := typeConvert(first, ty1, ty2, printFailtrace);
4007 ✗ then
4008 ((first_1 :: rest_1),(ty_1 :: tyrest_1));
4009 end match;
4010 end typeConvertList;
4011
4012 protected function typeConvertMatrixToList
4013 input list<list<DAE.Exp>> melist;
4014 input DAE.Type inType;
4015 input DAE.Type outType;
4016 input Boolean printFailtrace;
4017 output list<DAE.Exp> outExp;
4018 output DAE.Type actualOutType;
4019 algorithm
4020 (outExp,actualOutType) := matchcontinue (melist, inType, outType)
4021 local
4022 list<DAE.Exp> expl;
4023 list<list<DAE.Exp>> rest;
4024 Type t1,t2;
4025 DAE.Exp e;
4026
4027 case ({}, _, _) then ({},DAE.T_UNKNOWN_DEFAULT);
4028 case (expl::rest, DAE.T_ARRAY(ty=DAE.T_ARRAY(ty=t1)), DAE.T_METALIST(ty=DAE.T_METALIST(ty=t2)))
4029 algorithm
4030 24 (e,t1) := typeConvertMatrixRowToList(expl, t1, t2, printFailtrace);
4031 24 (expl,_) := typeConvertMatrixToList(rest, inType, outType, printFailtrace);
4032 24 then (e::expl,DAE.T_METALIST(t1));
4033 else
4034 algorithm
4035 ✗ true := Flags.isSet(Flags.TYPES);
4036 ✗ Debug.trace("- typeConvertMatrixToList failed\n");
4037 ✗ then fail();
4038 end matchcontinue;
4039 end typeConvertMatrixToList;
4040
4041 protected function typeConvertMatrixRowToList
4042 input list<DAE.Exp> elist;
4043 input DAE.Type inType;
4044 input DAE.Type outType;
4045 input Boolean printFailtrace;
4046 output DAE.Exp out;
4047 output DAE.Type t1;
4048 protected
4049 list<DAE.Exp> elist_1;
4050 algorithm
4051
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
24 (elist_1,t1::_) := matchTypeList(elist, inType, outType, printFailtrace);
4052 24 out := DAE.LIST(elist_1);
4053 24 t1 := DAE.T_METALIST(t1);
4054 end typeConvertMatrixRowToList;
4055
4056 public function matchWithPromote "This function is used for matching expressions in matrix construction,
4057 where automatic promotion is allowed. This means that array dimensions of
4058 size one (1) is added from the right to arrays of matrix construction until
4059 all elements have the same dimension size (with a maximum of 2).
4060 For instance, {1,{2}} becomes {1,2}.
4061 The function also has a flag indicating that Integer to Real
4062 conversion can be used."
4063 input DAE.Properties inProperties1;
4064 input DAE.Properties inProperties2;
4065 input Boolean inBoolean3;
4066 output DAE.Properties outProperties;
4067 algorithm
4068 outProperties := matchcontinue (inProperties1,inProperties2,inBoolean3)
4069 local
4070 Type t,t1,t2;
4071 Const c,c1,c2;
4072 DAE.Dimension dim,dim1;
4073 Boolean havereal;
4074 list<DAE.Var> v;
4075
4076 case (DAE.PROP(DAE.T_SUBTYPE_BASIC(complexType = t1),c1),DAE.PROP(t2,c2),havereal)
4077 ✗ then matchWithPromote(DAE.PROP(t1,c1),DAE.PROP(t2,c2),havereal);
4078
4079 case (DAE.PROP(t1,c1),DAE.PROP(DAE.T_SUBTYPE_BASIC(complexType = t2),c2),havereal)
4080 ✗ then matchWithPromote(DAE.PROP(t1,c1),DAE.PROP(t2,c2),havereal);
4081
4082 case (DAE.PROP(type_ = DAE.T_ARRAY(dims = {dim1},ty = t1),constFlag = c1),
4083 DAE.PROP(type_ = DAE.T_ARRAY(dims = {_},ty = t2),constFlag = c2),
4084 havereal) // Allow Integer => Real
4085 algorithm
4086
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 9596 times.
9596 DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4087 dim := dim1;
4088 9596 then
4089 DAE.PROP(DAE.T_ARRAY(t,{dim}),c);
4090
4091 // match integer, second
4092 case (DAE.PROP(type_ = t1,constFlag = c1),
4093 DAE.PROP(type_ = DAE.T_ARRAY(dims = {DAE.DIM_INTEGER(1)},ty = t2),constFlag = c2),
4094 havereal)
4095 algorithm
4096 ✗ false := isArray(t1);
4097 ✗ DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4098 ✗ then
4099 DAE.PROP(DAE.T_ARRAY(t, {DAE.DIM_INTEGER(1)}),c);
4100 // match enum, second
4101 case (DAE.PROP(type_ = t1,constFlag = c1),
4102 DAE.PROP(type_ = DAE.T_ARRAY(dims = {dim as DAE.DIM_ENUM(size=1)},ty = t2),constFlag = c2),
4103 havereal)
4104 algorithm
4105 ✗ false := isArray(t1);
4106 ✗ DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4107 ✗ then
4108 DAE.PROP(DAE.T_ARRAY(t,{dim}),c);
4109 // match boolean, second
4110 case (DAE.PROP(type_ = t1,constFlag = c1),
4111 DAE.PROP(type_ = DAE.T_ARRAY(dims = {dim as DAE.DIM_BOOLEAN()},ty = t2),constFlag = c2),
4112 havereal)
4113 algorithm
4114 ✗ false := isArray(t1);
4115 ✗ DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4116 ✗ then
4117 DAE.PROP(DAE.T_ARRAY(t,{dim}),c);
4118 // match integer, first
4119 case (DAE.PROP(type_ = DAE.T_ARRAY(dims = {DAE.DIM_INTEGER(1)},ty = t1),constFlag = c1),
4120 DAE.PROP(type_ = t2,constFlag = c2),havereal)
4121 algorithm
4122 ✗ false := isArray(t2);
4123 ✗ DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4124 ✗ then
4125 DAE.PROP(DAE.T_ARRAY(t,{DAE.DIM_INTEGER(1)}),c);
4126 // match enum, first
4127 case (DAE.PROP(type_ = DAE.T_ARRAY(dims = {dim as DAE.DIM_ENUM(size=1)},ty = t1),constFlag = c1),
4128 DAE.PROP(type_ = t2,constFlag = c2),havereal)
4129 algorithm
4130 ✗ false := isArray(t2);
4131 ✗ DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4132 ✗ then
4133 DAE.PROP(DAE.T_ARRAY(t,{dim}),c);
4134 // match boolean, first
4135 case (DAE.PROP(type_ = DAE.T_ARRAY(dims = {dim as DAE.DIM_BOOLEAN()},ty = t1),constFlag = c1),
4136 DAE.PROP(type_ = t2,constFlag = c2),havereal)
4137 algorithm
4138 ✗ false := isArray(t2);
4139 ✗ DAE.PROP(t,c) := matchWithPromote(DAE.PROP(t1,c1), DAE.PROP(t2,c2), havereal);
4140 ✗ then
4141 DAE.PROP(DAE.T_ARRAY(t,{dim}),c);
4142 // equal types
4143 case (DAE.PROP(type_ = t1,constFlag = c1),
4144 DAE.PROP(type_ = t2,constFlag = c2),false)
4145 algorithm
4146
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2486 times.
2486 false := isArray(t1);
4147
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2486 times.
2486 false := isArray(t2);
4148
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2486 times.
2486 true := equivtypes(t1,t2);
4149 2486 c := constAnd(c1, c2);
4150 2486 then
4151 DAE.PROP(t1,c);
4152 // enums
4153 case (DAE.PROP(type_ = t as DAE.T_ENUMERATION(),constFlag = c1),
4154 DAE.PROP(type_ = DAE.T_ENUMERATION(),constFlag = c2), false)
4155 algorithm
4156 ✗ c := constAnd(c1, c2) "Have enum and both Enum" ;
4157 ✗ then
4158 DAE.PROP(t,c);
4159 // reals
4160 case (DAE.PROP(type_ = DAE.T_REAL(varLst = v),constFlag = c1),
4161 DAE.PROP(type_ = DAE.T_REAL(),constFlag = c2),true)
4162 algorithm
4163 2312 c := constAnd(c1, c2) "Have real and both Real" ;
4164 2312 then
4165 DAE.PROP(DAE.T_REAL(v),c);
4166 // integer vs. real
4167 case (DAE.PROP(type_ = DAE.T_INTEGER(),constFlag = c1),
4168 DAE.PROP(type_ = DAE.T_REAL(varLst = v),constFlag = c2),true)
4169 algorithm
4170 ✗ c := constAnd(c1, c2) "Have real and first Integer" ;
4171 ✗ then
4172 DAE.PROP(DAE.T_REAL(v),c);
4173 // real vs. integer
4174 case (DAE.PROP(type_ = DAE.T_REAL(varLst = v),constFlag = c1),
4175 DAE.PROP(type_ = DAE.T_INTEGER(),constFlag = c2),true)
4176 algorithm
4177 ✗ c := constAnd(c1, c2) "Have real and second Integer" ;
4178 ✗ then
4179 DAE.PROP(DAE.T_REAL(v),c);
4180 // both integers
4181 case (DAE.PROP(type_ = DAE.T_INTEGER(),constFlag = c1),
4182 DAE.PROP(type_ = DAE.T_INTEGER(),constFlag = c2),true)
4183 algorithm
4184 ✗ c := constAnd(c1, c2) "Have real and both Integer" ;
4185 ✗ then
4186 DAE.PROP(DAE.T_REAL_DEFAULT,c);
4187
4188 else
4189 algorithm
4190 ✗ true := Flags.isSet(Flags.FAILTRACE);
4191 ✗ Debug.traceln("- Types.matchWithPromote failed on: " +
4192 "\nprop1: " + printPropStr(inProperties1) +
4193 "\nprop2: " + printPropStr(inProperties2) +
4194 "\nhaveReal: " + boolString(inBoolean3));
4195 ✗ then fail();
4196 end matchcontinue;
4197 end matchWithPromote;
4198
4199 public function constAnd "Returns the *and* operator of two Consts.
4200 I.e. C_CONST iff. both are C_CONST,
4201 C_PARAM iff both are C_PARAM (or one of them C_CONST),
4202 V_VAR otherwise."
4203 input DAE.Const inConst1;
4204 input DAE.Const inConst2;
4205 output DAE.Const outConst;
4206 algorithm
4207 outConst := match(inConst1,inConst2)
4208 case (DAE.C_CONST(),DAE.C_CONST()) then DAE.C_CONST();
4209 case (DAE.C_CONST(),DAE.C_PARAM()) then DAE.C_PARAM();
4210 case (DAE.C_PARAM(),DAE.C_CONST()) then DAE.C_PARAM();
4211 case (DAE.C_PARAM(),DAE.C_PARAM()) then DAE.C_PARAM();
4212 case (DAE.C_UNKNOWN(), _) then DAE.C_UNKNOWN();
4213 case (_, DAE.C_UNKNOWN()) then DAE.C_UNKNOWN();
4214 else DAE.C_VAR();
4215 end match;
4216 end constAnd;
4217
4218 protected function constTupleAnd "Returns the *and* operator of two TupleConsts
4219 For now, returns first tuple."
4220 input DAE.TupleConst inTupleConst1;
4221 input DAE.TupleConst inTupleConst2;
4222 output DAE.TupleConst outTupleConst;
4223 algorithm
4224 outTupleConst := match inTupleConst1
4225 local TupleConst c1;
4226 case c1 then c1;
4227 end match;
4228 end constTupleAnd;
4229
4230 public function constOr "Returns the *or* operator of two Const's.
4231 I.e. C_CONST if some is C_CONST,
4232 C_PARAM if none is C_CONST but some is C_PARAM and
4233 V_VAR otherwise."
4234 input DAE.Const inConst1;
4235 input DAE.Const inConst2;
4236 output DAE.Const outConst;
4237 algorithm
4238 outConst := match (inConst1,inConst2)
4239 case (DAE.C_CONST(),_) then DAE.C_CONST();
4240 case (_,DAE.C_CONST()) then DAE.C_CONST();
4241 case (DAE.C_PARAM(),_) then DAE.C_PARAM();
4242 case (_,DAE.C_PARAM()) then DAE.C_PARAM();
4243 case (DAE.C_UNKNOWN(),_) then DAE.C_UNKNOWN();
4244 case (_, DAE.C_UNKNOWN()) then DAE.C_UNKNOWN();
4245 else DAE.C_VAR();
4246 end match;
4247 end constOr;
4248
4249 public function boolConst "author: PA
4250 Creates a Const value from a bool.
4251 if true, C_CONST,
4252 if false C_VAR
4253 There is no way to create a C_PARAM using this function."
4254 input Boolean inBoolean;
4255 output DAE.Const outConst;
4256 algorithm
4257 ✗ outConst := match inBoolean
4258 case false then DAE.C_VAR();
4259 case true then DAE.C_CONST();
4260 end match;
4261 end boolConst;
4262
4263 public function boolConstSize "author: alleb
4264 A version of boolConst supposed to be used by Static.elabBuiltinSize.
4265 Creates a Const value from a bool. If true, C_CONST, if false C_PARAM."
4266 input Boolean inBoolean;
4267 output DAE.Const outConst;
4268 algorithm
4269
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 outConst := match inBoolean
4270 case false then DAE.C_PARAM();
4271 case true then DAE.C_CONST();
4272 end match;
4273 end boolConstSize;
4274
4275 public function constEqualOrHigher
4276 input DAE.Const c1;
4277 input DAE.Const c2;
4278 output Boolean b;
4279 algorithm
4280 b := match (c1, c2)
4281 case (DAE.C_CONST(), _) then true;
4282 case (_, DAE.C_CONST()) then false;
4283 case (DAE.C_PARAM(), _) then true;
4284 case (_, DAE.C_PARAM()) then false;
4285 else true;
4286 end match;
4287 end constEqualOrHigher;
4288
4289 public function constEqual
4290 input DAE.Const c1;
4291 input DAE.Const c2;
4292 output Boolean b;
4293 algorithm
4294 2153477 b := valueEq(c1,c2);
4295 end constEqual;
4296
4297 public function constIsVariable
4298 "Returns true if Const is C_VAR."
4299 input DAE.Const c;
4300 output Boolean b;
4301 algorithm
4302 1079270 b := constEqual(c, DAE.C_VAR());
4303 end constIsVariable;
4304
4305 public function constIsParameter
4306 "Returns true if Const is C_PARAM."
4307 input DAE.Const c;
4308 output Boolean b;
4309 algorithm
4310 ✗ b := constEqual(c, DAE.C_PARAM());
4311 end constIsParameter;
4312
4313 public function constIsConst
4314 "Returns true if Const is C_CONST."
4315 input DAE.Const c;
4316 output Boolean b;
4317 algorithm
4318 1074207 b := constEqual(c, DAE.C_CONST());
4319 end constIsConst;
4320
4321 public function printPropStr "Print the properties to a string."
4322 input DAE.Properties inProperties;
4323 output String outString;
4324 algorithm
4325 outString := match inProperties
4326 local
4327 String ty_str,const_str,res;
4328 DAE.Type ty;
4329 DAE.Const const;
4330 DAE.TupleConst tconst;
4331 case DAE.PROP(type_ = ty,constFlag = const)
4332 algorithm
4333 ✗ ty_str := TypesDump.unparseType(ty);
4334 ✗ const_str := TypesDump.printConstStr(const);
4335 ✗ res := stringAppendList({"DAE.PROP(",ty_str,", ",const_str,")"});
4336 then
4337 res;
4338 case DAE.PROP_TUPLE(type_ = ty,tupleConst = tconst)
4339 algorithm
4340 ✗ ty_str := TypesDump.unparseType(ty);
4341 ✗ const_str := TypesDump.printTupleConstStr(tconst);
4342 ✗ res := stringAppendList({"DAE.PROP_TUPLE(",ty_str,", ",const_str,")"});
4343 then
4344 res;
4345 end match;
4346 end printPropStr;
4347
4348 public function printProp "Print the Properties to the Print buffer."
4349 input DAE.Properties p;
4350 protected
4351 String str;
4352 algorithm
4353 ✗ str := printPropStr(p);
4354 ✗ Print.printErrorBuf(str);
4355 end printProp;
4356
4357 public function flowVariables "This function retrieves all variables names that are flow variables, and
4358 prepends the prefix given as an DAE.ComponentRef"
4359 input list<DAE.Var> inVarLst;
4360 input DAE.ComponentRef inComponentRef;
4361 output list<DAE.ComponentRef> outExpComponentRefLst;
4362 algorithm
4363 outExpComponentRefLst:=
4364 matchcontinue (inVarLst,inComponentRef)
4365 local
4366 DAE.ComponentRef cr_1,cr;
4367 list<DAE.ComponentRef> res;
4368 String id;
4369 list<DAE.Var> vs;
4370 DAE.Type ty2,ty;
4371
4372 // handle empty case
4373 case ({},_) then {};
4374
4375 // we have a flow prefix
4376 case ((DAE.TYPES_VAR(name = id,attributes = DAE.ATTR(connectorType = DAE.FLOW()),ty = ty) :: vs),cr)
4377 algorithm
4378 ✗ ty2 := simplifyType(ty);
4379 ✗ cr_1 := ComponentReference.crefPrependIdent(cr, id,{},ty2);
4380 // print("\n created: " + ComponentReference.debugPrintComponentRefTypeStr(cr_1) + "\n");
4381 ✗ res := flowVariables(vs, cr);
4382 then
4383 (cr_1 :: res);
4384
4385 // handle the rest
4386 case ((_ :: vs),cr)
4387 algorithm
4388 ✗ res := flowVariables(vs, cr);
4389 then
4390 res;
4391 end matchcontinue;
4392 end flowVariables;
4393
4394 public function streamVariables "This function retrieves all variables names that are stream variables,
4395 and prepends the prefix given as an DAE.ComponentRef"
4396 input list<DAE.Var> inVarLst;
4397 input DAE.ComponentRef inComponentRef;
4398 output list<DAE.ComponentRef> outExpComponentRefLst;
4399 algorithm
4400 outExpComponentRefLst:=
4401 matchcontinue (inVarLst,inComponentRef)
4402 local
4403 DAE.ComponentRef cr_1,cr;
4404 list<DAE.ComponentRef> res;
4405 String id;
4406 list<DAE.Var> vs;
4407 DAE.Type ty2,ty;
4408
4409 case ({},_) then {};
4410 case ((DAE.TYPES_VAR(name = id,attributes = DAE.ATTR(connectorType = DAE.STREAM()),ty = ty) :: vs),cr)
4411 algorithm
4412 ✗ ty2 := simplifyType(ty);
4413 ✗ cr_1 := ComponentReference.crefPrependIdent(cr, id, {}, ty2);
4414 ✗ res := streamVariables(vs, cr);
4415 then
4416 (cr_1 :: res);
4417 case ((_ :: vs),cr)
4418 algorithm
4419 ✗ res := streamVariables(vs, cr);
4420 then
4421 res;
4422 end matchcontinue;
4423 end streamVariables;
4424
4425 public function getAllExps "This function goes through the Type structure and finds all the
4426 expressions and returns them in a list"
4427 input DAE.Type inType;
4428 output list<DAE.Exp> outExpExpLst;
4429 algorithm
4430 ✗ outExpExpLst := getAllExpsTt(inType);
4431 end getAllExps;
4432
4433 protected function getAllExpsTt "This function goes through the TType structure and finds all the
4434 expressions and returns them in a list"
4435 input DAE.Type inType;
4436 output list<DAE.Exp> outExpExpLst;
4437 algorithm
4438 outExpExpLst := matchcontinue inType
4439 local
4440 list<DAE.Exp> exps,tyexps;
4441 list<DAE.Var> vars, attrs;
4442 Type ty;
4443 list<DAE.Type> tys;
4444 list<list<DAE.Exp>> explists,explist;
4445 list<DAE.FuncArg> fargs;
4446 Type tty;
4447 String str;
4448
4449 ✗ case DAE.T_INTEGER(varLst = vars) then getAllExpsVars(vars);
4450 ✗ case DAE.T_REAL(varLst = vars) then getAllExpsVars(vars);
4451 ✗ case DAE.T_STRING(varLst = vars) then getAllExpsVars(vars);
4452 ✗ case DAE.T_BOOL(varLst = vars) then getAllExpsVars(vars);
4453 // BTH return empty list for clock since it doesn't have attributes
4454 case DAE.T_CLOCK() then {};
4455 case DAE.T_ENUMERATION(literalVarLst = vars, attributeLst = attrs)
4456 algorithm
4457 ✗ exps := getAllExpsVars(vars);
4458 ✗ tyexps := getAllExpsVars(attrs);
4459 ✗ exps := listAppend(tyexps, exps);
4460 then
4461 exps;
4462 ✗ case DAE.T_ARRAY(ty = ty) then getAllExps(ty);
4463
4464 ✗ case DAE.T_COMPLEX(varLst = vars) then getAllExpsVars(vars);
4465 ✗ case DAE.T_SUBTYPE_BASIC(varLst = vars) then getAllExpsVars(vars);
4466
4467 case DAE.T_FUNCTION(funcArg = fargs,funcResultType = ty)
4468 algorithm
4469 ✗ explists := List.mapMap(fargs, funcArgType, getAllExps);
4470 ✗ tyexps := getAllExps(ty);
4471 ✗ exps := List.flatten((tyexps :: explists));
4472 then
4473 exps;
4474
4475 case DAE.T_TUPLE(types = tys)
4476 algorithm
4477 ✗ explist := List.map(tys, getAllExps);
4478 ✗ exps := List.flatten(explist);
4479 then
4480 exps;
4481
4482 case DAE.T_METATUPLE(types = tys)
4483 algorithm
4484 ✗ exps := getAllExpsTt(DAE.T_TUPLE(tys, NONE()));
4485 then
4486 exps;
4487
4488 case DAE.T_METAUNIONTYPE() then {};
4489
4490 ✗ case DAE.T_METAOPTION(ty = ty) then getAllExps(ty);
4491 ✗ case DAE.T_METALIST(ty = ty) then getAllExps(ty);
4492 ✗ case DAE.T_METAARRAY(ty = ty) then getAllExps(ty);
4493 ✗ case DAE.T_METABOXED(ty = ty) then getAllExps(ty);
4494 case DAE.T_METAPOLYMORPHIC() then {};
4495
4496 case DAE.T_UNKNOWN() then {};
4497 case DAE.T_NORETCALL() then {};
4498
4499 case tty
4500 algorithm
4501 ✗ true := Flags.isSet(Flags.FAILTRACE);
4502 ✗ str := TypesDump.unparseType(tty);
4503 ✗ Debug.traceln("-- Types.getAllExpsTt failed " + str);
4504 ✗ then
4505 fail();
4506 end matchcontinue;
4507 end getAllExpsTt;
4508
4509 protected function getAllExpsVars "Helper function to getAllExpsTt."
4510 input list<DAE.Var> vars;
4511 output list<DAE.Exp> exps;
4512 protected
4513 list<list<DAE.Exp>> explist;
4514 algorithm
4515 ✗ explist := List.map(vars, getAllExpsVar);
4516 ✗ exps := List.flatten(explist);
4517 end getAllExpsVars;
4518
4519 protected function getAllExpsVar "Helper function to getAllExpsVars."
4520 input DAE.Var inVar;
4521 output list<DAE.Exp> outExpExpLst;
4522 algorithm
4523 outExpExpLst := match inVar
4524 local
4525 list<DAE.Exp> tyexps,bndexp,exps;
4526 DAE.Type ty;
4527 DAE.Binding bnd;
4528
4529 case DAE.TYPES_VAR(ty = ty,binding = bnd)
4530 algorithm
4531 ✗ tyexps := getAllExps(ty);
4532 ✗ bndexp := getAllExpsBinding(bnd);
4533 ✗ exps := listAppend(tyexps, bndexp);
4534 then
4535 exps;
4536 end match;
4537 end getAllExpsVar;
4538
4539 protected function getAllExpsBinding "Helper function to get_all_exps_var."
4540 input DAE.Binding inBinding;
4541 output list<DAE.Exp> outExpExpLst;
4542 algorithm
4543 outExpExpLst := match inBinding
4544 local
4545 DAE.Exp exp;
4546 case DAE.EQBOUND(exp = exp) then {exp};
4547 case DAE.UNBOUND() then {};
4548 case DAE.VALBOUND() then {};
4549 else
4550 algorithm
4551 ✗ true := Flags.isSet(Flags.FAILTRACE);
4552 ✗ Debug.trace("-- Types.getAllExpsBinding failed\n");
4553 ✗ then
4554 fail();
4555 end match;
4556 end getAllExpsBinding;
4557
4558 public function isBoxedType
4559 input DAE.Type ty;
4560 output Boolean b;
4561 algorithm
4562 b := match ty
4563 case DAE.T_STRING() then true;
4564 case DAE.T_METAOPTION() then true;
4565 case DAE.T_METALIST() then true;
4566 case DAE.T_METATUPLE() then true;
4567 case DAE.T_METAUNIONTYPE() then true;
4568 case DAE.T_METARECORD() then true;
4569 case DAE.T_METAPOLYMORPHIC() then true;
4570 case DAE.T_METAARRAY() then true;
4571 case DAE.T_FUNCTION() then true;
4572 case DAE.T_METABOXED() then true;
4573 case DAE.T_ANYTYPE() then true;
4574 case DAE.T_UNKNOWN() then true;
4575 case DAE.T_METATYPE() then true;
4576 case DAE.T_NORETCALL() then true;
4577 case DAE.T_CODE() then true;
4578 case DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) then true;
4579 else false;
4580 end match;
4581 end isBoxedType;
4582
4583 public function isMetaBoxedType
4584 input DAE.Type inType;
4585 output Boolean outIsMetaBoxed;
4586 algorithm
4587 outIsMetaBoxed := match inType
4588 case DAE.T_METABOXED() then true;
4589 else false;
4590 end match;
4591 end isMetaBoxedType;
4592
4593 public function boxIfUnboxedType
4594 input DAE.Type ty;
4595 output DAE.Type outType;
4596 algorithm
4597 outType := matchcontinue ty
4598 local
4599 list<DAE.Type> tys;
4600
4601 case DAE.T_TUPLE()
4602 algorithm
4603 699 tys := List.map(ty.types, boxIfUnboxedType);
4604 699 then DAE.T_METATUPLE(tys); // TODO?! should now propagate the type source?
4605
4606
2/2
✓ Branch 1 taken 50227 times.
✓ Branch 2 taken 395433 times.
445660 else if isBoxedType(ty) then ty else DAE.T_METABOXED(ty);
4607
4608 end matchcontinue;
4609 end boxIfUnboxedType;
4610
4611 public function unboxedType
4612 input DAE.Type ity;
4613 output DAE.Type out;
4614 algorithm
4615 out := match ity
4616 local
4617 list<DAE.Type> tys;
4618 Type t, ty;
4619
4620 5932 case DAE.T_METABOXED() then unboxedType(ity.ty);
4621
4622 case DAE.T_METAOPTION()
4623 algorithm
4624 641 ty := unboxedType(ity.ty);
4625 641 ty := boxIfUnboxedType(ty);
4626 641 then DAE.T_METAOPTION(ty);
4627
4628 case DAE.T_METALIST()
4629 algorithm
4630 2923 ty := unboxedType(ity.ty);
4631 2923 ty := boxIfUnboxedType(ty);
4632 2923 then
4633 DAE.T_METALIST(ty);
4634
4635 case DAE.T_METATUPLE()
4636 algorithm
4637 2672 tys := List.mapMap(ity.types, unboxedType, boxIfUnboxedType);
4638 2672 then
4639 DAE.T_METATUPLE(tys);
4640
4641 case DAE.T_METAARRAY()
4642 algorithm
4643 81 ty := unboxedType(ity.ty);
4644 81 ty := boxIfUnboxedType(ty);
4645 81 then DAE.T_METAARRAY(ty);
4646
4647 case t as DAE.T_ARRAY()
4648 algorithm
4649 790 t.ty := unboxedType(t.ty);
4650 then t;
4651
4652 else ity;
4653 end match;
4654 end unboxedType;
4655
4656 public function listMatchSuperType "Takes lists of Exp,Type and calculates the
4657 supertype of the list, then converts the expressions to this type.
4658 "
4659 input list<DAE.Exp> ielist;
4660 input list<DAE.Type> typeList;
4661 input Boolean printFailtrace;
4662 output list<DAE.Exp> out;
4663 output DAE.Type t;
4664 algorithm
4665 (out,t) := matchcontinue (ielist, typeList)
4666 local
4667 Type st;
4668 list<DAE.Exp> elist;
4669
4670 case ({}, {}) then ({}, DAE.T_UNKNOWN_DEFAULT);
4671 case (_ :: _, _ :: _)
4672 algorithm
4673 3441 st := List.reduce(typeList, superType);
4674 3441 st := superType(st,st);
4675 3441 st := unboxedType(st);
4676 3441 elist := listMatchSuperType2(ielist,typeList,st,printFailtrace);
4677 then (elist, st);
4678 else
4679 algorithm
4680 ✗ true := Flags.isSet(Flags.FAILTRACE);
4681 ✗ Debug.trace("- Types.listMatchSuperType failed\n");
4682 ✗ then fail();
4683 end matchcontinue;
4684 end listMatchSuperType;
4685
4686 protected function listMatchSuperType2
4687 input list<DAE.Exp> elist;
4688 input list<DAE.Type> typeList;
4689 input DAE.Type st;
4690 input Boolean printFailtrace;
4691 output list<DAE.Exp> out;
4692 algorithm
4693 out := matchcontinue (elist, typeList)
4694 local
4695 DAE.Exp e;
4696 list<DAE.Exp> erest;
4697 Type t;
4698 list<DAE.Type> trest;
4699 String str;
4700 case ({}, {}) then {};
4701 case (e::erest, t::trest)
4702 algorithm
4703 20404 (e,t) := matchType(e,t,st,printFailtrace);
4704 20404 erest := listMatchSuperType2(erest,trest,st,printFailtrace);
4705 then (e::erest);
4706 case (e::_, _)
4707 algorithm
4708 ✗ true := Flags.isSet(Flags.FAILTRACE);
4709 ✗ str := ExpressionBasics.printExpStr(e);
4710 ✗ Debug.traceln("- Types.listMatchSuperType2 failed: " + str);
4711 ✗ then fail();
4712 end matchcontinue;
4713 end listMatchSuperType2;
4714
4715 public function superType "find the supertype of the two types"
4716 input DAE.Type inType1;
4717 input DAE.Type inType2;
4718 output DAE.Type out;
4719 algorithm
4720 out :=
4721 matchcontinue (inType1,inType2)
4722 local
4723 Type t1,t2,tp;
4724 list<DAE.Type> type_list1,type_list2;
4725 Absyn.Path path1,path2;
4726
4727 case (DAE.T_ANYTYPE(),t2) then t2;
4728 case (t1,DAE.T_ANYTYPE()) then t1;
4729 case (DAE.T_UNKNOWN(),t2) then t2;
4730 case (t1,DAE.T_UNKNOWN()) then t1;
4731 case (_,t2 as DAE.T_METAPOLYMORPHIC()) then t2;
4732
4733 case (DAE.T_TUPLE(types = type_list1),DAE.T_TUPLE(types = type_list2))
4734 algorithm
4735 ✗ type_list1 := List.map(type_list1, boxIfUnboxedType);
4736 ✗ type_list2 := List.map(type_list2, boxIfUnboxedType);
4737 ✗ type_list1 := List.threadMap(type_list1,type_list2,superType);
4738 ✗ then DAE.T_METATUPLE(type_list1);
4739
4740 case (DAE.T_TUPLE(types = type_list1),DAE.T_METATUPLE(types = type_list2))
4741 algorithm
4742 ✗ type_list1 := List.map(type_list1, boxIfUnboxedType);
4743 ✗ type_list2 := List.map(type_list2, boxIfUnboxedType);
4744 ✗ type_list1 := List.threadMap(type_list1,type_list2,superType);
4745 ✗ then DAE.T_METATUPLE(type_list1);
4746
4747 case (DAE.T_METATUPLE(types = type_list1),DAE.T_TUPLE(types = type_list2))
4748 algorithm
4749 ✗ type_list1 := List.map(type_list1, boxIfUnboxedType);
4750 ✗ type_list2 := List.map(type_list2, boxIfUnboxedType);
4751 ✗ type_list1 := List.threadMap(type_list1,type_list2,superType);
4752 ✗ then DAE.T_METATUPLE(type_list1);
4753
4754 case (DAE.T_METATUPLE(types = type_list1),DAE.T_METATUPLE(types = type_list2))
4755 algorithm
4756 19639 type_list1 := List.map(type_list1, boxIfUnboxedType);
4757 19639 type_list2 := List.map(type_list2, boxIfUnboxedType);
4758 19639 type_list1 := List.threadMap(type_list1,type_list2,superType);
4759 19639 then DAE.T_METATUPLE(type_list1);
4760
4761 case (DAE.T_METALIST(ty = t1),DAE.T_METALIST(ty = t2))
4762 algorithm
4763 385 t1 := boxIfUnboxedType(t1);
4764 385 t2 := boxIfUnboxedType(t2);
4765 385 tp := superType(t1,t2);
4766 385 then DAE.T_METALIST(tp);
4767
4768 case (DAE.T_METAOPTION(ty = t1), DAE.T_METAOPTION(ty = t2))
4769 algorithm
4770 87 t1 := boxIfUnboxedType(t1);
4771 87 t2 := boxIfUnboxedType(t2);
4772 87 tp := superType(t1,t2);
4773 87 then DAE.T_METAOPTION(tp);
4774
4775 case (DAE.T_METAARRAY(ty = t1), DAE.T_METAARRAY(ty = t2))
4776 algorithm
4777 1 t1 := boxIfUnboxedType(t1);
4778 1 t2 := boxIfUnboxedType(t2);
4779 1 tp := superType(t1,t2);
4780 1 then DAE.T_METAARRAY(tp);
4781
4782 case (t1 as DAE.T_METAUNIONTYPE(path = path1), DAE.T_METARECORD(utPath=path2))
4783 algorithm
4784
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5342 times.
5342 true := AbsynUtil.pathEqual(path1,path2);
4785 then t1;
4786
4787 case (DAE.T_METARECORD(knownSingleton=false,utPath = path1), DAE.T_METARECORD(knownSingleton=false,utPath=path2))
4788 algorithm
4789
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 934 times.
934 true := AbsynUtil.pathEqual(path1,path2);
4790 934 then DAE.T_METAUNIONTYPE({},inType1.typeVars,false,DAE.NOT_SINGLETON(),path1);
4791
4792 case (DAE.T_INTEGER(),DAE.T_REAL())
4793 then DAE.T_REAL_DEFAULT;
4794
4795 case (DAE.T_REAL(),DAE.T_INTEGER())
4796 then DAE.T_REAL_DEFAULT;
4797
4798 case (t1,t2)
4799 algorithm
4800
2/2
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 49804 times.
49866 true := subtype(t1,t2);
4801 then t2;
4802
4803 case (t1,t2)
4804 algorithm
4805
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
62 true := subtype(t2,t1);
4806 then t1;
4807
4808 end matchcontinue;
4809 end superType;
4810
4811 public function matchTypePolymorphic "Like matchType, except we also
4812 bind polymorphic variabled. Used when elaborating calls."
4813 input DAE.Exp iexp;
4814 input DAE.Type iactual;
4815 input DAE.Type expected;
4816 input Option<Absyn.Path> envPath "to detect which polymorphic types are recursive";
4817 input InstTypes.PolymorphicBindings ipolymorphicBindings;
4818 input Boolean printFailtrace;
4819 output DAE.Exp exp=iexp;
4820 output DAE.Type actual=iactual;
4821 output InstTypes.PolymorphicBindings polymorphicBindings=ipolymorphicBindings;
4822 protected
4823 constant Boolean debug=false;
4824 algorithm
4825
2/2
✓ Branch 1 taken 122680 times.
✓ Branch 2 taken 3366 times.
126046 if /*(if not Config.acceptMetaModelicaGrammar() then true else*/ listEmpty(getAllInnerTypesOfType(expected, isPolymorphic)) then
4826 122680 (exp,actual) := matchType(exp,actual,expected,printFailtrace);
4827 else
4828 if debug then print("match type: " + ExpressionBasics.printExpStr(exp) + " of " + TypesDump.unparseType(actual) + " with " + TypesDump.unparseType(expected) + "\n"); end if;
4829 3366 (exp,actual) := matchType(exp,actual,DAE.T_METABOXED(DAE.T_UNKNOWN_DEFAULT), printFailtrace);
4830 if debug then print("matched type: " + ExpressionBasics.printExpStr(exp) + " of " + TypesDump.unparseType(actual) + " with " + TypesDump.unparseType(expected) + " (boxed)\n"); end if;
4831 3358 polymorphicBindings := subtypePolymorphic(getUniontypeIfMetarecordReplaceAllSubtypes(actual), getUniontypeIfMetarecordReplaceAllSubtypes(expected), envPath, polymorphicBindings);
4832 if debug then print("match type: " + ExpressionBasics.printExpStr(exp) + " of " + TypesDump.unparseType(actual) + " with " + TypesDump.unparseType(expected) + " and bindings " + polymorphicBindingsStr(polymorphicBindings) + " (OK)\n"); end if;
4833 end if;
4834 end matchTypePolymorphic;
4835
4836 public function matchTypePolymorphicWithError "Like matchType, except we also
4837 bind polymorphic variabled. Used when elaborating calls."
4838 input DAE.Exp iexp;
4839 input DAE.Type iactual;
4840 input DAE.Type iexpected;
4841 input Option<Absyn.Path> envPath "to detect which polymorphic types are recursive";
4842 input InstTypes.PolymorphicBindings ipolymorphicBindings;
4843 input SourceInfo info;
4844 output DAE.Exp outExp;
4845 output DAE.Type outType;
4846 output InstTypes.PolymorphicBindings outBindings;
4847 algorithm
4848 (outExp,outType,outBindings):=
4849 matchcontinue (iexp, iactual, iexpected, ipolymorphicBindings)
4850 local
4851 DAE.Exp exp;
4852 Type actual,expected;
4853 InstTypes.PolymorphicBindings polymorphicBindings;
4854 String str1,str2,str3;
4855
4856 case (exp, actual, expected, polymorphicBindings)
4857 algorithm
4858 70 (exp,actual,polymorphicBindings) := matchTypePolymorphic(exp,actual,expected,envPath,polymorphicBindings,false);
4859 then (exp,actual,polymorphicBindings);
4860 else
4861 algorithm
4862 ✗ str1 := ExpressionBasics.printExpStr(iexp);
4863 ✗ str2 := TypesDump.unparseType(iactual);
4864 ✗ str3 := TypesDump.unparseType(iexpected);
4865 ✗ Error.addSourceMessage(Error.EXP_TYPE_MISMATCH, {str1,str3,str2}, info);
4866 ✗ then fail();
4867 end matchcontinue;
4868 end matchTypePolymorphicWithError;
4869
4870 public function matchType
4871 "This function matches an expression with an expected type, and converts the
4872 expression to the expected type if necessary."
4873 input DAE.Exp inExp;
4874 input DAE.Type inActualType;
4875 input DAE.Type inExpectedType;
4876 input Boolean inPrintFailtrace=false;
4877 output DAE.Exp outExp;
4878 output DAE.Type outType;
4879 algorithm
4880
2/2
✓ Branch 1 taken 2302600 times.
✓ Branch 2 taken 708267 times.
3010867 if subtype(inExpectedType, inActualType) then
4881 /* TODO: Don't return ANY as type here; use the most restrictive... Else we get issues... */
4882 outExp := inExp;
4883 2302600 outType := inActualType;
4884 else
4885 try
4886
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 708261 times.
708267 false := subtype(inActualType, inExpectedType);
4887 708261 (outExp, outType) := typeConvert(inExp, inActualType, inExpectedType, inPrintFailtrace);
4888 246457 outExp := ExpressionSimplify.simplify1(outExp);
4889 else
4890 461810 printFailure(Flags.TYPES, "matchType", inExp, inActualType, inExpectedType);
4891 461810 fail();
4892 end try;
4893 end if;
4894 end matchType;
4895
4896 public function matchTypeNoFail
4897 input DAE.Exp inExp;
4898 input DAE.Type inActualType;
4899 input DAE.Type inExpectedType;
4900 output DAE.Exp outExp;
4901 output DAE.Type outType;
4902 output Boolean outMatch;
4903 algorithm
4904
2/2
✓ Branch 1 taken 8293 times.
✓ Branch 2 taken 5 times.
8298 if subtype(inExpectedType, inActualType) then
4905 outExp := inExp;
4906 8293 outType := inActualType;
4907 outMatch := true;
4908 else
4909 try
4910 5 (outExp, outType) := typeConvert(inExp, inActualType, inExpectedType, false);
4911 5 outExp := ExpressionSimplify.simplify1(outExp);
4912 outMatch := true;
4913 else
4914 outExp := inExp;
4915 ✗ outType := inActualType;
4916 outMatch := true;
4917 end try;
4918 end if;
4919 end matchTypeNoFail;
4920
4921 public function matchTypes
4922 "matchType, list of actual types, one expected type."
4923 input list<DAE.Exp> iexps;
4924 input list<DAE.Type> itys;
4925 input DAE.Type expected;
4926 input Boolean printFailtrace;
4927 output list<DAE.Exp> outExps;
4928 output list<DAE.Type> outTys;
4929 algorithm
4930 8038 (outExps, outTys) := matchTypes_tail(iexps, itys, expected, printFailtrace, {}, {});
4931 end matchTypes;
4932
4933 protected function matchTypes_tail
4934 input list<DAE.Exp> iexps;
4935 input list<DAE.Type> itys;
4936 input DAE.Type expected;
4937 input Boolean printFailtrace;
4938 input list<DAE.Exp> inAccumExps;
4939 input list<DAE.Type> inAccumTypes;
4940 output list<DAE.Exp> outExps;
4941 output list<DAE.Type> outTys;
4942 algorithm
4943 (outExps, outTys) :=
4944 match(iexps, itys)
4945 local
4946 DAE.Exp e;
4947 list<DAE.Exp> exps;
4948 DAE.Type ty;
4949 list<DAE.Type> tys;
4950
4951 case (e :: exps, ty :: tys)
4952 algorithm
4953 23360 (e, ty) := matchTypes2(e, ty, expected, printFailtrace);
4954 23360 (exps, tys) := matchTypes_tail(exps, tys, expected, printFailtrace,
4955 e :: inAccumExps, ty :: inAccumTypes);
4956 then
4957 (exps, tys);
4958
4959 case ({}, {})
4960 8038 then (listReverse(inAccumExps), listReverse(inAccumTypes));
4961
4962 end match;
4963 end matchTypes_tail;
4964
4965 protected function matchTypes2
4966 input DAE.Exp inExp;
4967 input DAE.Type inType;
4968 input DAE.Type inExpected;
4969 input Boolean inPrintFailtrace;
4970 output DAE.Exp outExp;
4971 output DAE.Type outType;
4972 algorithm
4973 (outExp, outType) := matchcontinue inPrintFailtrace
4974 local
4975 DAE.Exp e;
4976 DAE.Type ty, expected_ty;
4977 String str;
4978
4979 case _
4980 algorithm
4981 23360 ty := getUniontypeIfMetarecordReplaceAllSubtypes(inType);
4982 23360 expected_ty := getUniontypeIfMetarecordReplaceAllSubtypes(inExpected);
4983 23360 (e, ty) := matchType(inExp, ty, expected_ty, inPrintFailtrace);
4984 then
4985 (e, ty);
4986
4987 else
4988 algorithm
4989 ✗ str := "- Types.matchTypes failed for " + ExpressionBasics.printExpStr(inExp)
4990 + " from " + TypesDump.unparseType(inType) + " to " + TypesDump.unparseType(inExpected) + "\n";
4991 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
4992 ✗ then
4993 fail();
4994
4995 end matchcontinue;
4996 end matchTypes2;
4997
4998 protected function printFailure
4999 "@author adrpo
5000 print the message only when flag is on.
5001 this is to speed up the flattening as we don't
5002 generate the strings at all."
5003 input Flags.DebugFlag flag;
5004 input String source;
5005 input DAE.Exp e;
5006 input DAE.Type e_type;
5007 input DAE.Type expected_type;
5008 algorithm
5009
1/2
✓ Branch 1 taken 461810 times.
✗ Branch 2 not taken.
461810 if Flags.isSet(flag) then
5010 ✗ Debug.traceln("- Types." + source + " failed on:" + ExpressionBasics.printExpStr(e));
5011 ✗ Debug.traceln(" type:" + TypesDump.unparseType(e_type) + " differs from expected\n type:" + TypesDump.unparseType(expected_type));
5012 end if;
5013 end printFailure;
5014
5015 protected function polymorphicBindingStr
5016 input tuple<String,list<DAE.Type>> binding;
5017 output String str;
5018 protected
5019 list<DAE.Type> tys;
5020 algorithm
5021 6 (str,tys) := binding;
5022 // Don't bother doing this fast; it's just for error messages
5023 6 str := " " + str + ":\n" + stringDelimitList(List.map1r(List.map(tys, TypesDump.unparseType), stringAppend, " "), "\n");
5024 end polymorphicBindingStr;
5025
5026 public function polymorphicBindingsStr
5027 input InstTypes.PolymorphicBindings bindings;
5028 output String str;
5029 algorithm
5030 9 str := stringDelimitList(List.map(bindings, polymorphicBindingStr), "\n");
5031 end polymorphicBindingsStr;
5032
5033 public function fixPolymorphicRestype
5034 "Uses the polymorphic bindings to determine the result type of the function."
5035 input DAE.Type ty;
5036 input InstTypes.PolymorphicBindings bindings;
5037 input SourceInfo info;
5038 output DAE.Type resType;
5039 algorithm
5040 //print("Trying to fix restype: " + TypesDump.unparseType(ty) + "\n");
5041 112221 resType := fixPolymorphicRestype2(ty,"$",bindings,info);
5042 //print("OK: " + TypesDump.unparseType(resType) + "\n");
5043 end fixPolymorphicRestype;
5044
5045 protected function fixPolymorphicRestype2
5046 input DAE.Type ty;
5047 input String prefix;
5048 input InstTypes.PolymorphicBindings bindings;
5049 input SourceInfo info;
5050 output DAE.Type resType;
5051 algorithm
5052 resType := matchcontinue ty
5053 local
5054 String id,bstr,tstr;
5055 Type t1,t2,ty1;
5056 list<DAE.Type> tys,tys1;
5057 list<DAE.FuncArg> args1;
5058 DAE.FunctionAttributes functionAttributes;
5059 list<Absyn.Path> paths;
5060 Absyn.Path path;
5061 Boolean knownSingleton;
5062 DAE.EvaluateSingletonType singletonType;
5063
5064 case DAE.T_METAPOLYMORPHIC(name = id)
5065 algorithm
5066
2/4
✗ Branch 2 not taken.
✓ Branch 3 taken 5853 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5853 times.
8318 {t1} := polymorphicBindingsLookup(prefix + id, bindings);
5067 5853 t1 := fixPolymorphicRestype2(t1, "", bindings, info);
5068 then t1;
5069
5070 case DAE.T_METALIST(ty = t1)
5071 algorithm
5072 5187 t2 := fixPolymorphicRestype2(t1, prefix,bindings, info);
5073 5187 t2 := boxIfUnboxedType(t2);
5074 5187 then DAE.T_METALIST(t2);
5075
5076 case DAE.T_METAARRAY(ty = t1)
5077 algorithm
5078 429 t2 := fixPolymorphicRestype2(t1,prefix,bindings, info);
5079 429 t2 := boxIfUnboxedType(t2);
5080 429 then DAE.T_METAARRAY(t2);
5081
5082 case DAE.T_METAOPTION(ty = t1)
5083 algorithm
5084 306 t2 := fixPolymorphicRestype2(t1, prefix,bindings, info);
5085 306 t2 := boxIfUnboxedType(t2);
5086 306 then DAE.T_METAOPTION(t2);
5087
5088 case DAE.T_METAUNIONTYPE(typeVars={})
5089 then ty;
5090
5091 case DAE.T_METAUNIONTYPE(typeVars=tys)
5092 algorithm
5093 306 tys := List.map3(tys, fixPolymorphicRestype2, prefix, bindings, info);
5094 306 tys := List.map(tys, boxIfUnboxedType);
5095 306 then DAE.T_METAUNIONTYPE(ty.paths,tys,ty.knownSingleton,ty.singletonType,ty.path);
5096
5097 case DAE.T_METATUPLE(types = tys)
5098 algorithm
5099 882 tys := List.map3(tys, fixPolymorphicRestype2, prefix, bindings, info);
5100 882 tys := List.map(tys, boxIfUnboxedType);
5101 882 then DAE.T_METATUPLE(tys);
5102
5103 case t1 as DAE.T_ARRAY()
5104 algorithm
5105 31888 t1.ty := fixPolymorphicRestype2(t1.ty,prefix,bindings, info);
5106 then t1;
5107
5108 case t1 as DAE.T_TUPLE()
5109 algorithm
5110 3356 t1.types := List.map3(t1.types, fixPolymorphicRestype2, prefix, bindings, info);
5111 then t1;
5112
5113 case DAE.T_FUNCTION(args1,ty1,functionAttributes,path)
5114 algorithm
5115 56788 tys1 := List.map(args1, funcArgType);
5116 56788 tys1 := List.map3(tys1, fixPolymorphicRestype2, prefix, bindings, info);
5117 56788 ty1 := fixPolymorphicRestype2(ty1,prefix,bindings,info);
5118 56788 args1 := List.threadMap(args1,tys1,setFuncArgType);
5119 56788 ty1 := DAE.T_FUNCTION(args1,ty1,functionAttributes,path);
5120 then ty1;
5121
5122 // Add Uniontype, Function reference(?)
5123 case _
5124 algorithm
5125 // failure(isPolymorphic(ty)); Recursive functions like to return polymorphic crap we don't know of
5126 then ty;
5127
5128 else
5129 algorithm
5130 ✗ tstr := TypesDump.unparseType(ty);
5131 ✗ bstr := polymorphicBindingsStr(bindings);
5132 ✗ id := "Types.fixPolymorphicRestype failed for type: " + tstr + " using bindings: " + bstr;
5133 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {id}, info);
5134 ✗ then fail();
5135 end matchcontinue;
5136 end fixPolymorphicRestype2;
5137
5138 public function polymorphicBindingsLookup
5139 input String id;
5140 input InstTypes.PolymorphicBindings bindings;
5141 output list<DAE.Type> resType;
5142 algorithm
5143 resType := matchcontinue bindings
5144 local
5145 String id2;
5146 list<DAE.Type> tys;
5147 InstTypes.PolymorphicBindings rest;
5148 case (id2,tys)::_
5149 algorithm
5150
4/4
✓ Branch 0 taken 6716 times.
✓ Branch 1 taken 3484 times.
✓ Branch 3 taken 5907 times.
✓ Branch 4 taken 809 times.
10200 true := id == id2;
5151 5907 then List.map(tys, boxIfUnboxedType);
5152 case _::rest
5153 algorithm
5154 4293 tys := polymorphicBindingsLookup(id,rest);
5155 then tys;
5156 end matchcontinue;
5157 end polymorphicBindingsLookup;
5158
5159 public function getAllInnerTypesOfType
5160 "Traverses all the types the input DAE.Type contains, checks if
5161 they are of the type the given function specifies, then returns
5162 a list of all those types."
5163 input DAE.Type inType;
5164 input TypeFn inFn;
5165 output list<DAE.Type> outTypes;
5166 partial function TypeFn
5167 input DAE.Type fnInType;
5168 output Boolean outMatch;
5169 end TypeFn;
5170 algorithm
5171 163139 outTypes := getAllInnerTypes({inType},{},inFn);
5172 end getAllInnerTypesOfType;
5173
5174 protected function getAllInnerTypes
5175 "Traverses all the types that the input DAE.Type contains, and returns all
5176 types for which the given function returns true."
5177 input list<DAE.Type> inTypes;
5178 input list<DAE.Type> inAccum = {};
5179 input MatchFunc inFunc;
5180 output list<DAE.Type> outTypes = inAccum;
5181
5182 partial function MatchFunc
5183 input DAE.Type inType;
5184 output Boolean outMatch;
5185 end MatchFunc;
5186 protected
5187 DAE.Type ty;
5188 list<DAE.Type> tys;
5189 algorithm
5190
2/2
✓ Branch 0 taken 293770 times.
✓ Branch 1 taken 456909 times.
750679 for t in inTypes loop
5191 // Add the type to the result list if the match function return true.
5192
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 293770 times.
✓ Branch 4 taken 46412 times.
✓ Branch 5 taken 247358 times.
293770 if inFunc(t) then
5193 outTypes := t :: outTypes;
5194 end if;
5195
5196 // Get the inner types of the type.
5197 tys := match t
5198 local
5199 list<DAE.Var> fields;
5200 list<DAE.FuncArg> funcArgs;
5201 case DAE.T_ARRAY(ty = ty) then {ty};
5202 case DAE.T_METALIST(ty = ty) then {ty};
5203 case DAE.T_METAARRAY(ty = ty) then {ty};
5204 case DAE.T_METABOXED(ty = ty) then {ty};
5205 case DAE.T_METAOPTION(ty = ty) then {ty};
5206 case DAE.T_TUPLE(types = tys) then tys;
5207 case DAE.T_METATUPLE(types = tys) then tys;
5208 case DAE.T_METAUNIONTYPE(typeVars = tys) then tys;
5209 case DAE.T_METARECORD(typeVars = tys, fields = fields)
5210 17359 then listAppend(tys, List.map(fields, getVarType));
5211 case DAE.T_COMPLEX(varLst = fields)
5212 5857 then List.map(fields, getVarType);
5213 case DAE.T_SUBTYPE_BASIC(varLst = fields)
5214 121 then List.map(fields, getVarType);
5215 case DAE.T_FUNCTION(funcArg = funcArgs, funcResultType = ty)
5216 1136 then ty :: List.map(funcArgs, funcArgType);
5217 else {};
5218 end match;
5219
5220 // Call this function recursively to filter out the matching inner types and
5221 // add them to the result.
5222 293770 outTypes := getAllInnerTypes(tys, outTypes, inFunc);
5223 end for;
5224 end getAllInnerTypes;
5225
5226 public function uniontypeFilter
5227 input DAE.Type ty;
5228 output Boolean outMatch;
5229 algorithm
5230 outMatch := match ty
5231 case DAE.T_METAUNIONTYPE(__) then true;
5232 else false;
5233 end match;
5234 end uniontypeFilter;
5235
5236 public function metarecordFilter
5237 input DAE.Type ty;
5238 output Boolean outMatch;
5239 algorithm
5240 outMatch := match ty
5241 case DAE.T_METARECORD(__) then true;
5242 else false;
5243 end match;
5244 end metarecordFilter;
5245
5246 public function getUniontypePaths
5247 input DAE.Type ty;
5248 output list<Absyn.Path> outPaths;
5249 algorithm
5250 outPaths := match ty
5251 local
5252 list<Absyn.Path> paths;
5253 case DAE.T_METAUNIONTYPE(paths=paths) then paths;
5254 end match;
5255 end getUniontypePaths;
5256
5257 public function makeFunctionPolymorphicReference
5258 "Takes a function reference. If it contains any types that are not boxed, we
5259 return a reference to the function that does take boxed types. Else, we
5260 return a reference to the regular function."
5261 input DAE.Type inType;
5262 output DAE.Type outType;
5263 algorithm
5264 outType := match inType
5265 local
5266 list<DAE.FuncArg> funcArgs1,funcArgs2;
5267 list<DAE.Type> funcArgTypes1, funcArgTypes2, dummyBoxedTypeList;
5268 list<DAE.Exp> dummyExpList;
5269 Type ty2,resType1,resType2;
5270 Absyn.Path path;
5271 DAE.FunctionAttributes functionAttributes;
5272
5273 case DAE.T_FUNCTION(funcArgs1,resType1,functionAttributes,path)
5274 algorithm
5275 899 funcArgTypes1 := List.map(funcArgs1, funcArgType);
5276 899 (dummyExpList,dummyBoxedTypeList) := makeDummyExpAndTypeLists(funcArgTypes1);
5277 899 (_,funcArgTypes2) := matchTypeTuple(dummyExpList, funcArgTypes1, dummyBoxedTypeList, false);
5278 899 funcArgs2 := List.threadMap(funcArgs1,funcArgTypes2,setFuncArgType);
5279 899 resType2 := makeFunctionPolymorphicReferenceResType(resType1);
5280 899 ty2 := DAE.T_FUNCTION(funcArgs2,resType2,functionAttributes,path);
5281 then ty2;
5282
5283 /* Maybe add this case when standard Modelica gets function references?
5284 case (ty1 as (tty1 as DAE.T_FUNCTION(funcArgs1,resType),SOME(path)))
5285 local
5286 list<Boolean> boolList;
5287 algorithm
5288 funcArgTypes1 = List.map(funcArgs1, Util.tuple22);
5289 boolList = List.map(funcArgTypes1, isBoxedType);
5290 true = List.reduce(boolList, boolAnd);
5291 then ty1; */
5292 case _
5293 algorithm
5294 // fprintln(Flags.FAILTRACE, "- Types.makeFunctionPolymorphicReference failed");
5295 then fail();
5296 end match;
5297 end makeFunctionPolymorphicReference;
5298
5299 protected function makeFunctionPolymorphicReferenceResType
5300 input DAE.Type inType;
5301 output DAE.Type outType;
5302 algorithm
5303 outType := matchcontinue inType
5304 local
5305 DAE.Exp e;
5306 Type ty,ty1,ty2;
5307 list<DAE.Type> tys, dummyBoxedTypeList;
5308 list<DAE.Exp> dummyExpList;
5309
5310 case ty as DAE.T_TUPLE(tys)
5311 algorithm
5312 101 (dummyExpList,dummyBoxedTypeList) := makeDummyExpAndTypeLists(tys);
5313 101 (_,tys) := matchTypeTuple(dummyExpList, tys, dummyBoxedTypeList, false);
5314 101 ty.types := tys;
5315 then ty;
5316 case ty as DAE.T_NORETCALL() then ty;
5317 case ty1
5318 algorithm
5319
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 792 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 792 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 792 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 792 times.
792 ({e},{ty2}) := makeDummyExpAndTypeLists({ty1});
5320 792 (_,ty) := matchType(e, ty1, ty2, false);
5321 792 then ty;
5322 end matchcontinue;
5323 end makeFunctionPolymorphicReferenceResType;
5324
5325 protected function makeDummyExpAndTypeLists
5326 input list<DAE.Type> lst;
5327 output list<DAE.Exp> outExps;
5328 output list<DAE.Type> outTypes;
5329 algorithm
5330 (outExps,outTypes) := match lst
5331 local
5332 list<DAE.Exp> restExp;
5333 list<DAE.Type> restType, rest;
5334 DAE.ComponentRef cref_;
5335 DAE.Exp crefExp;
5336
5337 case {} then ({},{});
5338
5339 case _::rest
5340 algorithm
5341 2360 (restExp,restType) := makeDummyExpAndTypeLists(rest);
5342 2360 cref_ := ComponentReferenceBasics.makeCrefIdent("#DummyExp#",DAE.T_UNKNOWN_DEFAULT,{});
5343 2360 crefExp := Expression.crefExp(cref_);
5344 2360 then (crefExp::restExp,DAE.T_METABOXED(DAE.T_UNKNOWN_DEFAULT)::restType);
5345 end match;
5346 end makeDummyExpAndTypeLists;
5347
5348 public function resTypeToListTypes
5349 "Transforms a DAE.T_TUPLE to a list of types. Other types return the same type (as a list)"
5350 input DAE.Type inType;
5351 output list<DAE.Type> outType;
5352 algorithm
5353 outType := match inType
5354 local
5355 list<DAE.Type> tys;
5356 Type ty;
5357 case DAE.T_TUPLE(types = tys) then tys;
5358 case DAE.T_NORETCALL() then {};
5359 case ty then {ty};
5360 end match;
5361 end resTypeToListTypes;
5362
5363 public function getRealOrIntegerDimensions
5364 "If the type is a Real, Integer or an array of Real or Integer, the function returns
5365 list of dimensions; otherwise, it fails."
5366 input DAE.Type inType;
5367 output DAE.Dimensions outDims;
5368 algorithm
5369 outDims := match inType
5370 local
5371 Type ty;
5372 DAE.Dimension d;
5373 DAE.Dimensions dims;
5374
5375 case DAE.T_REAL() then {};
5376 case DAE.T_INTEGER() then {};
5377 case DAE.T_SUBTYPE_BASIC(complexType = ty)
5378 ✗ then getRealOrIntegerDimensions(ty);
5379
5380 case DAE.T_ARRAY(dims = {d as DAE.DIM_INTEGER(_)}, ty = ty)
5381 algorithm
5382 ✗ dims := getRealOrIntegerDimensions(ty);
5383 then
5384 d::dims;
5385 end match;
5386 end getRealOrIntegerDimensions;
5387
5388 public function isPolymorphic
5389 input DAE.Type ty;
5390 output Boolean outMatch;
5391 algorithm
5392 outMatch := match ty
5393 case DAE.T_METAPOLYMORPHIC(__) then true;
5394 else false;
5395 end match;
5396 end isPolymorphic;
5397
5398 public function polymorphicTypeName
5399 input DAE.Type ty;
5400 output String name;
5401 algorithm
5402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 DAE.T_METAPOLYMORPHIC(name = name) := ty;
5403 end polymorphicTypeName;
5404
5405 public function addPolymorphicBinding
5406 input String id;
5407 input DAE.Type ity;
5408 input InstTypes.PolymorphicBindings bindings;
5409 output InstTypes.PolymorphicBindings outBindings;
5410 algorithm
5411 outBindings := matchcontinue (id,ity,bindings)
5412 local
5413 String id1,id2;
5414 list<DAE.Type> tys;
5415 InstTypes.PolymorphicBindings rest;
5416 tuple<String,list<DAE.Type>> first;
5417 Type ty;
5418
5419 case (_,ty,{})
5420 algorithm
5421 2518 ty := unboxedType(ty);
5422 2518 ty := boxIfUnboxedType(ty);
5423 2518 then {(id,{ty})};
5424 case (id1,ty,(id2,tys)::rest)
5425 algorithm
5426
4/4
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 336 times.
✓ Branch 3 taken 1654 times.
✓ Branch 4 taken 418 times.
2408 true := id1 == id2;
5427 1654 ty := unboxedType(ty);
5428 1654 ty := boxIfUnboxedType(ty);
5429 1654 then (id2,ty::tys)::rest;
5430 case (_,ty,first::rest)
5431 algorithm
5432 754 rest := addPolymorphicBinding(id,ty,rest);
5433 then first::rest;
5434 end matchcontinue;
5435 end addPolymorphicBinding;
5436
5437 public function solvePolymorphicBindings
5438 "Takes a set of polymorphic bindings and tries to solve the constraints
5439 such that each name is bound to a non-polymorphic type.
5440 Solves by doing iterations until a valid state is found (or no change is
5441 possible)."
5442 input InstTypes.PolymorphicBindings bindings;
5443 input SourceInfo info;
5444 input Absyn.Path path;
5445 output InstTypes.PolymorphicBindings solvedBindings;
5446 protected
5447 InstTypes.PolymorphicBindings unsolvedBindings;
5448 algorithm
5449 // print("solvePoly " + polymorphicBindingsStr(bindings) + "\n");
5450 56006 (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(bindings, {}, {});
5451 56006 checkValidBindings(bindings, solvedBindings, unsolvedBindings, info, path);
5452 // print("solved poly " + polymorphicBindingsStr(solvedBindings) + "\n");
5453 end solvePolymorphicBindings;
5454
5455 protected function checkValidBindings
5456 "Emits an error message if we could not solve the polymorphic types to actual types."
5457 input InstTypes.PolymorphicBindings bindings;
5458 input InstTypes.PolymorphicBindings solvedBindings;
5459 input InstTypes.PolymorphicBindings unsolvedBindings;
5460 input SourceInfo info;
5461 input Absyn.Path path;
5462 protected
5463 String bindingsStr, solvedBindingsStr, unsolvedBindingsStr, pathStr;
5464 algorithm
5465
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 56003 times.
56006 if not listEmpty(unsolvedBindings) then
5466 3 pathStr := AbsynUtil.pathString(path);
5467 3 bindingsStr := polymorphicBindingsStr(bindings);
5468 3 solvedBindingsStr := polymorphicBindingsStr(solvedBindings);
5469 3 unsolvedBindingsStr := polymorphicBindingsStr(unsolvedBindings);
5470 3 Error.addSourceMessage(Error.META_UNSOLVED_POLYMORPHIC_BINDINGS, {pathStr,bindingsStr,solvedBindingsStr,unsolvedBindingsStr},info);
5471 3 fail();
5472 end if;
5473 end checkValidBindings;
5474
5475 protected function solvePolymorphicBindingsLoop
5476 input InstTypes.PolymorphicBindings ibindings;
5477 input InstTypes.PolymorphicBindings isolvedBindings;
5478 input InstTypes.PolymorphicBindings iunsolvedBindings;
5479 output InstTypes.PolymorphicBindings outSolvedBindings;
5480 output InstTypes.PolymorphicBindings outUnsolvedBindings;
5481 algorithm
5482 (outSolvedBindings,outUnsolvedBindings) := matchcontinue (ibindings,isolvedBindings,iunsolvedBindings)
5483 /* Fail by returning crap :) */
5484 local
5485 tuple<String, list<DAE.Type>> first;
5486 Type ty;
5487 list<DAE.Type> tys;
5488 String id;
5489 Integer len1, len2;
5490 InstTypes.PolymorphicBindings rest,solvedBindings,unsolvedBindings;
5491
5492 56006 case ({}, solvedBindings, unsolvedBindings) then (solvedBindings, unsolvedBindings);
5493
5494 case ((id,{ty})::rest,solvedBindings,unsolvedBindings)
5495 algorithm
5496 2452 ty := Types.boxIfUnboxedType(ty);
5497 2452 (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(listAppend(unsolvedBindings,rest),(id,{ty})::solvedBindings,{});
5498 then (solvedBindings,unsolvedBindings);
5499
5500 // Replace solved bindings
5501 case ((id,tys)::rest,solvedBindings,unsolvedBindings)
5502 algorithm
5503 1201 tys := replaceSolvedBindings(tys, solvedBindings, false);
5504 46 tys := List.unionOnTrue(tys, {}, equivtypes);
5505 92 (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(listAppend((id,tys)::unsolvedBindings,rest),solvedBindings,{});
5506 then (solvedBindings,unsolvedBindings);
5507
5508 case ((id,tys)::rest,solvedBindings,unsolvedBindings)
5509 algorithm
5510 1155 (tys,solvedBindings) := solveBindings(tys, tys, solvedBindings);
5511 63 tys := List.unionOnTrue(tys, {}, equivtypes);
5512 126 (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(listAppend((id,tys)::unsolvedBindings,rest),solvedBindings,{});
5513 then (solvedBindings,unsolvedBindings);
5514
5515 // Duplicate types need to be removed
5516 case ((id,tys)::rest,solvedBindings,unsolvedBindings)
5517 algorithm
5518 1092 len1 := listLength(tys);
5519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1092 times.
1092 true := len1 > 1;
5520 1092 tys := List.unionOnTrue(tys, {}, equivtypes); // Remove duplicates
5521 1092 len2 := listLength(tys);
5522
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1089 times.
1092 false := len1 == len2;
5523 2178 (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(listAppend((id,tys)::unsolvedBindings,rest),solvedBindings,{});
5524 then (solvedBindings,unsolvedBindings);
5525
5526 case (first::rest, solvedBindings, unsolvedBindings)
5527 algorithm
5528 3 (solvedBindings,unsolvedBindings) := solvePolymorphicBindingsLoop(rest, solvedBindings, first::unsolvedBindings);
5529 then (solvedBindings, unsolvedBindings);
5530 end matchcontinue;
5531 end solvePolymorphicBindingsLoop;
5532
5533 protected function solveBindings
5534 "Checks all types against each other to find an unbound polymorphic variable, which will then become bound.
5535 Uses unification to solve the system, but the algorithm is slow (possibly quadratic).
5536 The good news is we don't have functions with many unknown types in the compiler.
5537 Horribly complicated function to keep track of what happens..."
5538 input list<DAE.Type> itys1;
5539 input list<DAE.Type> itys2;
5540 input InstTypes.PolymorphicBindings isolvedBindings;
5541 output list<DAE.Type> outTys;
5542 output InstTypes.PolymorphicBindings outSolvedBindings;
5543 algorithm
5544 (outTys,outSolvedBindings) := matchcontinue (itys1,itys2,isolvedBindings)
5545 local
5546 Type ty,ty1,ty2;
5547 list<DAE.Type> tys,rest,tys1,tys2;
5548 String id,id1,id2;
5549 list<DAE.FuncArg> args1,args2;
5550 DAE.FunctionAttributes functionAttributes1;
5551 Absyn.Path path;
5552 Boolean fromOtherFunction;
5553 InstTypes.PolymorphicBindings solvedBindings;
5554
5555 case ((ty1 as DAE.T_METAPOLYMORPHIC(name = id1))::_,(ty2 as DAE.T_METAPOLYMORPHIC(name = id2))::tys2,solvedBindings)
5556 algorithm
5557
4/4
✓ Branch 0 taken 986 times.
✓ Branch 1 taken 24 times.
✓ Branch 3 taken 978 times.
✓ Branch 4 taken 8 times.
1010 false := id1 == id2;
5558 // If we have $X,Y,..., bind $X = Y instead of Y = $X
5559 32 fromOtherFunction := System.stringFind(id1,"$") <> -1;
5560
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 15 times.
32 id := if fromOtherFunction then id1 else id2;
5561
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 15 times.
32 ty := if fromOtherFunction then ty2 else ty1; // Lookup from one id to the other type
5562
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
62 failure(polymorphicBindingsLookup(id, solvedBindings));
5563 30 solvedBindings := addPolymorphicBinding(id,ty,solvedBindings);
5564 30 then (ty::tys2, solvedBindings);
5565
5566 case ((DAE.T_METAPOLYMORPHIC(name = id))::_,ty2::tys2,solvedBindings)
5567 algorithm
5568
2/2
✓ Branch 1 taken 980 times.
✓ Branch 2 taken 28 times.
1008 false := isPolymorphic(ty2);
5569
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 failure(polymorphicBindingsLookup(id, solvedBindings));
5570 28 solvedBindings := addPolymorphicBinding(id,ty2,solvedBindings);
5571 28 then (ty2::tys2, solvedBindings);
5572
5573 case (ty1::_,(DAE.T_METAPOLYMORPHIC(name = id))::tys2,solvedBindings)
5574 algorithm
5575
2/2
✓ Branch 1 taken 980 times.
✓ Branch 2 taken 5 times.
985 false := isPolymorphic(ty1);
5576
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 failure(polymorphicBindingsLookup(id, solvedBindings));
5577 5 solvedBindings := addPolymorphicBinding(id,ty1,solvedBindings);
5578 5 then (ty1::tys2, solvedBindings);
5579
5580 case (DAE.T_METAOPTION(ty = ty1)::_,DAE.T_METAOPTION(ty = ty2)::tys2,solvedBindings)
5581 algorithm
5582
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
30 ({ty1},solvedBindings) := solveBindings({ty1},{ty2},solvedBindings);
5583 1 ty1 := DAE.T_METAOPTION(ty1);
5584 1 then (ty1::tys2,solvedBindings);
5585
5586 case (DAE.T_METALIST(ty = ty1)::_,DAE.T_METALIST(ty = ty2)::tys2,solvedBindings)
5587 algorithm
5588
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
188 ({ty1},solvedBindings) := solveBindings({ty1},{ty2},solvedBindings);
5589 4 ty1 := DAE.T_METALIST(ty1);
5590 4 then (ty1::tys2,solvedBindings);
5591
5592 case (DAE.T_METAARRAY(ty = ty1)::_,DAE.T_METAARRAY(ty = ty2)::tys2,solvedBindings)
5593 algorithm
5594
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
7 ({ty1},solvedBindings) := solveBindings({ty1},{ty2},solvedBindings);
5595 1 ty1 := DAE.T_METAARRAY(ty1);
5596 1 then (ty1::tys2,solvedBindings);
5597
5598 case (DAE.T_METATUPLE(types = tys1)::_,DAE.T_METATUPLE(types = tys2)::rest,solvedBindings)
5599 algorithm
5600 62 (tys1,solvedBindings) := solveBindingsThread(tys1,tys2,false,solvedBindings);
5601 2 ty1 := DAE.T_METATUPLE(tys1);
5602 2 then (ty1::rest,solvedBindings);
5603
5604 case (DAE.T_FUNCTION(args1,ty1,functionAttributes1,path)::_,DAE.T_FUNCTION(args2,ty2,_,_)::rest,solvedBindings)
5605 algorithm
5606 9 tys1 := List.map(args1, funcArgType);
5607 9 tys2 := List.map(args2, funcArgType);
5608
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
9 (ty1::tys1,solvedBindings) := solveBindingsThread(ty1::tys1,ty2::tys2,false,solvedBindings);
5609 3 tys1 := List.map(tys1, boxIfUnboxedType);
5610 3 args1 := List.threadMap(args1,tys1,setFuncArgType);
5611 3 args1 := List.map(args1,clearDefaultBinding);
5612 3 ty1 := DAE.T_FUNCTION(args1,ty1,functionAttributes1,path);
5613 3 then (ty1::rest,solvedBindings);
5614
5615 case (tys1,ty::tys2,solvedBindings)
5616 algorithm
5617 3112 (tys,solvedBindings) := solveBindings(tys1,tys2,solvedBindings);
5618 69 then (ty::tys,solvedBindings);
5619 end matchcontinue;
5620 end solveBindings;
5621
5622 protected function solveBindingsThread
5623 "Checks all types against each other to find an unbound polymorphic variable, which will then become bound.
5624 Uses unification to solve the system, but the algorithm is slow (possibly quadratic).
5625 The good news is we don't have functions with many unknown types in the compiler.
5626
5627 Horribly complicated function to keep track of what happens..."
5628 input list<DAE.Type> itys1;
5629 input list<DAE.Type> itys2;
5630 input Boolean changed "if true, something changed and the function will succeed";
5631 input InstTypes.PolymorphicBindings isolvedBindings;
5632 output list<DAE.Type> outTys;
5633 output InstTypes.PolymorphicBindings outSolvedBindings;
5634 algorithm
5635 (outTys,outSolvedBindings) := matchcontinue (itys1,itys2,changed,isolvedBindings)
5636 local
5637 Type ty1,ty2;
5638 InstTypes.PolymorphicBindings solvedBindings;
5639 list<DAE.Type> tys1, tys2;
5640
5641 case (ty1::tys1,ty2::tys2,_,solvedBindings)
5642 algorithm
5643
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
187 ({ty1},solvedBindings) := solveBindings({ty1},{ty2},solvedBindings);
5644 5 (tys2,solvedBindings) := solveBindingsThread(tys1,tys2,true,solvedBindings);
5645 5 then (ty1::tys2,solvedBindings);
5646 case (ty1::tys1,_::tys2,_,solvedBindings)
5647 algorithm
5648 182 (tys2,solvedBindings) := solveBindingsThread(tys1,tys2,changed,solvedBindings);
5649 8 then (ty1::tys2,solvedBindings);
5650 case ({},{},true,solvedBindings) then ({},solvedBindings);
5651 end matchcontinue;
5652 end solveBindingsThread;
5653
5654 protected function replaceSolvedBindings
5655 input list<DAE.Type> itys;
5656 input InstTypes.PolymorphicBindings isolvedBindings;
5657 input Boolean changed "if true, something changed and the function will succeed";
5658 output list<DAE.Type> outTys;
5659 algorithm
5660 outTys := matchcontinue (itys, isolvedBindings, changed)
5661 local
5662 Type ty;
5663 list<DAE.Type> tys;
5664 InstTypes.PolymorphicBindings solvedBindings;
5665
5666 case ({},_,true) then {};
5667 case (ty::tys,solvedBindings,_)
5668 algorithm
5669 3182 ty := replaceSolvedBinding(ty,solvedBindings);
5670 58 tys := replaceSolvedBindings(tys,solvedBindings,true);
5671 then ty::tys;
5672 case (ty::tys,solvedBindings,_)
5673 algorithm
5674 3124 tys := replaceSolvedBindings(tys,solvedBindings,changed);
5675 then ty::tys;
5676 end matchcontinue;
5677 end replaceSolvedBindings;
5678
5679 protected function replaceSolvedBinding
5680 input DAE.Type ity;
5681 input InstTypes.PolymorphicBindings isolvedBindings;
5682 output DAE.Type outTy;
5683 algorithm
5684 outTy := match (ity,isolvedBindings)
5685 local
5686 list<DAE.FuncArg> args;
5687 list<DAE.Type> tys;
5688 String id;
5689 list<String> names;
5690 Absyn.Path path;
5691 DAE.FunctionAttributes functionAttributes;
5692 DAE.Type ty,resType;
5693 InstTypes.PolymorphicBindings solvedBindings;
5694
5695 case (DAE.T_METALIST(ty = ty),solvedBindings)
5696 algorithm
5697 205 ty := replaceSolvedBinding(ty, solvedBindings);
5698 5 ty := DAE.T_METALIST(ty);
5699 then ty;
5700
5701 case (DAE.T_METAARRAY(ty = ty),solvedBindings)
5702 algorithm
5703 9 ty := replaceSolvedBinding(ty, solvedBindings);
5704 1 ty := DAE.T_METAARRAY(ty);
5705 then ty;
5706
5707 case (DAE.T_METAOPTION(ty = ty),solvedBindings)
5708 algorithm
5709 32 ty := replaceSolvedBinding(ty, solvedBindings);
5710 1 ty := DAE.T_METAOPTION(ty);
5711 then ty;
5712
5713 case (DAE.T_METATUPLE(types = tys),solvedBindings)
5714 algorithm
5715 74 tys := replaceSolvedBindings(tys,solvedBindings,false);
5716 2 ty := DAE.T_METATUPLE(tys);
5717 then ty;
5718
5719 case (DAE.T_TUPLE(types = tys),solvedBindings)
5720 algorithm
5721 12 tys := replaceSolvedBindings(tys,solvedBindings,false);
5722 2 ty := DAE.T_TUPLE(tys,ity.names);
5723 then ty;
5724
5725 case (DAE.T_FUNCTION(args,resType,functionAttributes,path),solvedBindings)
5726 algorithm
5727 15 tys := List.map(args, funcArgType);
5728 15 tys := replaceSolvedBindings(resType::tys,solvedBindings,false);
5729 2 tys := List.map(tys, unboxedType);
5730
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 ty::tys := List.map(tys, boxIfUnboxedType);
5731 2 args := List.threadMap(args,tys,setFuncArgType);
5732 2 ty := makeRegularTupleFromMetaTupleOnTrue(isTuple(resType),ty);
5733 2 ty := DAE.T_FUNCTION(args,ty,functionAttributes,path);
5734 then ty;
5735
5736 case (DAE.T_METAPOLYMORPHIC(name = id),solvedBindings)
5737 algorithm
5738
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
1151 {ty} := polymorphicBindingsLookup(id, solvedBindings);
5739 then ty;
5740 end match;
5741 end replaceSolvedBinding;
5742
5743 protected function subtypePolymorphic
5744 "A simple subtype() that also binds polymorphic variables.
5745 Only works on the MetaModelica datatypes; the input is assumed to be boxed.
5746 "
5747 input DAE.Type actual;
5748 input DAE.Type expected;
5749 input Option<Absyn.Path> envPath;
5750 input InstTypes.PolymorphicBindings inBindings;
5751 output InstTypes.PolymorphicBindings bindings;
5752 algorithm
5753 bindings := matchcontinue (actual,expected)
5754 local
5755 String id,prefix;
5756 Type ty,ty1,ty2;
5757 list<DAE.FuncArg> farg1,farg2;
5758 list<DAE.Type> tList1,tList2,tys;
5759 Absyn.Path path1,path2;
5760 list<String> ids,names1,names2;
5761
5762 case (_,DAE.T_METAPOLYMORPHIC(name = id))
5763 4091 then addPolymorphicBinding("$" + id,actual,inBindings);
5764
5765 case (DAE.T_METAPOLYMORPHIC(name = id),_)
5766 algorithm
5767
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
15 if stringGet(id,1)<>stringCharInt("$") then
5768 // We allow things like inner type variables of function pointers,
5769 // but not things like accepting T1 can be tuple<T2,T3>.
5770 // print("Not adding METAPOLYMORPHIC $$"+id+"="+TypesDump.unparseType(expected)+"\n");
5771 10 fail();
5772 end if;
5773 5 then addPolymorphicBinding("$$" + id,expected,inBindings);
5774
5775 case (DAE.T_METABOXED(ty = ty1),ty2)
5776 algorithm
5777 446 ty1 := unboxedType(ty1);
5778 446 then subtypePolymorphic(ty1,ty2,envPath,inBindings);
5779
5780 case (ty1,DAE.T_METABOXED(ty = ty2))
5781 algorithm
5782 307 ty2 := unboxedType(ty2);
5783 307 then subtypePolymorphic(ty1,ty2,envPath,inBindings);
5784
5785 case (DAE.T_NORETCALL(),DAE.T_NORETCALL()) then inBindings;
5786 case (DAE.T_INTEGER(),DAE.T_INTEGER()) then inBindings;
5787 case (DAE.T_REAL(),DAE.T_INTEGER()) then inBindings;
5788 case (DAE.T_STRING(),DAE.T_STRING()) then inBindings;
5789 case (DAE.T_BOOL(),DAE.T_BOOL()) then inBindings;
5790
5791 case (DAE.T_ENUMERATION(names = names1),
5792 DAE.T_ENUMERATION(names = names2))
5793 algorithm
5794
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
46 true := List.isEqualOnTrue(names1, names2, stringEq);
5795 then inBindings;
5796
5797 case (DAE.T_ARRAY(ty = ty1),DAE.T_ARRAY(ty = ty2))
5798 139 then subtypePolymorphic(ty1,ty2,envPath,inBindings);
5799
5800 case (DAE.T_METAARRAY(ty = ty1),DAE.T_METAARRAY(ty = ty2))
5801 146 then subtypePolymorphic(ty1,ty2,envPath,inBindings);
5802 case (DAE.T_METALIST(ty = ty1),DAE.T_METALIST(ty = ty2))
5803 1042 then subtypePolymorphic(ty1,ty2,envPath,inBindings);
5804 case (DAE.T_METAOPTION(ty = ty1),DAE.T_METAOPTION(ty = ty2))
5805 32 then subtypePolymorphic(ty1,ty2,envPath,inBindings);
5806 case (DAE.T_METATUPLE(types = tList1),DAE.T_METATUPLE(types = tList2))
5807 147 then subtypePolymorphicList(tList1,tList2,envPath,inBindings);
5808
5809 case (DAE.T_TUPLE(types = tList1),DAE.T_TUPLE(types = tList2))
5810 209 then subtypePolymorphicList(tList1,tList2,envPath,inBindings);
5811
5812 case (DAE.T_METAUNIONTYPE(),DAE.T_METAUNIONTYPE())
5813 algorithm
5814
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 662 times.
662 true := AbsynUtil.pathEqual(actual.path, expected.path);
5815 662 then subtypePolymorphicList(actual.typeVars, expected.typeVars, envPath, inBindings);
5816
5817 case (DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(path1)),DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(path2)))
5818 algorithm
5819 ✗ true := AbsynUtil.pathEqual(path1,path2);
5820 then inBindings;
5821
5822 // MM Function Reference. sjoelund
5823 case (DAE.T_FUNCTION(farg1,ty1,_,path1),DAE.T_FUNCTION(farg2,ty2,_,_))
5824 algorithm
5825
2/2
✓ Branch 2 taken 299 times.
✓ Branch 3 taken 360 times.
659 if AbsynUtil.pathPrefixOf(Util.getOptionOrDefault(envPath,Absyn.IDENT("$TOP$")),path1) then // Don't rename the result type for recursive calls...
5826 299 tList1 := List.map(farg1, funcArgType);
5827 299 tList2 := List.map(farg2, funcArgType);
5828 299 bindings := subtypePolymorphicList(tList1,tList2,envPath,inBindings);
5829 299 bindings := subtypePolymorphic(ty1,ty2,envPath,bindings);
5830 else
5831 360 prefix := "$" + AbsynUtil.pathString(path1) + ".";
5832
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 360 times.
360 (DAE.T_FUNCTION(farg1,ty1,_,_),_) := traverseType(actual, prefix, prefixTraversedPolymorphicType);
5833 360 tList1 := List.map(farg1, funcArgType);
5834 360 tList2 := List.map(farg2, funcArgType);
5835 360 bindings := subtypePolymorphicList(tList1,tList2,envPath,inBindings);
5836 360 bindings := subtypePolymorphic(ty1,ty2,envPath,bindings);
5837 end if;
5838 then bindings;
5839
5840 case (DAE.T_UNKNOWN(),ty2)
5841 algorithm
5842 9 tys := getAllInnerTypesOfType(ty2, isPolymorphic);
5843 9 ids := List.map(tys, polymorphicTypeName);
5844 9 bindings := List.fold1(ids, addPolymorphicBinding, actual, inBindings);
5845 then bindings;
5846
5847 case (DAE.T_ANYTYPE(),ty2)
5848 algorithm
5849 ✗ tys := getAllInnerTypesOfType(ty2, isPolymorphic);
5850 ✗ ids := List.map(tys, polymorphicTypeName);
5851 ✗ bindings := List.fold1(ids, addPolymorphicBinding, actual, inBindings);
5852 then bindings;
5853
5854 else
5855 algorithm
5856 // print("subtypePolymorphic failed: " + TypesDump.unparseType(actual) + " and " + TypesDump.unparseType(expected) + "\n");
5857 then fail();
5858
5859 end matchcontinue;
5860 end subtypePolymorphic;
5861
5862 protected function subtypePolymorphicList
5863 "A simple subtype() that also binds polymorphic variables.
5864 Only works on the MetaModelica datatypes; the input is assumed to be boxed."
5865 input list<DAE.Type> actual;
5866 input list<DAE.Type> expected;
5867 input Option<Absyn.Path> envPath;
5868 input InstTypes.PolymorphicBindings ibindings;
5869 output InstTypes.PolymorphicBindings outBindings;
5870 algorithm
5871 outBindings := match (actual, expected, ibindings)
5872 local
5873 Type ty1,ty2;
5874 list<DAE.Type> tList1,tList2;
5875 InstTypes.PolymorphicBindings bindings;
5876 case ({}, {}, bindings) then bindings;
5877 case (ty1::tList1, ty2::tList2, bindings)
5878 algorithm
5879 2165 bindings := subtypePolymorphic(ty1,ty2,envPath,bindings);
5880 2165 bindings := subtypePolymorphicList(tList1,tList2,envPath,bindings);
5881 then bindings;
5882 end match;
5883 end subtypePolymorphicList;
5884
5885 public function boxVarLst
5886 input list<DAE.Var> vars;
5887 output list<DAE.Var> ovars;
5888 algorithm
5889 ovars := match vars
5890 local
5891 String name;
5892 DAE.Attributes attributes;
5893 DAE.Type type_;
5894 DAE.Binding binding;
5895 Boolean bdsrc;
5896 Option<DAE.Const> constOfForIteratorRange;
5897 list<DAE.Var> rest;
5898
5899 case {} then {};
5900 case DAE.TYPES_VAR(name,attributes,type_,binding,bdsrc,constOfForIteratorRange)::rest
5901 algorithm
5902 92252 type_ := boxIfUnboxedType(type_);
5903 92252 rest := boxVarLst(rest);
5904
1/2
✓ Branch 0 taken 92252 times.
✗ Branch 1 not taken.
184504 then DAE.TYPES_VAR(name,attributes,type_,binding,bdsrc,constOfForIteratorRange)::rest;
5905
5906 end match;
5907 end boxVarLst;
5908
5909 public function liftArraySubscript "Lifts a type to an array using DAE.Subscript for dimension in the case of non-expanded arrays"
5910 input DAE.Type inType;
5911 input DAE.Subscript inSubscript;
5912 output DAE.Type outType;
5913 algorithm
5914 outType := match (inType,inSubscript)
5915 local
5916 Type ty;
5917 Integer i;
5918 DAE.Exp e;
5919
5920 // An array with an explicit dimension
5921 case (ty,DAE.WHOLE_NONEXP(exp=DAE.ICONST(i)))
5922 ✗ then DAE.T_ARRAY(ty, {DAE.DIM_INTEGER(i)});
5923
5924 // An array with parametric dimension
5925 case (ty,DAE.WHOLE_NONEXP(exp = e))
5926 ✗ then DAE.T_ARRAY(ty,{DAE.DIM_EXP(e)});
5927
5928 // All other kinds of subscripts denote an index, so the type stays the same
5929 case (ty,_)
5930 then ty;
5931 end match;
5932 end liftArraySubscript;
5933
5934 public function liftArraySubscriptList "
5935 Lifts a type using list<DAE.Subscript> to determine dimensions in the case of non-expanded arrays"
5936 input DAE.Type inType;
5937 input list<DAE.Subscript> inSubscriptLst;
5938 output DAE.Type outType;
5939 algorithm
5940 outType := match (inType,inSubscriptLst)
5941 local
5942 Type ty;
5943 DAE.Subscript sub;
5944 list<DAE.Subscript> rest;
5945 case (ty,{}) then ty;
5946 ✗ case (ty,sub::rest) then liftArraySubscript(liftArraySubscriptList(ty,rest),sub);
5947 end match;
5948 end liftArraySubscriptList;
5949
5950 public function convertTupleToMetaTuple "Needed when pattern-matching"
5951 input DAE.Exp exp;
5952 input DAE.Type ty;
5953 output DAE.Exp oexp;
5954 output DAE.Type oty;
5955 algorithm
5956 (oexp,oty) := match exp
5957 case DAE.TUPLE(_)
5958 algorithm
5959 /* So we can verify that the contents of the tuple is boxed */
5960 ✗ (oexp,oty) := matchType(exp,ty,DAE.T_METABOXED_DEFAULT,false);
5961 then (oexp,oty);
5962 675 else (exp,ty);
5963 end match;
5964 end convertTupleToMetaTuple;
5965
5966 public function isFunctionType
5967 input DAE.Type ty;
5968 output Boolean b;
5969 algorithm
5970 b := match ty
5971 case DAE.T_FUNCTION() then true;
5972 else false;
5973 end match;
5974 end isFunctionType;
5975
5976 protected function prefixTraversedPolymorphicType
5977 input Type ty;
5978 input String prefix;
5979 output Type oty = ty;
5980 output String str;
5981 algorithm
5982 (oty,str) := match oty
5983 case DAE.T_METAPOLYMORPHIC()
5984 algorithm
5985 146 oty.name := prefix + oty.name;
5986 then (oty,prefix);
5987 else (ty,prefix);
5988 end match;
5989 end prefixTraversedPolymorphicType;
5990
5991 public function makeExpDimensionsUnknown
5992 input DAE.Type ty;
5993 input Integer dummy;
5994 output DAE.Type oty = ty;
5995 output Integer odummy = dummy;
5996 algorithm
5997 oty := match oty
5998 case DAE.T_ARRAY(dims={DAE.DIM_EXP()})
5999 algorithm
6000 196 oty.dims := {DAE.DIM_UNKNOWN()};
6001 then oty;
6002 else oty;
6003 end match;
6004 end makeExpDimensionsUnknown;
6005
6006 public function makeKnownDimensionsInteger "In binding equations, [Boolean] and [2] match, so we need to convert them"
6007 input DAE.Type ty;
6008 input Integer dummy;
6009 output DAE.Type oty = ty;
6010 output Integer odummy = dummy;
6011 algorithm
6012 oty := match oty
6013 local
6014 Integer size;
6015 case DAE.T_ARRAY(dims={DAE.DIM_BOOLEAN()})
6016 algorithm
6017 ✗ oty.dims := {DAE.DIM_INTEGER(2)};
6018 then oty;
6019 case DAE.T_ARRAY(dims={DAE.DIM_ENUM(size=size)})
6020 algorithm
6021 ✗ oty.dims := {DAE.DIM_INTEGER(size)};
6022 then oty;
6023 case DAE.T_ARRAY(dims={DAE.DIM_EXP(exp=DAE.ICONST(size))})
6024 algorithm
6025 ✗ oty.dims := {DAE.DIM_INTEGER(size)};
6026 then oty;
6027 else oty;
6028 end match;
6029 end makeKnownDimensionsInteger;
6030
6031 public function traverseType
6032 input DAE.Type ty;
6033 input A arg;
6034 input Func fn;
6035 output DAE.Type oty;
6036 output A a = arg;
6037 replaceable type A subtypeof Any;
6038 partial function Func
6039 input DAE.Type ty;
6040 input A arg;
6041 output DAE.Type oty;
6042 output A oarg;
6043 end Func;
6044 algorithm
6045 (oty,a) := match ty
6046 local
6047 list<DAE.Type> tys;
6048 Type tyInner;
6049 String str;
6050 list<DAE.Var> vars;
6051 list<DAE.FuncArg> farg;
6052
6053 case DAE.T_INTEGER() then (ty,a);
6054 case DAE.T_REAL() then (ty,a);
6055 case DAE.T_STRING() then (ty,a);
6056 case DAE.T_BOOL() then (ty,a);
6057 case DAE.T_CLOCK() then (ty,a);
6058 case DAE.T_ENUMERATION() then (ty,a);
6059 case DAE.T_NORETCALL() then (ty,a);
6060 case DAE.T_UNKNOWN() then (ty,a);
6061 case DAE.T_METAUNIONTYPE() then (ty,a);
6062 case DAE.T_METAPOLYMORPHIC() then (ty,a);
6063 case DAE.T_CODE() then (ty,a);
6064
6065 case oty as DAE.T_METABOXED()
6066 algorithm
6067 31046 (tyInner,a) := traverseType(oty.ty, a, fn);
6068 31046 oty.ty := tyInner;
6069 31046 then (oty,a);
6070 case oty as DAE.T_ARRAY()
6071 algorithm
6072 411736 (tyInner,a) := traverseType(oty.ty, a, fn);
6073 411736 oty.ty := tyInner;
6074 411736 then (oty,a);
6075 case oty as DAE.T_METATYPE()
6076 algorithm
6077 63 (tyInner,a) := traverseType(oty.ty, a, fn);
6078 63 oty.ty := tyInner;
6079 63 then (oty,a);
6080 case oty as DAE.T_METALIST()
6081 algorithm
6082 35858 (tyInner, a) := traverseType(oty.ty, a, fn);
6083 35858 oty.ty := tyInner;
6084 35858 then (oty,a);
6085 case oty as DAE.T_METAOPTION()
6086 algorithm
6087 21336 (tyInner,a) := traverseType(oty.ty, a, fn);
6088 21336 oty.ty := tyInner;
6089 21336 then (oty,a);
6090 case oty as DAE.T_METAARRAY()
6091 algorithm
6092 1585 (tyInner,a) := traverseType(oty.ty, a, fn);
6093 1585 oty.ty := tyInner;
6094 1585 then (oty,a);
6095 case oty as DAE.T_FUNCTION_REFERENCE_VAR()
6096 algorithm
6097 ✗ (tyInner,a) := traverseType(oty.functionType, a, fn);
6098 ✗ oty.functionType := tyInner;
6099 ✗ then (oty,a);
6100 case oty as DAE.T_FUNCTION_REFERENCE_FUNC()
6101 algorithm
6102 ✗ (tyInner,a) := traverseType(oty.functionType, a, fn);
6103 ✗ oty.functionType := tyInner;
6104 ✗ then (oty,a);
6105
6106 case oty as DAE.T_METATUPLE()
6107 algorithm
6108 17626 (tys,a) := traverseTupleType(oty.types, a, fn);
6109 17626 oty.types := tys;
6110 17626 then (oty,a);
6111 case oty as DAE.T_TUPLE()
6112 algorithm
6113 5575 (tys,a) := traverseTupleType(oty.types, a, fn);
6114 5575 oty.types := tys;
6115 5575 then (oty, a);
6116
6117 case oty as DAE.T_METARECORD()
6118 algorithm
6119 35063 (vars, a) := traverseVarTypes(oty.fields, a, fn);
6120 35063 oty.fields := vars;
6121 35063 then (oty, a);
6122 case oty as DAE.T_COMPLEX()
6123 algorithm
6124 94703 (vars, a) := traverseVarTypes(oty.varLst, a, fn);
6125 94703 oty.varLst := vars;
6126 94703 then (oty, a);
6127
6128 case oty as DAE.T_SUBTYPE_BASIC()
6129 algorithm
6130 47977 (vars, a) := traverseVarTypes(oty.varLst, a, fn);
6131 47977 (tyInner,a) := traverseType(oty.complexType, a, fn);
6132 47977 oty.varLst := vars;
6133 47977 oty.complexType := tyInner;
6134 47977 then (oty, a);
6135
6136 case oty as DAE.T_FUNCTION()
6137 algorithm
6138 3913 (farg, a) := traverseFuncArg(oty.funcArg, a, fn);
6139 3913 (tyInner, a) := traverseType(oty.funcResultType, a, fn);
6140 3913 oty.funcArg := farg;
6141 3913 oty.funcResultType := tyInner;
6142 3913 then (oty, a);
6143
6144 else
6145 algorithm
6146 ✗ str := "Types.traverseType not implemented correctly: " + TypesDump.unparseType(ty);
6147 ✗ Error.addMessage(Error.INTERNAL_ERROR,{str});
6148 ✗ then
6149 fail();
6150 end match;
6151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2539902 times.
2539902 (oty, a) := fn(oty, a);
6152 end traverseType;
6153
6154 protected function traverseTupleType
6155 input list<DAE.Type> itys;
6156 input A ia;
6157 input Func fn;
6158 output list<DAE.Type> otys;
6159 output A oa;
6160 replaceable type A subtypeof Any;
6161 partial function Func
6162 input DAE.Type ty;
6163 input A arg;
6164 output DAE.Type oty;
6165 output A oarg;
6166 end Func;
6167 algorithm
6168 (otys,oa) := match (itys, ia)
6169 local
6170 Type ty;
6171 list<DAE.Type> tys;
6172 A a;
6173
6174 case ({}, a) then ({},a);
6175 case (ty::tys, a)
6176 algorithm
6177 49303 (ty,a) := traverseType(ty, a, fn);
6178 49303 (tys,a) := traverseTupleType(tys, a, fn);
6179 49303 then (ty::tys,a);
6180 end match;
6181 end traverseTupleType;
6182
6183 protected function traverseVarTypes
6184 input list<DAE.Var> ivars;
6185 input A ia;
6186 input Func fn;
6187 output list<DAE.Var> ovars;
6188 output A oa;
6189 replaceable type A subtypeof Any;
6190 partial function Func
6191 input DAE.Type ty;
6192 input A arg;
6193 output DAE.Type oty;
6194 output A oarg;
6195 end Func;
6196 algorithm
6197 (ovars,oa) := match (ivars, ia)
6198 local
6199 DAE.Var var;
6200 DAE.Type ty;
6201 list<DAE.Var> vars;
6202 A a;
6203
6204 case ({}, a) then ({},a);
6205 case (var::vars, a)
6206 algorithm
6207 668441 ty := getVarType(var);
6208 668441 (ty, a) := traverseType(ty, a, fn);
6209 668441 var := setVarType(var,ty);
6210 668441 (vars,a) := traverseVarTypes(vars,a,fn);
6211 668441 then (var::vars,a);
6212 end match;
6213 end traverseVarTypes;
6214
6215 protected function traverseFuncArg
6216 input list<DAE.FuncArg> iargs;
6217 input A ia;
6218 input Func fn;
6219 output list<DAE.FuncArg> oargs;
6220 output A oa;
6221 replaceable type A subtypeof Any;
6222 partial function Func
6223 input DAE.Type ty;
6224 input A arg;
6225 output DAE.Type oty;
6226 output A oarg;
6227 end Func;
6228 algorithm
6229 (oargs,oa) := match (iargs,ia)
6230 local
6231 list<DAE.FuncArg> args;
6232 A a;
6233 DAE.FuncArg arg;
6234 DAE.Type ty;
6235
6236 case ({},a) then ({},a);
6237 case ((arg as DAE.FUNCARG())::args,a)
6238 algorithm
6239 6039 (ty, a) := traverseType(arg.ty, a, fn);
6240 6039 arg.ty := ty;
6241 6039 (args,a) := traverseFuncArg(args,a,fn);
6242 6039 then (arg::args, a);
6243 end match;
6244 end traverseFuncArg;
6245
6246 public function makeRegularTupleFromMetaTupleOnTrue
6247 input Boolean b;
6248 input DAE.Type ty;
6249 output DAE.Type out;
6250 algorithm
6251 out := match (b,ty)
6252 local
6253 list<DAE.Type> tys;
6254
6255 case (true,DAE.T_METATUPLE(tys))
6256 algorithm
6257 146 tys := List.mapMap(tys, unboxedType, boxIfUnboxedType);
6258 146 tys := List.map(tys, unboxedType); // Yes. Crazy
6259 146 then (DAE.T_TUPLE(tys,NONE()));
6260
6261 case (false,_) then ty;
6262 end match;
6263 end makeRegularTupleFromMetaTupleOnTrue;
6264
6265 public function allTuple
6266 input list<DAE.Type> itys;
6267 output Boolean b;
6268 algorithm
6269 b := match itys local list<DAE.Type> tys;
6270 case {} then true;
6271 695 case DAE.T_TUPLE()::tys then allTuple(tys);
6272 else false;
6273 end match;
6274 end allTuple;
6275
6276 public function unboxedFunctionType "For DAE.PARTEVALFUNC"
6277 input DAE.Type inType;
6278 output DAE.Type outType;
6279 algorithm
6280 outType := match inType
6281 local
6282 list<DAE.FuncArg> args1;
6283 list<DAE.Type> tys1;
6284 Type ty1;
6285 DAE.FunctionAttributes functionAttributes;
6286 Absyn.Path path;
6287
6288 case DAE.T_FUNCTION(args1,ty1,functionAttributes,path)
6289 algorithm
6290 ✗ tys1 := List.mapMap(args1, funcArgType, unboxedType);
6291 ✗ ty1 := unboxedType(ty1);
6292 ✗ args1 := List.threadMap(args1,tys1,setFuncArgType);
6293 ✗ then (DAE.T_FUNCTION(args1,ty1,functionAttributes,path));
6294 end match;
6295 end unboxedFunctionType;
6296
6297 public function varHasMetaRecordType
6298 input DAE.Var var;
6299 output Boolean b;
6300 algorithm
6301 b := match var
6302 case DAE.TYPES_VAR(ty = DAE.T_METABOXED(ty = DAE.T_METARECORD()))
6303 then true;
6304 case DAE.TYPES_VAR(ty = DAE.T_METARECORD())
6305 then true;
6306 case DAE.TYPES_VAR(ty = DAE.T_METABOXED(ty = DAE.T_COMPLEX(complexClassType = ClassInf.META_RECORD(_))))
6307 then true;
6308 else false;
6309 end match;
6310 end varHasMetaRecordType;
6311
6312 protected function optInteger
6313 input Option<Integer> inInt;
6314 output Integer outInt;
6315 algorithm
6316 outInt := match inInt
6317 local Integer i;
6318 case SOME(i) then i;
6319 else -1;
6320 end match;
6321 end optInteger;
6322
6323 public function typeToValue "This function builds Values.Value out of a type using generated bindings."
6324 input DAE.Type inType;
6325 output Values.Value defaultValue;
6326 algorithm
6327 defaultValue := matchcontinue inType
6328 local
6329 list<DAE.Var> vars;
6330 list<String> comp;
6331 ClassInf.State st;
6332 Type t;
6333 list<DAE.Type> tys;
6334 String s1;
6335 Absyn.Path path;
6336 Integer i;
6337 Option<Integer> iOpt;
6338 Values.Value v;
6339 list<Values.Value> valueLst, ordered;
6340
6341 case DAE.T_INTEGER() then Values.INTEGER(0);
6342 case DAE.T_REAL() then Values.REAL(0.0);
6343 case DAE.T_STRING() then Values.STRING("<EMPTY>");
6344 case DAE.T_BOOL() then Values.BOOL(false);
6345 case DAE.T_ENUMERATION(index = iOpt, path = path)
6346 algorithm
6347 ✗ i := optInteger(iOpt);
6348 ✗ then
6349 Values.ENUM_LITERAL(path, i);
6350
6351 case DAE.T_COMPLEX(complexClassType = st,varLst = vars)
6352 algorithm
6353 2624 (ordered, comp) := varsToValues(vars);
6354 2624 path := ClassInfUtil.getStateName(st);
6355 2624 then
6356 Values.RECORD(path, ordered, comp, -1);
6357
6358 case DAE.T_SUBTYPE_BASIC(complexType = t)
6359 algorithm
6360 ✗ v := typeToValue(t);
6361 then
6362 v;
6363
6364 case DAE.T_ARRAY(dims = {DAE.DIM_INTEGER(i)},ty = t)
6365 algorithm
6366 7788 v := typeToValue(t);
6367 7788 valueLst := List.fill(v, i);
6368 7788 then
6369 Values.ARRAY(valueLst, {i});
6370
6371 case DAE.T_TUPLE(types = tys)
6372 algorithm
6373 ✗ valueLst := List.map(tys, typeToValue);
6374 ✗ v := Values.TUPLE(valueLst);
6375 then
6376 v;
6377
6378 case DAE.T_UNKNOWN() then Values.META_FAIL();
6379
6380
6381 // All the other ones we don't handle
6382 else
6383 algorithm
6384 ✗ true := Flags.isSet(Flags.FAILTRACE);
6385 ✗ Debug.trace("- Types.typeToValue failed on unhandled Type ");
6386 ✗ s1 := TypesDump.printTypeStr(inType);
6387 ✗ Debug.traceln(s1);
6388 ✗ then
6389 fail();
6390
6391 end matchcontinue;
6392 end typeToValue;
6393
6394 public function varsToValues "Translates a list of Var list to Values.Value, the
6395 names of the variables as component names.
6396 Used e.g. when retrieving the type of a record value."
6397 input list<DAE.Var> inVarLst;
6398 output list<Values.Value> outValuesValueLst;
6399 output list<String> outExpIdentLst;
6400 algorithm
6401 (outValuesValueLst,outExpIdentLst) := matchcontinue inVarLst
6402 local
6403 DAE.Type tp;
6404 list<DAE.Var> rest;
6405 Values.Value v;
6406 list<Values.Value> restVals;
6407 String id;
6408 list<String> restIds;
6409
6410 case {} then ({}, {});
6411
6412 case DAE.TYPES_VAR(name = id,ty = tp)::rest
6413 algorithm
6414 7928 v := typeToValue(tp);
6415 7928 (restVals, restIds) := varsToValues(rest);
6416 7928 then
6417 (v::restVals, id::restIds);
6418
6419 else
6420 algorithm
6421 ✗ true := Flags.isSet(Flags.FAILTRACE);
6422 ✗ Debug.trace("- Types.varsToValues failed\n");
6423 ✗ then
6424 fail();
6425 end matchcontinue;
6426 end varsToValues;
6427
6428 public function makeNthDimUnknown
6429 "Real [3,2,1],3 => Real [3,2,:]"
6430 input DAE.Type ty;
6431 input Integer dim;
6432 output DAE.Type oty;
6433 algorithm
6434 oty := match (ty,dim)
6435 local
6436 DAE.Dimension ad;
6437 Type ty1;
6438
6439 156 case (DAE.T_ARRAY(ty1,{_}),1) then DAE.T_ARRAY(ty1,{DAE.DIM_UNKNOWN()});
6440 case (DAE.T_ARRAY(ty1,{ad}),_)
6441 algorithm
6442 5 ty1 := makeNthDimUnknown(ty1,dim-1);
6443 5 then
6444 DAE.T_ARRAY(ty1,{ad});
6445 end match;
6446 end makeNthDimUnknown;
6447
6448 public function arraySuperType
6449 "Selects the supertype out of two array-types. Integer may be promoted to Real."
6450 input DAE.Type ity1;
6451 input SourceInfo info;
6452 input DAE.Type ity2;
6453 output DAE.Type ty;
6454 algorithm
6455 ty := matchcontinue (ity1, ity2)
6456 local
6457 String str1,str2;
6458 Type ty1, ty2;
6459 case (ty1, ty2)
6460 algorithm
6461
2/2
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 5 times.
87 true := isInteger(arrayElementType(ty1));
6462
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
5 true := isReal(arrayElementType(ty2));
6463 3 ty1 := traverseType(ty1, -1, replaceIntegerTypeWithReal);
6464
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 true := subtype(ty1,ty2);
6465 then ty1;
6466 case (ty1, ty2)
6467 algorithm
6468
2/2
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 2 times.
84 true := isInteger(arrayElementType(ty2));
6469
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 true := isReal(arrayElementType(ty1));
6470 ✗ ty2 := traverseType(ty2, -1, replaceIntegerTypeWithReal);
6471 ✗ true := subtype(ty1,ty2);
6472 then ty1;
6473 case (ty1, ty2)
6474 algorithm
6475
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
84 true := subtype(ty1,ty2);
6476 then ty1;
6477 case (ty1, ty2)
6478 algorithm
6479 ✗ str1 := TypesDump.unparseType(ty1);
6480 ✗ str2 := TypesDump.unparseType(ty2);
6481 ✗ typeErrorSanityCheck(str1, str2, info);
6482 ✗ Error.addSourceMessage(Error.ARRAY_TYPE_MISMATCH,{str1,str2},info);
6483 ✗ then fail();
6484 end matchcontinue;
6485 end arraySuperType;
6486
6487 protected function replaceIntegerTypeWithReal
6488 input Type ty;
6489 input Integer dummy;
6490 output Type oty;
6491 output Integer odummy = dummy;
6492 algorithm
6493 oty := match ty
6494 case DAE.T_INTEGER() then DAE.T_REAL_DEFAULT;
6495 else ty;
6496 end match;
6497 end replaceIntegerTypeWithReal;
6498
6499 public function isZeroLengthArray
6500 input DAE.Type ty;
6501 output Boolean res;
6502 algorithm
6503 res := match ty
6504 local
6505 list<DAE.Dimension> dims;
6506 case DAE.T_ARRAY(dims = dims)
6507 algorithm
6508 124344 res := List.fold(dims, isZeroDim, false);
6509 then res;
6510 else false;
6511 end match;
6512 end isZeroLengthArray;
6513
6514 protected function isZeroDim "Check dimensions by folding and checking for zeroes"
6515 input DAE.Dimension dim;
6516 input Boolean acc;
6517 output Boolean res;
6518 algorithm
6519 res := match dim
6520 case DAE.DIM_INTEGER(integer=0) then true;
6521 case DAE.DIM_ENUM(size=0) then true;
6522 else acc;
6523 end match;
6524 end isZeroDim;
6525
6526 public function variabilityToConst "translates an SCode.Variability to a DAE.Const"
6527 input SCode.Variability variability;
6528 output DAE.Const const;
6529 algorithm
6530 const := match variability
6531 case SCode.VAR() then DAE.C_VAR();
6532 case SCode.DISCRETE() then DAE.C_VAR();
6533 case SCode.PARAM() then DAE.C_PARAM();
6534 case SCode.CONST() then DAE.C_CONST();
6535 end match;
6536 end variabilityToConst;
6537
6538 public function varKindToConst "translates an DAE.varKind to a DAE.Const"
6539 input DAE.VarKind varKind;
6540 output DAE.Const const;
6541 algorithm
6542 const := match varKind
6543 case DAE.VARIABLE() then DAE.C_VAR();
6544 case DAE.DISCRETE() then DAE.C_VAR();
6545 case DAE.PARAM() then DAE.C_PARAM();
6546 case DAE.CONST() then DAE.C_CONST();
6547 end match;
6548 end varKindToConst;
6549
6550 public function isValidFunctionVarType
6551 input DAE.Type inType;
6552 output Boolean outIsValid;
6553 algorithm
6554 outIsValid := match inType
6555 local
6556 Type ty;
6557 ClassInf.State state;
6558
6559 case DAE.T_COMPLEX(complexClassType = state)
6560 5622 then isValidFunctionVarState(state);
6561
6562 case DAE.T_SUBTYPE_BASIC(complexType = ty)
6563 28 then isValidFunctionVarType(ty);
6564
6565 else true;
6566
6567 end match;
6568 end isValidFunctionVarType;
6569
6570 protected function isValidFunctionVarState
6571 input ClassInf.State inState;
6572 output Boolean outIsValid;
6573 algorithm
6574 outIsValid := match inState
6575 case ClassInf.MODEL() then false;
6576 case ClassInf.BLOCK() then false;
6577 case ClassInf.CONNECTOR() then false;
6578 case ClassInf.OPTIMIZATION() then false;
6579 case ClassInf.PACKAGE() then false;
6580 else true;
6581 end match;
6582 end isValidFunctionVarState;
6583
6584 protected function makeDummyExpFromType
6585 "Creates a dummy expression from a type. Used by typeConvertArray to handle
6586 empty arrays."
6587 input DAE.Type inType;
6588 output DAE.Exp outExp;
6589 algorithm
6590 outExp := match inType
6591 local
6592 Type ty;
6593 DAE.Dimension dim;
6594 Integer idim;
6595 DAE.Exp exp;
6596 list<DAE.Exp> expl;
6597 DAE.Type ety;
6598
6599 case DAE.T_INTEGER() then DAE.ICONST(0);
6600 case DAE.T_REAL() then DAE.RCONST(0.0);
6601 case DAE.T_STRING() then DAE.SCONST("");
6602 case DAE.T_BOOL() then DAE.BCONST(false);
6603 ✗ case DAE.T_ENUMERATION() then getNthEnumLiteral(inType, 1);
6604 case DAE.T_ARRAY(ty = ty, dims = {dim})
6605 algorithm
6606 23 idim := Expression.dimensionSize(dim);
6607 23 exp := makeDummyExpFromType(ty);
6608 23 ety := Expression.typeof(exp);
6609 23 ety := Expression.liftArrayLeft(ety, dim);
6610 23 expl := List.fill(exp, idim);
6611 23 then
6612 DAE.ARRAY(ety, true, expl);
6613
6614 end match;
6615 end makeDummyExpFromType;
6616
6617 public function printExpTypeStr
6618 input DAE.Type iet;
6619 output String str;
6620 algorithm
6621 ✗ str := TypesDump.printTypeStr(expTypetoTypesType(iet));
6622 end printExpTypeStr;
6623
6624 public function isUnknownType
6625 "Return true if the type is DAE.T_UNKNOWN or DAE.T_ANYTYPE"
6626 input DAE.Type inType;
6627 output Boolean b;
6628 algorithm
6629 b := match inType
6630 case DAE.T_UNKNOWN() then true;
6631 case DAE.T_ANYTYPE() then true;
6632 else false;
6633 end match;
6634 end isUnknownType;
6635
6636 public function isOverdeterminedType
6637 "Returns true if the given type is overdetermined, i.e. a type or record with
6638 an equalityConstraint function, otherwise false."
6639 input DAE.Type inType;
6640 output Boolean outIsOverdetermined;
6641 algorithm
6642 outIsOverdetermined := match inType
6643 local
6644 ClassInf.State cct;
6645
6646 case DAE.T_COMPLEX(complexClassType = cct, equalityConstraint = SOME(_))
6647 ✗ then ClassInfUtil.isTypeOrRecord(cct);
6648
6649 case DAE.T_SUBTYPE_BASIC(equalityConstraint = SOME(_)) then true;
6650 end match;
6651 end isOverdeterminedType;
6652
6653 public function hasMetaArray
6654 input DAE.Type ty;
6655 output Boolean b;
6656 algorithm
6657 38325 (_,b) := traverseType(ty, false, hasMetaArrayWork);
6658 end hasMetaArray;
6659
6660 protected function hasMetaArrayWork
6661 input Type ty;
6662 input Boolean b;
6663 output Type oty = ty;
6664 output Boolean ob = b;
6665 algorithm
6666
1/2
✓ Branch 0 taken 67511 times.
✗ Branch 1 not taken.
67511 if not b then
6667 ob := match ty
6668 case DAE.T_METAARRAY() then true;
6669 else false;
6670 end match;
6671 end if;
6672 end hasMetaArrayWork;
6673
6674 protected function classTypeEqualIfRecord
6675 input ClassInf.State st1;
6676 input ClassInf.State st2;
6677 output Boolean b;
6678 algorithm
6679 b := match (st1,st2)
6680 local
6681 Absyn.Path p1,p2;
6682 53210 case (ClassInf.RECORD(p1),ClassInf.RECORD(p2)) then AbsynUtil.pathEqual(p1,p2);
6683 else true;
6684 end match;
6685 end classTypeEqualIfRecord;
6686
6687 public function ifExpMakeDimsUnknown "If one branch of an if-expression has truly unknown dimensions they both will need to return unknown dimensions for type-checking to work"
6688 input DAE.Type ty1;
6689 input DAE.Type ty2;
6690 output DAE.Type oty1;
6691 output DAE.Type oty2;
6692 algorithm
6693 (oty1,oty2) := match (ty1,ty2)
6694 local
6695 DAE.Type inner1,inner2;
6696 DAE.Dimension d1,d2;
6697 case (DAE.T_ARRAY(ty=inner1,dims={DAE.DIM_UNKNOWN()}),DAE.T_ARRAY(ty=inner2,dims={_}))
6698 algorithm
6699 ✗ (oty1,oty2) := ifExpMakeDimsUnknown(inner1,inner2);
6700 ✗ then (DAE.T_ARRAY(inner1,DAE.DIM_UNKNOWN()::{}),DAE.T_ARRAY(inner2,DAE.DIM_UNKNOWN()::{}));
6701 case (DAE.T_ARRAY(ty=inner1,dims={_}),DAE.T_ARRAY(ty=inner2,dims={DAE.DIM_UNKNOWN()}))
6702 algorithm
6703 ✗ (oty1,oty2) := ifExpMakeDimsUnknown(inner1,inner2);
6704 ✗ then (DAE.T_ARRAY(inner1,DAE.DIM_UNKNOWN()::{}),DAE.T_ARRAY(inner2,DAE.DIM_UNKNOWN()::{}));
6705 case (DAE.T_ARRAY(ty=inner1,dims={d1}),DAE.T_ARRAY(ty=inner2,dims={d2}))
6706 algorithm
6707 ✗ (oty1,oty2) := ifExpMakeDimsUnknown(inner1,inner2);
6708 ✗ then (DAE.T_ARRAY(inner1,{d1}),DAE.T_ARRAY(inner2,{d2}));
6709 else (ty1,ty2);
6710 end match;
6711 end ifExpMakeDimsUnknown;
6712
6713 public function isFixedWithNoBinding
6714 "check if the type has bindings for everything
6715 if is parameter or constant without fixed = false
6716 specified otherwise"
6717 input DAE.Type inTy;
6718 input SCode.Variability inVariability;
6719 output Boolean outFixed;
6720 algorithm
6721 outFixed := matchcontinue inTy
6722 local
6723 Boolean b;
6724 list<DAE.Var> vl;
6725
6726 case _
6727 algorithm
6728 // if this function doesn't fail return its value
6729 ✗ b := getFixedVarAttribute(inTy);
6730 then
6731 b;
6732
6733 case DAE.T_COMPLEX(varLst = vl)
6734 algorithm
6735 ✗ true := allHaveBindings(vl);
6736 then
6737 false;
6738
6739 // we couldn't get the fixed attribute
6740 // assume true for constants and parameters
6741 // false otherwise
6742 else
6743 algorithm
6744 ✗ b := listMember(inVariability, {SCode.PARAM(), SCode.CONST()});
6745 then
6746 b;
6747
6748 end matchcontinue;
6749 end isFixedWithNoBinding;
6750
6751 public function allHaveBindings
6752 input list<DAE.Var> inVars;
6753 output Boolean b;
6754 algorithm
6755 b := match inVars
6756 local
6757 DAE.Var v;
6758 list<DAE.Var> rest;
6759
6760 case {} then true;
6761
6762 case v::_ guard not hasBinding(v)
6763 then
6764 false;
6765
6766 case v::rest
6767 algorithm
6768
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7059 times.
7059 true := hasBinding(v);
6769
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7059 times.
7059 true := allHaveBindings(rest);
6770 then
6771 true;
6772
6773 end match;
6774 end allHaveBindings;
6775
6776 public function hasBinding
6777 input DAE.Var inVar;
6778 output Boolean b;
6779 algorithm
6780 b := match inVar
6781 case DAE.TYPES_VAR(binding = DAE.UNBOUND()) then false;
6782 else true;
6783 end match;
6784 end hasBinding;
6785
6786 public function typeErrorSanityCheck
6787 input String inType1;
6788 input String inType2;
6789 input SourceInfo inInfo;
6790 algorithm
6791
3/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 18203 times.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
18204 if stringEq(inType1, inType2) then
6792 ✗ Error.addSourceMessage(Error.ERRONEOUS_TYPE_ERROR, {inType1}, inInfo);
6793 ✗ fail();
6794 end if;
6795 end typeErrorSanityCheck;
6796
6797 public function dimNotFixed
6798 input DAE.Dimension dim;
6799 output Boolean b;
6800 algorithm
6801 b := match dim
6802 case DAE.DIM_UNKNOWN() then true;
6803 case DAE.DIM_EXP() then true;
6804 else false;
6805 end match;
6806 end dimNotFixed;
6807
6808 function isArrayWithUnknownDimension
6809 input DAE.Type ty;
6810 output Boolean b;
6811 algorithm
6812 b := match ty
6813
4/4
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 61 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 61 times.
133 case DAE.T_ARRAY() then max(
6814 match d case DAE.DIM_UNKNOWN() then true; else false; end match
6815 for d in TypesDump.getDimensions(ty));
6816 else false;
6817 end match;
6818 end isArrayWithUnknownDimension;
6819
6820 public function setTypeVars
6821 input output DAE.Type ty;
6822 input list<DAE.Var> inVars;
6823 algorithm
6824 ty := match ty
6825 case DAE.T_REAL()
6826 algorithm
6827 383227 ty.varLst := inVars;
6828 then ty;
6829 case DAE.T_INTEGER()
6830 algorithm
6831 14549 ty.varLst := inVars;
6832 then ty;
6833 case DAE.T_STRING()
6834 algorithm
6835 27957 ty.varLst := inVars;
6836 then ty;
6837 case DAE.T_BOOL()
6838 algorithm
6839 29796 ty.varLst := inVars;
6840 then ty;
6841 case DAE.T_CLOCK()
6842 algorithm
6843 26 ty.varLst := inVars;
6844 then ty;
6845 case DAE.T_ENUMERATION()
6846 algorithm
6847 ✗ ty.attributeLst := inVars;
6848 then ty;
6849 case DAE.T_ARRAY()
6850 algorithm
6851 ✗ ty.ty := setTypeVars(ty.ty, inVars);
6852 then ty;
6853 case DAE.T_SUBTYPE_BASIC()
6854 algorithm
6855 ✗ ty.complexType := setTypeVars(ty.complexType, inVars);
6856 then ty;
6857 end match;
6858 end setTypeVars;
6859
6860 public function isEmptyOrNoRetcall
6861 input DAE.Type ty;
6862 output Boolean b;
6863 algorithm
6864 b := match ty
6865 case DAE.T_TUPLE(types={}) then true;
6866 case DAE.T_METATUPLE(types={}) then true;
6867 case DAE.T_NORETCALL() then true;
6868 else false;
6869 end match;
6870 end isEmptyOrNoRetcall;
6871
6872 protected function typeConvertIntToEnumCheck "
6873 Deal with the invalid conversions from Integer to enumeration.
6874 If the Integer corresponds to the Integer(ENUM) value of some enumeration constant ENUM,
6875 just give a warning, otherwise report an error.
6876 Returns false if an error was reported, otherwise true.
6877 "
6878 input DAE.Exp exp;
6879 input DAE.Type expected;
6880 output Boolean conversionOK;
6881 algorithm
6882 conversionOK := matchcontinue (exp, expected)
6883 local
6884 Integer oi;
6885 Absyn.Path tp;
6886 list<String> l;
6887 String pathStr, intStr, enumConst, lengthStr;
6888 case (DAE.ICONST(oi),
6889 DAE.T_ENUMERATION(path = tp, names = l))
6890 algorithm
6891
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
7 true := (1 <= oi and oi <= listLength(l));
6892 7 pathStr := AbsynUtil.pathString(tp);
6893 7 intStr := intString(oi);
6894 7 enumConst := listGet(l, oi);
6895 7 Error.addMessage(Error.INTEGER_ENUMERATION_CONVERSION_WARNING, {intStr, pathStr, enumConst});
6896 then true;
6897 case (DAE.ICONST(oi),
6898 DAE.T_ENUMERATION(path = tp, names = l))
6899 algorithm
6900 ✗ pathStr := AbsynUtil.pathString(tp);
6901 ✗ false := stringEq(pathStr, "");
6902 ✗ intStr := intString(oi);
6903 ✗ lengthStr := intString(listLength(l));
6904 ✗ Error.addMessage(Error.INTEGER_ENUMERATION_OUT_OF_RANGE, {pathStr, intStr, lengthStr});
6905 then false;
6906 case (DAE.ICONST(oi),
6907 DAE.T_ENUMERATION(path = tp))
6908 algorithm
6909 ✗ pathStr := AbsynUtil.pathString(tp);
6910 ✗ true := stringEq(pathStr, "");
6911 ✗ intStr := intString(oi);
6912 ✗ Error.addMessage(Error.INTEGER_TO_UNKNOWN_ENUMERATION, {intStr});
6913 then false;
6914 end matchcontinue;
6915 end typeConvertIntToEnumCheck;
6916
6917 public function findVarIndex
6918 input String id;
6919 input list<DAE.Var> vars;
6920 output Integer index;
6921 algorithm
6922 2253 index := List.position1OnTrue(vars,selectVar,id)-1 "shift to zero-based index";
6923 end findVarIndex;
6924
6925 protected function selectVar
6926 input DAE.Var var;
6927 input String id;
6928 output Boolean b;
6929 algorithm
6930 b := match var
6931 local
6932 String id1;
6933
4/4
✓ Branch 0 taken 2554 times.
✓ Branch 1 taken 2104 times.
✓ Branch 3 taken 301 times.
✓ Branch 4 taken 2253 times.
4658 case DAE.TYPES_VAR(name=id1) then stringEq(id,id1);
6934 else false;
6935 end match;
6936 end selectVar;
6937
6938 public function getUniontypeIfMetarecord
6939 input DAE.Type inTy;
6940 output DAE.Type ty;
6941 algorithm
6942 ty := match inTy
6943 local
6944 Boolean b;
6945 Absyn.Path p;
6946 ✗ case DAE.T_METARECORD(utPath=p,knownSingleton=b) then DAE.T_METAUNIONTYPE({},inTy.typeVars,b,if b then DAE.EVAL_SINGLETON_KNOWN_TYPE(inTy) else DAE.NOT_SINGLETON(),p);
6947 else inTy;
6948 end match;
6949 end getUniontypeIfMetarecord;
6950
6951 public function getUniontypeIfMetarecordReplaceAllSubtypes
6952 input DAE.Type inTy;
6953 output DAE.Type ty;
6954 algorithm
6955 269744 (ty,_) := traverseType(inTy, 1, getUniontypeIfMetarecordTraverse);
6956 end getUniontypeIfMetarecordReplaceAllSubtypes;
6957
6958 protected function getUniontypeIfMetarecordTraverse
6959 input DAE.Type ty;
6960 input Integer dummy;
6961 output DAE.Type oty;
6962 output Integer odummy = dummy;
6963 algorithm
6964 oty := match ty
6965
2/2
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 17279 times.
17890 case DAE.T_METARECORD() then DAE.T_METAUNIONTYPE({},ty.typeVars,ty.knownSingleton,if ty.knownSingleton then DAE.EVAL_SINGLETON_KNOWN_TYPE(ty) else DAE.NOT_SINGLETON(),ty.utPath);
6966 else ty;
6967 end match;
6968 end getUniontypeIfMetarecordTraverse;
6969
6970 protected function isBuiltin
6971 input DAE.FunctionBuiltin a;
6972 output Boolean b;
6973 algorithm
6974 b := match a
6975 case DAE.FUNCTION_NOT_BUILTIN() then false;
6976 else true;
6977 end match;
6978 end isBuiltin;
6979
6980 public function makeCallAttr
6981 input DAE.Type ty;
6982 input DAE.FunctionAttributes attr;
6983 output DAE.CallAttributes callAttr;
6984 protected
6985 Boolean isImpure,isT,isB;
6986 algorithm
6987 165 isT := isTuple(ty);
6988 165 isB := isBuiltin(attr.isBuiltin);
6989 165 isImpure := attr.purity == DAE.Purity.IMPURE;
6990
3/6
✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 165 times.
✗ Branch 5 not taken.
660 callAttr := DAE.CALL_ATTR(ty,isT,isB,isImpure,false,attr.inline,DAE.NO_TAIL(),DAE.NoReturn.RETURNS);
6991 end makeCallAttr;
6992
6993 public function builtinName
6994 input DAE.FunctionBuiltin isbuiltin;
6995 output Option<String> name;
6996 algorithm
6997 ✗ name := match isbuiltin case DAE.FUNCTION_BUILTIN() then isbuiltin.name; else NONE(); end match;
6998 end builtinName;
6999
7000 public function getFuncArg
7001 input DAE.Type ty;
7002 output list<DAE.FuncArg> args;
7003 algorithm
7004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 DAE.T_FUNCTION(funcArg=args) := ty;
7005 end getFuncArg;
7006
7007 public function isArray1D
7008 input DAE.Type inType;
7009 output Boolean b;
7010 algorithm
7011 b := match inType
7012 local
7013 DAE.Type ty;
7014 ✗ case DAE.T_ARRAY(ty = ty) then not arrayType(ty);
7015 else false;
7016 end match;
7017 end isArray1D;
7018
7019 public function isArray2D
7020 input DAE.Type inType;
7021 output Boolean b;
7022 algorithm
7023 b := match inType
7024 local
7025 DAE.Type ty;
7026 ✗ case DAE.T_ARRAY(ty = DAE.T_ARRAY(ty = ty)) then not arrayType(ty);
7027 else false;
7028 end match;
7029 end isArray2D;
7030
7031 public function funcArgName
7032 input DAE.FuncArg arg;
7033 output String name;
7034 algorithm
7035 ✗ DAE.FUNCARG(name=name) := arg;
7036 end funcArgName;
7037
7038 public function funcArgType
7039 input DAE.FuncArg arg;
7040 output DAE.Type ty;
7041 algorithm
7042 385333 DAE.FUNCARG(ty=ty) := arg;
7043 end funcArgType;
7044
7045 public function funcArgDefaultBinding
7046 input DAE.FuncArg arg;
7047 output Option<DAE.Exp> defaultBinding;
7048 algorithm
7049 12 DAE.FUNCARG(defaultBinding=defaultBinding) := arg;
7050 end funcArgDefaultBinding;
7051
7052 public function setFuncArgType
7053 input DAE.FuncArg arg;
7054 input DAE.Type ty;
7055 output DAE.FuncArg outArg;
7056 protected
7057 String name;
7058 DAE.Const const;
7059 DAE.VarParallelism par;
7060 Option<DAE.Exp> defaultBinding;
7061 algorithm
7062 203770 DAE.FUNCARG(name,_,const,par,defaultBinding) := arg;
7063 203770 outArg := DAE.FUNCARG(name,ty,const,par,defaultBinding);
7064 end setFuncArgType;
7065
7066 public function setFuncArgName
7067 input DAE.FuncArg arg;
7068 input String name;
7069 output DAE.FuncArg outArg;
7070 protected
7071 DAE.Type ty;
7072 DAE.Const const;
7073 DAE.VarParallelism par;
7074 Option<DAE.Exp> defaultBinding;
7075 algorithm
7076 168 DAE.FUNCARG(_,ty,const,par,defaultBinding) := arg;
7077 168 outArg := DAE.FUNCARG(name,ty,const,par,defaultBinding);
7078 end setFuncArgName;
7079
7080 public function clearDefaultBinding
7081 input DAE.FuncArg arg;
7082 output DAE.FuncArg outArg;
7083 protected
7084 String name;
7085 DAE.Type ty;
7086 DAE.Const const;
7087 DAE.VarParallelism par;
7088 algorithm
7089 6 DAE.FUNCARG(name,ty,const,par,_) := arg;
7090 6 outArg := DAE.FUNCARG(name,ty,const,par,NONE());
7091 end clearDefaultBinding;
7092
7093 public function makeDefaultFuncArg
7094 input String name;
7095 input DAE.Type ty;
7096 output DAE.FuncArg arg;
7097 algorithm
7098 38842 arg := DAE.FUNCARG(name,ty,DAE.C_VAR(),DAE.NON_PARALLEL(),NONE());
7099 end makeDefaultFuncArg;
7100
7101 public function setIsFunctionPointer
7102 input DAE.Type ty;
7103 input Integer dummy;
7104 output DAE.Type oty = ty;
7105 output Integer odummy = dummy;
7106 algorithm
7107 oty := match oty
7108 local
7109 DAE.FunctionAttributes attr;
7110 case DAE.T_FUNCTION(functionAttributes=attr as DAE.FUNCTION_ATTRIBUTES(isFunctionPointer=false))
7111 algorithm
7112 704 attr.isFunctionPointer := true;
7113 704 oty.functionAttributes := attr;
7114 then oty;
7115 else oty;
7116 end match;
7117 end setIsFunctionPointer;
7118
7119 public function isFunctionReferenceVar
7120 input DAE.Type ty;
7121 output Boolean b;
7122 algorithm
7123 b := match ty
7124 case DAE.T_FUNCTION_REFERENCE_VAR() then true;
7125 else false;
7126 end match;
7127 end isFunctionReferenceVar;
7128
7129 public function isFunctionPointer
7130 input DAE.Type inType;
7131 output Boolean outIsFunPtr;
7132 algorithm
7133 outIsFunPtr := match inType
7134 case DAE.T_FUNCTION(functionAttributes =
7135 DAE.FUNCTION_ATTRIBUTES(isFunctionPointer = true)) then true;
7136 else false;
7137 end match;
7138 end isFunctionPointer;
7139
7140 public function filterRecordComponents
7141 input list<DAE.Var> inRecordVars;
7142 input SourceInfo inInfo;
7143 output list<DAE.Var> outRecordVars;
7144 algorithm
7145
4/4
✓ Branch 0 taken 33658 times.
✓ Branch 1 taken 3514 times.
✓ Branch 2 taken 33658 times.
✓ Branch 3 taken 3514 times.
37172 outRecordVars := list(match v case DAE.TYPES_VAR()
7146 algorithm
7147
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33658 times.
33658 if not allowedInRecord(v.ty) then
7148 ✗ Error.addSourceMessage(Error.ILLEGAL_RECORD_COMPONENT, {TypesDump.unparseVar(v)}, inInfo);
7149 ✗ fail();
7150 end if;
7151 then v;
7152 end match for v in inRecordVars
7153 );
7154 end filterRecordComponents;
7155
7156 public function allowedInRecord
7157 input DAE.Type ty;
7158 output Boolean yes;
7159 algorithm
7160 yes := matchcontinue ty
7161 local DAE.Type t;
7162
7163 // basic types, records or arrays of the same
7164 case _
7165 algorithm
7166 33658 t := arrayElementType(ty);
7167
3/6
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 33626 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
33658 true := basicType(t) or isRecord(t) or extendsBasicType(t);
7168 then
7169 true;
7170
7171 // nothing else please!
7172 else false;
7173
7174 end matchcontinue;
7175 end allowedInRecord;
7176
7177 public function lookupIndexInMetaRecord
7178 input list<DAE.Var> vars;
7179 input String name;
7180 output Integer index;
7181 algorithm
7182 29 index := List.position1OnTrue(vars, DAEUtil.typeVarIdentEqual, name);
7183 end lookupIndexInMetaRecord;
7184
7185 function checkEnumDuplicateLiterals
7186 input list<String> names;
7187 input Absyn.Info info;
7188 protected
7189 list<String> sortedNames;
7190 algorithm
7191 // Sort+uniq = O(n*log(n)); naive way to check duplicates is O(n*n) but might be faster...
7192 4512 sortedNames := List.sort(names,Util.strcmpBool);
7193
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4512 times.
4512 if not List.sortedListAllUnique(sortedNames, stringEq) then
7194 ✗ Error.addSourceMessage(Error.ENUM_DUPLICATES, {stringDelimitList(List.sortedUniqueOnlyDuplicates(sortedNames, stringEq), ","), stringDelimitList(names, ",")}, info);
7195 ✗ fail();
7196 end if;
7197 end checkEnumDuplicateLiterals;
7198
7199 public function checkTypeCompat
7200 "This function checks that two types are compatible, as per the definition of
7201 type compatible expressions in the specification. If needed it also does type
7202 casting to make the expressions compatible. If the types are compatible it
7203 returns the compatible type, otherwise the type returned is undefined."
7204 input DAE.Exp inExp1;
7205 input DAE.Type inType1;
7206 input DAE.Exp inExp2;
7207 input DAE.Type inType2;
7208 input Boolean inAllowUnknown = false;
7209 output DAE.Exp outExp1 = inExp1;
7210 output DAE.Exp outExp2 = inExp2;
7211 output DAE.Type outCompatType;
7212 output Boolean outCompatible = true;
7213 protected
7214 DAE.Type ty1, ty2;
7215 algorithm
7216 // Return true if the references are the same.
7217
2/2
✓ Branch 0 taken 1672 times.
✓ Branch 1 taken 8417 times.
10089 if referenceEq(inType1, inType2) then
7218 1672 outCompatType := inType1;
7219 1672 return;
7220 end if;
7221
7222 // Check if the types are different kinds of types.
7223
2/2
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 7595 times.
8417 if valueConstructor(inType1) <> valueConstructor(inType2) then
7224
3/4
✓ Branch 1 taken 822 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 821 times.
822 if extendsBasicType(inType1) or extendsBasicType(inType2) then
7225 // If either type extends a basic type, check the basic type instead.
7226 1 ty1 := derivedBasicType(inType1);
7227 1 ty2 := derivedBasicType(inType2);
7228 1 (outExp1, outExp2, outCompatType, outCompatible) :=
7229 checkTypeCompat(inExp1, ty1, inExp2, ty2);
7230 else
7231 // If the types are not of the same kind they might need to be type cast
7232 // to become compatible.
7233 821 (outExp1, outExp2, outCompatType, outCompatible) :=
7234 checkTypeCompat_cast(inExp1, inType1, inExp2, inType2, inAllowUnknown);
7235 end if;
7236
7237 // Regardless of the chosen branch above, we are done here.
7238 822 return;
7239 end if;
7240
7241 // The types are of the same kind, so we only need to match on one of them
7242 // (which is a lot more efficient than matching both).
7243 outCompatType := match inType1
7244 local
7245 list<DAE.Dimension> dims1, dims2;
7246 DAE.Type ety1, ety2, ty;
7247 list<String> names;
7248 list<DAE.Var> vars;
7249 list<FuncArg> args;
7250 list<DAE.Type> tys, tys2;
7251 String name;
7252 Absyn.Path p1, p2;
7253
7254 // Basic types, must be the same.
7255 case DAE.T_INTEGER() then DAE.T_INTEGER_DEFAULT;
7256 case DAE.T_REAL() then DAE.T_REAL_DEFAULT;
7257 case DAE.T_STRING() then DAE.T_STRING_DEFAULT;
7258 case DAE.T_BOOL() then DAE.T_BOOL_DEFAULT;
7259 case DAE.T_CLOCK() then DAE.T_CLOCK_DEFAULT;
7260
7261 case DAE.T_SUBTYPE_BASIC()
7262 algorithm
7263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 DAE.T_SUBTYPE_BASIC(complexType = ty) := inType2;
7264 2 (outExp1, outExp2, outCompatType, outCompatible) :=
7265 checkTypeCompat(inExp1, inType1.complexType, inExp2, ty);
7266 2 then
7267 outCompatType;
7268
7269 // Enumerations, check that they have same literals.
7270 case DAE.T_ENUMERATION()
7271 algorithm
7272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2276 times.
2276 DAE.T_ENUMERATION(names = names) := inType2;
7273 2276 outCompatible := List.isEqualOnTrue(inType1.names, names, stringEq);
7274 then
7275 inType1;
7276
7277 // Arrays, must have compatible element types and dimensions.
7278 case DAE.T_ARRAY()
7279 algorithm
7280 // Check that the element types are compatible.
7281 647 ety1 := arrayElementType(inType1);
7282 647 ety2 := arrayElementType(inType2);
7283 647 (outExp1, outExp2, outCompatType, outCompatible) :=
7284 checkTypeCompat(inExp1, ety1, inExp2, ety2);
7285
7286 // If the element types are compatible, check the dimensions too.
7287
1/2
✓ Branch 0 taken 647 times.
✗ Branch 1 not taken.
647 if outCompatible then
7288 647 dims1 := TypesDump.getDimensions(inType1);
7289 647 dims2 := TypesDump.getDimensions(inType2);
7290
7291 // The arrays must have the same number of dimensions.
7292
1/2
✓ Branch 2 taken 647 times.
✗ Branch 3 not taken.
647 if listLength(dims1) == listLength(dims2) then
7293
9/10
✓ Branch 0 taken 686 times.
✓ Branch 1 taken 647 times.
✓ Branch 2 taken 686 times.
✓ Branch 3 taken 647 times.
✓ Branch 4 taken 686 times.
✓ Branch 5 taken 647 times.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 676 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 647 times.
1333 dims1 := list(if Expression.dimensionsKnownAndEqual(dim1, dim2) then
7294 dim1 else DAE.DIM_UNKNOWN() threaded for dim1 in dims1, dim2 in dims2);
7295 647 outCompatType := liftArrayListDims(outCompatType, dims1);
7296 else
7297 ✗ outCompatible := false;
7298 end if;
7299 end if;
7300 647 then
7301 outCompatType;
7302
7303 // Records, must have the same components.
7304 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD())
7305 algorithm
7306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
91 DAE.T_COMPLEX(varLst = vars) := inType2;
7307 // TODO: Implement type casting for records with the same components but
7308 // in different order.
7309 91 outCompatible := List.isEqualOnTrue(inType1.varLst, vars, varEqualName);
7310 then
7311 inType1;
7312
7313 case DAE.T_FUNCTION()
7314 algorithm
7315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 DAE.T_FUNCTION(funcResultType = ty, funcArg = args) := inType2;
7316 2 (outExp1, outExp2, outCompatType, outCompatible) :=
7317 checkTypeCompat(inExp1, inType1.funcResultType, inExp2, ty);
7318
7319
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if outCompatible then
7320
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
6 tys := list(funcArgType(arg) for arg in inType1.funcArg);
7321
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
6 tys2 := list(funcArgType(arg) for arg in args);
7322 2 (_, outCompatible) := checkTypeCompatList(inExp1, tys, inExp2, tys2);
7323 end if;
7324 then
7325 inType1;
7326
7327 case DAE.T_TUPLE()
7328 algorithm
7329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 DAE.T_TUPLE(types = tys) := inType2;
7330 2 (tys, outCompatible) :=
7331 checkTypeCompatList(inExp1, inType1.types, inExp2, tys);
7332 2 then
7333 DAE.T_TUPLE(tys, inType1.names);
7334
7335 // MetaModelica types.
7336 case DAE.T_METALIST()
7337 algorithm
7338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 DAE.T_METALIST(ty = ty) := inType2;
7339 //print("List(" + anyString(inType1.ty) + "), List(" + anyString(ty) + ")\n");
7340 49 (outExp1, outExp2, outCompatType, outCompatible) :=
7341 checkTypeCompat(inExp1, inType1.ty, inExp2, ty, true);
7342 49 then DAE.T_METALIST(outCompatType);
7343
7344 case DAE.T_METAARRAY()
7345 algorithm
7346 ✗ DAE.T_METAARRAY(ty = ty) := inType2;
7347 ✗ (outExp1, outExp2, outCompatType, outCompatible) :=
7348 checkTypeCompat(inExp1, inType1.ty, inExp2, ty, true);
7349 ✗ then DAE.T_METAARRAY(outCompatType);
7350
7351 case DAE.T_METAOPTION()
7352 algorithm
7353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 DAE.T_METAOPTION(ty = ty) := inType2;
7354 8 (outExp1, outExp2, outCompatType, outCompatible) :=
7355 checkTypeCompat(inExp1, inType1.ty, inExp2, ty, true);
7356 8 then DAE.T_METAOPTION(outCompatType);
7357
7358 case DAE.T_METATUPLE()
7359 algorithm
7360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 DAE.T_METATUPLE(types = tys) := inType2;
7361 16 (tys, outCompatible) :=
7362 checkTypeCompatList(inExp1, inType1.types, inExp2, tys);
7363 16 then DAE.T_METATUPLE(tys);
7364
7365 case DAE.T_METABOXED()
7366 algorithm
7367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 DAE.T_METABOXED(ty = ty) := inType2;
7368 14 (outExp1, outExp2, outCompatType, outCompatible) :=
7369 checkTypeCompat(inExp1, inType1.ty, inExp2, ty);
7370 14 then DAE.T_METABOXED(outCompatType);
7371
7372 case DAE.T_METAPOLYMORPHIC()
7373 algorithm
7374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 DAE.T_METAPOLYMORPHIC(name = name) := inType2;
7375
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 outCompatible := inType1.name == name;
7376 then inType1;
7377
7378 case DAE.T_METAUNIONTYPE(path = p1)
7379 algorithm
7380
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 DAE.T_METAUNIONTYPE(path = p2) := inType2;
7381 23 outCompatible := AbsynUtil.pathEqual(p1, p2);
7382 then inType1;
7383
7384 case DAE.T_METARECORD(utPath = p1)
7385 algorithm
7386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
137 DAE.T_METARECORD(utPath = p2) := inType2;
7387 137 outCompatible := AbsynUtil.pathEqual(p1, p2);
7388 then
7389 inType1;
7390
7391 case DAE.T_FUNCTION_REFERENCE_VAR()
7392 algorithm
7393 ✗ DAE.T_FUNCTION_REFERENCE_VAR(functionType = ty) := inType2;
7394 ✗ (outExp1, outExp2, outCompatType, outCompatible) :=
7395 checkTypeCompat(inExp1, inType1.functionType, inExp2, ty);
7396 ✗ then
7397 DAE.T_FUNCTION_REFERENCE_VAR(outCompatType);
7398
7399 else
7400 algorithm
7401 ✗ outCompatible := false;
7402 then
7403 DAE.T_UNKNOWN_DEFAULT;
7404
7405 end match;
7406 end checkTypeCompat;
7407
7408 protected function checkTypeCompatList
7409 "Checks that two lists of types are compatible using checkTypeCompat."
7410 input DAE.Exp inExp1;
7411 input list<DAE.Type> inTypes1;
7412 input DAE.Exp inExp2;
7413 input list<DAE.Type> inTypes2;
7414 output list<DAE.Type> outCompatibleTypes = {};
7415 output Boolean outCompatible = true;
7416 protected
7417 DAE.Type ty2;
7418 list<DAE.Type> rest_ty2 = inTypes2;
7419 Boolean compat;
7420 algorithm
7421
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 if listLength(inTypes1) <> listLength(inTypes2) then
7422 outCompatible := false;
7423 ✗ return;
7424 end if;
7425
7426
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 20 times.
61 for ty1 in inTypes1 loop
7427
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 ty2 :: rest_ty2 := rest_ty2;
7428 // Ignore the returned expressions. This function is used for tuples, and
7429 // it's not clear how tuples should be type converted. So we only check that
7430 // the types are compatible and hope for the best.
7431 41 (_, _, ty2, compat) := checkTypeCompat(inExp1, ty1, inExp2, ty2);
7432
7433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if not compat then
7434 outCompatible := false;
7435 ✗ return;
7436 end if;
7437
7438 41 outCompatibleTypes := ty2 :: outCompatibleTypes;
7439 end for;
7440
7441 20 outCompatibleTypes := listReverse(outCompatibleTypes);
7442 end checkTypeCompatList;
7443
7444 protected function checkTypeCompat_cast
7445 "Helper function to checkTypeCompat. Tries to type cast one of the given
7446 expressions so that they become type compatible."
7447 input DAE.Exp inExp1;
7448 input DAE.Type inType1;
7449 input DAE.Exp inExp2;
7450 input DAE.Type inType2;
7451 input Boolean inAllowUnknown;
7452 output DAE.Exp outExp1 = inExp1;
7453 output DAE.Exp outExp2 = inExp2;
7454 output DAE.Type outCompatType;
7455 output Boolean outCompatible = true;
7456 protected
7457 DAE.Type ty1, ty2;
7458 Absyn.Path path;
7459 algorithm
7460 821 ty1 := derivedBasicType(inType1);
7461 821 ty2 := derivedBasicType(inType2);
7462
7463 outCompatType := match(ty1, ty2)
7464 // Real <-> Integer
7465 case (DAE.T_REAL(), DAE.T_INTEGER())
7466 algorithm
7467 438 outExp2 := Expression.typeCastElements(inExp2, DAE.T_REAL_DEFAULT);
7468 then
7469 DAE.T_REAL_DEFAULT;
7470
7471 case (DAE.T_INTEGER(), DAE.T_REAL())
7472 algorithm
7473 350 outExp1 := Expression.typeCastElements(inExp1, DAE.T_REAL_DEFAULT);
7474 then
7475 DAE.T_REAL_DEFAULT;
7476
7477 // If one of the expressions is boxed, unbox it.
7478 case (DAE.T_METABOXED(), _)
7479 algorithm
7480 3 (outExp1, outExp2, outCompatType, outCompatible) :=
7481 checkTypeCompat(inExp1, ty1.ty, inExp2, ty2, inAllowUnknown);
7482
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
3 outExp1 := if isBoxedType(ty2) then outExp1 else DAE.UNBOX(outExp1, outCompatType);
7483 then
7484 ty2;
7485
7486 case (_, DAE.T_METABOXED())
7487 algorithm
7488 1 (outExp1, outExp2, outCompatType, outCompatible) :=
7489 checkTypeCompat(inExp1, ty1, inExp2, ty2.ty, inAllowUnknown);
7490
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 outExp2 := if isBoxedType(ty1) then outExp2 else DAE.UNBOX(outExp2, outCompatType);
7491 then
7492 ty1;
7493
7494 // Expressions such as Absyn.IDENT gets the type T_METARECORD(Absyn.Path.IDENT)
7495 // instead of UNIONTYPE(Absyn.Path), but e.g. a function returning an
7496 // Absyn.PATH has the type UNIONTYPE(Absyn.PATH). So we'll just pretend that
7497 // metarecords actually have uniontype type.
7498 case (DAE.T_METARECORD(), DAE.T_METAUNIONTYPE())
7499 algorithm
7500 12 outCompatible := AbsynUtil.pathEqual(ty1.utPath, ty2.path);
7501 then
7502 ty2;
7503
7504 case (DAE.T_METAUNIONTYPE(), DAE.T_METARECORD())
7505 algorithm
7506 9 outCompatible := AbsynUtil.pathEqual(ty1.path, ty2.utPath);
7507 then
7508 ty1;
7509
7510 // Allow unknown types in some cases, e.g. () has type T_METALIST(T_UNKNOWN)
7511 case (DAE.T_UNKNOWN(), _)
7512 algorithm
7513 7 outCompatible := inAllowUnknown;
7514 then
7515 ty2;
7516
7517 case (_, DAE.T_UNKNOWN())
7518 algorithm
7519 //print("Unknown(" + boolString(inAllowUnknown) + ")\n");
7520 1 outCompatible := inAllowUnknown;
7521 then
7522 ty1;
7523
7524 // Anything else is not compatible.
7525 else
7526 algorithm
7527 ✗ outCompatible := false;
7528 then
7529 DAE.T_UNKNOWN_DEFAULT;
7530
7531 end match;
7532 end checkTypeCompat_cast;
7533
7534 public function arrayHasUnknownDims
7535 "Checks if an array type has dimensions which are unknown."
7536 input DAE.Type inType;
7537 output Boolean outUnknownDims;
7538 algorithm
7539 outUnknownDims := match inType
7540 case DAE.T_ARRAY()
7541
3/4
✓ Branch 1 taken 678 times.
✓ Branch 2 taken 27 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 678 times.
705 then List.any(inType.dims, Expression.dimensionUnknown) or
7542 arrayHasUnknownDims(inType.ty);
7543
7544 else false;
7545 end match;
7546 end arrayHasUnknownDims;
7547
7548 public function metaArrayElementType
7549 input DAE.Type inType;
7550 output DAE.Type outType;
7551 algorithm
7552 outType := match inType
7553 134 case DAE.T_METAARRAY() then inType.ty;
7554 ✗ case DAE.T_METATYPE() then metaArrayElementType(inType.ty);
7555 end match;
7556 end metaArrayElementType;
7557
7558 public function isMetaArray
7559 input DAE.Type inType;
7560 output Boolean b;
7561 algorithm
7562 b := match inType
7563 case DAE.T_METAARRAY() then true;
7564 213 case DAE.T_METATYPE() then isMetaArray(inType.ty);
7565 else false;
7566 end match;
7567 end isMetaArray;
7568
7569 public function getAttributes
7570 input DAE.Type inType;
7571 output list<DAE.Var> outAttributes;
7572 algorithm
7573 outAttributes := match inType
7574 344 case DAE.T_REAL() then inType.varLst;
7575 ✗ case DAE.T_INTEGER() then inType.varLst;
7576 ✗ case DAE.T_STRING() then inType.varLst;
7577 ✗ case DAE.T_BOOL() then inType.varLst;
7578 ✗ case DAE.T_ENUMERATION() then inType.attributeLst;
7579 ✗ case DAE.T_SUBTYPE_BASIC() then getAttributes(inType.complexType);
7580 else {};
7581 end match;
7582 end getAttributes;
7583
7584 public function lookupAttributeValue
7585 input list<DAE.Var> inAttributes;
7586 input String inName;
7587 output Option<Values.Value> outValue = NONE();
7588 algorithm
7589
1/2
✓ Branch 0 taken 78 times.
✗ Branch 1 not taken.
78 for attr in inAttributes loop
7590
4/4
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 30 times.
✓ Branch 5 taken 32 times.
✓ Branch 6 taken 16 times.
78 if inName == TypesDump.getVarName(attr) then
7591 32 outValue := DAEUtil.bindingValue(varBinding(attr));
7592 32 break;
7593 end if;
7594 end for;
7595 end lookupAttributeValue;
7596
7597 public function lookupAttributeExp
7598 input list<DAE.Var> inAttributes;
7599 input String inName;
7600 output Option<DAE.Exp> outExp = NONE();
7601 algorithm
7602
2/2
✓ Branch 0 taken 808 times.
✓ Branch 1 taken 146 times.
954 for attr in inAttributes loop
7603
4/4
✓ Branch 1 taken 291 times.
✓ Branch 2 taken 517 times.
✓ Branch 5 taken 180 times.
✓ Branch 6 taken 111 times.
808 if inName == TypesDump.getVarName(attr) then
7604 180 outExp := DAEUtil.bindingExp(varBinding(attr));
7605 180 break;
7606 end if;
7607 end for;
7608 end lookupAttributeExp;
7609
7610 protected function unboxedTypeTraverseHelper<T>
7611 input DAE.Type ty;
7612 input T dummy;
7613 output DAE.Type oty = unboxedType(ty);
7614 output T odummy = dummy;
7615 end unboxedTypeTraverseHelper;
7616
7617 public function getMetaRecordFields
7618 input DAE.Type ty;
7619 output list<DAE.Var> fields;
7620 algorithm
7621 fields := match ty
7622 local
7623 DAE.EvaluateSingletonTypeFunction fun;
7624 case DAE.T_METARECORD(fields=fields) then fields;
7625 case DAE.T_METAUNIONTYPE(knownSingleton=false)
7626 algorithm
7627 ✗ Error.addInternalError(getInstanceName() + " called on a non-singleton uniontype: " + TypesDump.unparseType(ty), sourceInfo());
7628 ✗ then fail();
7629 case DAE.T_METAUNIONTYPE(singletonType=DAE.EVAL_SINGLETON_KNOWN_TYPE(ty=DAE.T_METARECORD(fields=fields))) then fields;
7630 case DAE.T_METAUNIONTYPE(singletonType=DAE.EVAL_SINGLETON_TYPE_FUNCTION(fun=fun))
7631 algorithm
7632
2/4
✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 416 times.
416 DAE.T_METARECORD(fields=fields) := fun();
7633 then fields;
7634 else
7635 algorithm
7636 ✗ Error.addInternalError(getInstanceName() + " called on a non-singleton uniontype: " + TypesDump.unparseType(ty), sourceInfo());
7637 ✗ then fail();
7638 end match;
7639 end getMetaRecordFields;
7640
7641 public function getMetaRecordIfSingleton
7642 input DAE.Type ty;
7643 output DAE.Type oty;
7644 algorithm
7645 oty := match ty
7646 local
7647 DAE.EvaluateSingletonTypeFunction fun;
7648 case DAE.T_METAUNIONTYPE(knownSingleton=false) then ty;
7649 ✗ case DAE.T_METAUNIONTYPE(singletonType=DAE.EVAL_SINGLETON_KNOWN_TYPE(ty=oty)) then setTypeVariables(oty, ty.typeVars);
7650 case DAE.T_METAUNIONTYPE(singletonType=DAE.EVAL_SINGLETON_TYPE_FUNCTION(fun=fun))
7651 algorithm
7652
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 oty := fun();
7653 50 then setTypeVariables(oty, ty.typeVars);
7654 else ty;
7655 end match;
7656 end getMetaRecordIfSingleton;
7657
7658 public function setTypeVariables
7659 input DAE.Type ty;
7660 input list<DAE.Type> typeVars;
7661 output DAE.Type oty;
7662 algorithm
7663 oty := match ty
7664 case oty as DAE.T_METAUNIONTYPE()
7665 algorithm
7666 98 oty.typeVars := typeVars;
7667 then oty;
7668 case oty as DAE.T_METARECORD()
7669 algorithm
7670 50 oty.typeVars := typeVars;
7671 then oty;
7672 else ty;
7673 end match;
7674 end setTypeVariables;
7675
7676 public function isExpandableConnector
7677 "@author: adrpo
7678 this function checks if the given type is an expandable connector"
7679 input DAE.Type ty;
7680 output Boolean isExpandable;
7681 algorithm
7682 isExpandable := match ty
7683 case DAE.T_COMPLEX(complexClassType = ClassInf.CONNECTOR(_,true)) then true;
7684 // TODO! check if subtype is needed here
7685 case DAE.T_SUBTYPE_BASIC(complexClassType = ClassInf.CONNECTOR(_,true)) then true;
7686 else false;
7687 end match;
7688 end isExpandableConnector;
7689
7690 public function getBasicType
7691 input DAE.Type ty;
7692 output DAE.Type outType;
7693 algorithm
7694 outType := match ty
7695 13 case DAE.Type.T_ARRAY() then getBasicType(ty.ty);
7696 ✗ case DAE.Type.T_SUBTYPE_BASIC() then getBasicType(ty.complexType);
7697 else ty;
7698 end match;
7699 end getBasicType;
7700
7701 public function resultExps
7702 "Collects the result expressions of a list of match-expression cases.
7703 Moved here from Patternm so Types does not depend on the instantiation cluster."
7704 input list<DAE.MatchCase> inCases;
7705 output list<DAE.Exp> exps;
7706 algorithm
7707 exps := match inCases
7708 local
7709 DAE.Exp exp; list<DAE.MatchCase> cases;
7710 case {} then {};
7711 case DAE.CASE(result=SOME(exp))::cases
7712 algorithm
7713 16 exps := resultExps(cases);
7714 then exp::exps;
7715 ✗ case _::cases then resultExps(cases);
7716 end match;
7717 end resultExps;
7718
7719 public function fixCaseReturnTypes2
7720 "Replaces the result expressions of a list of match-expression cases.
7721 Moved here from Patternm (see resultExps)."
7722 input list<DAE.MatchCase> inCases;
7723 input list<DAE.Exp> inExps;
7724 input SourceInfo inInfo;
7725 output list<DAE.MatchCase> outCases;
7726 algorithm
7727 outCases := matchcontinue (inCases,inExps,inInfo)
7728 local
7729 list<DAE.Pattern> patterns;
7730 list<DAE.Element> decls;
7731 list<DAE.Statement> body;
7732 Option<DAE.Exp> patternGuard;
7733 DAE.Exp exp;
7734 DAE.MatchCase case_;
7735 Integer jump;
7736 SourceInfo resultInfo,info2;
7737 list<DAE.MatchCase> cases;
7738 list<DAE.Exp> exps;
7739 SourceInfo info;
7740
7741 case ({},{},_) then {};
7742
7743 case (DAE.CASE(patterns,patternGuard,decls,body,SOME(_),resultInfo,jump,info2)::cases,exp::exps,info)
7744 algorithm
7745 5082 cases := fixCaseReturnTypes2(cases,exps,info);
7746 5082 then DAE.CASE(patterns,patternGuard,decls,body,SOME(exp),resultInfo,jump,info2)::cases;
7747
7748 case ((case_ as DAE.CASE(result=NONE()))::cases,exps,info)
7749 algorithm
7750 90 cases := fixCaseReturnTypes2(cases,exps,info);
7751 then case_::cases;
7752
7753 else
7754 algorithm
7755 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {"Types.fixCaseReturnTypes2 failed"}, inInfo);
7756 ✗ then fail();
7757 end matchcontinue;
7758 end fixCaseReturnTypes2;
7759
7760 annotation(__OpenModelica_Interface="frontend_base");
7761 end Types;
7762