Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 81.7% 272 / 0 / 333
Functions: -% 0 / 1 / 1
Branches: 72.9% 172 / 0 / 236

OMCompiler/Compiler/NFFrontEnd/NFConvertDAE.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 NFConvertDAE
37
38 import Binding = NFBinding;
39 import DAE;
40 import Equation = NFEquation;
41 import FlatModel = NFFlatModel;
42 import NFFlatten.FunctionTree;
43 import NFInstNode.InstNode;
44 import Statement = NFStatement;
45 import Restriction = NFRestriction;
46
47 protected
48
49 import Algorithm = NFAlgorithm;
50 import Attributes = NFAttributes;
51 import AbsynUtil;
52 import AvlTreePathFunction;
53 import Call = NFCall;
54 import ComponentReferenceBasics;
55 import ComponentRef = NFComponentRef;
56 import Dimension = NFDimension;
57 import ElementSource;
58 import ExecStat.execStat;
59 import Expression = NFExpression;
60 import Flags;
61 import Flatten = NFFlatten;
62 import Function = NFFunction.Function;
63 import MetaModelica.Dangerous.listReverseInPlace;
64 import Class = NFClass;
65 import NFClassTree.ClassTree;
66 import Component = NFComponent;
67 import NFModifier.Modifier;
68 import NFPrefixes.ConnectorType;
69 import NFPrefixes.Direction;
70 import NFPrefixes.Variability;
71 import NFPrefixes.Visibility;
72 import Prefixes = NFPrefixes;
73 import Sections = NFSections;
74 import SCode;
75 import Type = NFType;
76 import Util;
77 import Variable = NFVariable;
78
79 public
80 function convert
81 input FlatModel flatModel;
82 input FunctionTree functions;
83 output DAE.DAElist dae;
84 output AvlTreePathFunction.Tree daeFunctions;
85 protected
86 algorithm
87 1366 daeFunctions := convertFunctionTree(functions);
88 1366 dae := convertModel(flatModel);
89 1366 execStat(getInstanceName());
90 end convert;
91
92 function convertModel
93 input FlatModel flatModel;
94 output DAE.DAElist dae;
95 protected
96 list<DAE.Element> elems;
97 DAE.Element class_elem;
98 algorithm
99 1374 elems := convertVariables(flatModel.variables, {});
100 1374 elems := convertEquations(flatModel.equations, elems);
101 1374 elems := convertInitialEquations(flatModel.initialEquations, elems);
102 1374 elems := convertAlgorithms(flatModel.algorithms, elems);
103 1374 elems := convertInitialAlgorithms(flatModel.initialAlgorithms, elems);
104
105 1374 class_elem := DAE.COMP(FlatModel.fullName(flatModel), elems, flatModel.source, ElementSource.getOptComment(flatModel.source));
106 1374 dae := DAE.DAE({class_elem});
107 end convertModel;
108
109 function convertStatements
110 input list<Statement> statements;
111 output list<DAE.Statement> elements;
112 algorithm
113
4/4
✓ Branch 0 taken 95217 times.
✓ Branch 1 taken 21156 times.
✓ Branch 2 taken 95217 times.
✓ Branch 3 taken 21156 times.
116373 elements := list(convertStatement(s) for s in statements);
114 end convertStatements;
115
116 protected
117 uniontype VariableConversionSettings
118 record VARIABLE_CONVERSION_SETTINGS
119 Boolean isFunctionParameter;
120 Boolean addTypeToSource;
121 end VARIABLE_CONVERSION_SETTINGS;
122 end VariableConversionSettings;
123
124 constant VariableConversionSettings FUNCTION_VARIABLE_CONVERSION_SETTINGS =
125 VARIABLE_CONVERSION_SETTINGS(true, false);
126
127 function convertVariables
128 input list<Variable> variables;
129 input output list<DAE.Element> elements;
130 protected
131 VariableConversionSettings settings;
132 ComponentRef rest, last_rest = ComponentRef.EMPTY();
133 Boolean encrypted, rest_encrypted = false;
134 algorithm
135
4/4
✓ Branch 1 taken 1371 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1368 times.
1377 settings := VariableConversionSettings.VARIABLE_CONVERSION_SETTINGS(
136 isFunctionParameter = false,
137 addTypeToSource = Flags.isSet(Flags.INFO_XML_OPERATIONS) or Flags.isSet(Flags.VISUAL_XML)
138 );
139
140
2/2
✓ Branch 1 taken 373309 times.
✓ Branch 2 taken 1374 times.
374683 for var in listReverse(variables) loop
141 // The variables of an instance share its name as their prefix.
142
1/2
✓ Branch 1 taken 373309 times.
✗ Branch 2 not taken.
373309 if ComponentRef.isCref(var.name) then
143 373309 rest := ComponentRef.rest(var.name);
144
2/2
✓ Branch 0 taken 52144 times.
✓ Branch 1 taken 321165 times.
373309 if not referenceEq(rest, last_rest) then
145 last_rest := rest;
146 52144 rest_encrypted := Variable.isEncryptedName(rest);
147 end if;
148
2/4
✓ Branch 0 taken 373309 times.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 373309 times.
373309 encrypted := rest_encrypted or Variable.isEncryptedNode(ComponentRef.node(var.name));
149 else
150 encrypted := false;
151 end if;
152
153 373309 elements := convertVariable(var, settings, encrypted) :: elements;
154 end for;
155 end convertVariables;
156
157 function convertVariable
158 input Variable var;
159 input VariableConversionSettings settings;
160 input Boolean encrypted;
161 output DAE.Element daeVar;
162 protected
163 Option<DAE.VariableAttributes> var_attr;
164 Option<DAE.Exp> binding_exp;
165 algorithm
166 373309 binding_exp := Binding.toDAEExp(var.binding);
167 373309 var_attr := convertVarAttributes(var.typeAttributes, var.ty, var.attributes);
168 373309 daeVar := makeDAEVar(var.name, var.ty, binding_exp, var.attributes,
169 var.visibility, var_attr, var.comment, settings, var.info, encrypted);
170 end convertVariable;
171
172 function makeDAEVar
173 input ComponentRef cref;
174 input Type ty;
175 input Option<DAE.Exp> binding;
176 input Attributes attr;
177 input Visibility vis;
178 input Option<DAE.VariableAttributes> vattr;
179 input SCode.Comment comment;
180 input VariableConversionSettings settings;
181 input SourceInfo info;
182 input Boolean encrypted;
183 output DAE.Element var;
184 protected
185 DAE.ComponentRef dcref;
186 DAE.Type dty;
187 DAE.ElementSource source;
188 algorithm
189 430565 dcref := ComponentRef.toDAE(cref);
190
2/2
✓ Branch 0 taken 57256 times.
✓ Branch 1 taken 373309 times.
430565 dty := Type.toDAE(if settings.isFunctionParameter then Type.arrayElementType(ty) else ty);
191 430565 source := ElementSource.createElementSource(info);
192
193
2/2
✓ Branch 0 taken 3370 times.
✓ Branch 1 taken 427195 times.
430565 if settings.addTypeToSource then
194 3370 source := addComponentTypeToSource(cref, source);
195 end if;
196
197 var := match attr
198 case Attributes.ATTRIBUTES()
199
1/2
✓ Branch 0 taken 430565 times.
✗ Branch 1 not taken.
861130 then
200 DAE.VAR(
201 dcref,
202 Prefixes.variabilityToDAE(attr.variability),
203 Prefixes.directionToDAE(attr.direction),
204 Prefixes.parallelismToDAE(attr.parallelism),
205 Prefixes.visibilityToDAE(vis),
206 dty,
207 binding,
208 ComponentReferenceBasics.crefDims(dcref),
209 ConnectorType.toDAE(attr.connectorType),
210 source,
211 vattr,
212 SOME(comment),
213 Absyn.NOT_INNER_OUTER(),
214 encrypted
215 );
216
217 ✗ else
218 DAE.VAR(dcref, DAE.VarKind.VARIABLE(), DAE.VarDirection.BIDIR(),
219 DAE.VarParallelism.NON_PARALLEL(), Prefixes.visibilityToDAE(vis), dty,
220 binding, {}, DAE.ConnectorType.NON_CONNECTOR(), source, vattr, SOME(comment),
221 Absyn.NOT_INNER_OUTER(),encrypted);
222
223 end match;
224 end makeDAEVar;
225
226 function addComponentTypeToSource
227 input ComponentRef cref;
228 input output DAE.ElementSource source;
229 algorithm
230 source := match cref
231 case ComponentRef.CREF()
232 algorithm
233 11241 source := addComponentLevelTypeToSource(InstNode.parent(ComponentRef.node(cref)), source);
234 11241 then
235 addComponentTypeToSource(cref.restCref, source);
236
237 else source;
238 end match;
239 end addComponentTypeToSource;
240
241 function addComponentLevelTypeToSource
242 "Records the type(s) of the class that owns the component referenced at one
243 level of a cref into the element source. For a regular component this is a
244 single class (the class in which the component is declared). When a component
245 is inherited through one or more `extends` of a visualization type, e.g.
246
247 model MyShape
248 extends ModelicaServices.Animation.Shape;
249 end MyShape;
250
251 getDerivedNode collapses the whole extends chain down to the most derived
252 class (MyShape), so the visualization base class (Shape) would be lost and
253 the backend (VisualXML) could no longer recognize it. In that case we record
254 the full extends chain, with the visualization base class kept in the primary
255 slot of this level so that the identifier prefix computed from the type index
256 in VisualXML.isVisualizationVarFold still points at the right component.
257
258 This is only reached when the element source types are recorded at all, i.e.
259 under -d=visxml (animation) or infoXmlOperations; otherwise the original
260 single most derived class entry is kept."
261 input InstNode parentNode;
262 input output DAE.ElementSource source;
263 protected
264 InstNode concrete, n;
265 Absyn.Path concretePath, p;
266 list<Absyn.Path> chain = {};
267 Option<Absyn.Path> visPath = NONE();
268 algorithm
269 // the collapsed, most derived class (default behaviour)
270 11241 concrete := InstNode.classScope(InstNode.getDerivedNode(parentNode));
271 11241 concretePath := InstNode.scopePath(concrete);
272
273 // Skip the chain walk when the most derived class is itself a visualization
274 // type (direct ModelicaServices/MultiBody shapes already match as a single
275 // entry); only an inherited shape needs the base classes recorded.
276
2/2
✓ Branch 1 taken 9471 times.
✓ Branch 2 taken 1770 times.
11241 if not isVisualizerLeafName(concretePath) then
277 // walk the extends chain from where the component is actually declared up
278 // to the most derived class, collecting the intermediate base classes
279 9471 n := InstNode.classScope(parentNode);
280
2/2
✓ Branch 1 taken 505 times.
✓ Branch 2 taken 9471 times.
9976 while InstNode.isBaseClass(n) loop
281 505 p := InstNode.scopePath(n, ignoreBaseClass = true);
282 chain := p :: chain;
283
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 505 times.
✓ Branch 2 taken 505 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 505 times.
505 if isNone(visPath) and isVisualizerLeafName(p) then
284 visPath := SOME(p);
285 end if;
286 505 n := InstNode.classScope(InstNode.getDerivedNode(n, recursive = false));
287 end while;
288 end if;
289
290
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11241 times.
✓ Branch 2 taken 11241 times.
✗ Branch 3 not taken.
11241 if isSome(visPath) then
291 // a visualization type appears as a base class -> record the whole chain
292 // with the visualization base class in the primary slot of this level
293 ✗ SOME(p) := visPath;
294 ✗ chain := listAppend(list(c for c guard not AbsynUtil.pathEqual(c, p) in chain),
295 {concretePath});
296 ✗ for c in listReverse(chain) loop
297 ✗ source := ElementSource.addElementSourceType(source, c);
298 end for;
299 ✗ source := ElementSource.addElementSourceType(source, p);
300 else
301 // default (unchanged): single most derived class entry
302 11241 source := ElementSource.addElementSourceType(source, concretePath);
303 end if;
304 end addComponentLevelTypeToSource;
305
306 function isVisualizerLeafName
307 "Returns true if the last identifier of the path is one of the visualization
308 type names (Shape, Vector, Surface). This is only used to position the type
309 in the element source; VisualXML.hasVisPath remains the authority on whether
310 a fully qualified path is actually a visualization type."
311 input Absyn.Path path;
312 output Boolean isVisualizer;
313 algorithm
314 isVisualizer := match AbsynUtil.pathLastIdent(path)
315 case "Shape" then true;
316 case "Vector" then true;
317 case "Surface" then true;
318 else false;
319 end match;
320 end isVisualizerLeafName;
321
322 function convertVarAttributes
323 input list<tuple<String, Binding>> attrs;
324 input Type ty;
325 input Attributes compAttrs;
326 output Option<DAE.VariableAttributes> attributes;
327 protected
328 Boolean is_final;
329 Option<Boolean> is_final_opt;
330 algorithm
331
4/4
✓ Branch 0 taken 345452 times.
✓ Branch 1 taken 85113 times.
✓ Branch 2 taken 341127 times.
✓ Branch 3 taken 4325 times.
430565 is_final := compAttrs.isFinal or
332 compAttrs.variability == Variability.STRUCTURAL_PARAMETER;
333
334
4/4
✓ Branch 0 taken 158245 times.
✓ Branch 1 taken 272320 times.
✓ Branch 2 taken 132266 times.
✓ Branch 3 taken 25979 times.
430565 if listEmpty(attrs) and not is_final then
335 attributes := NONE();
336 132266 return;
337 end if;
338
339
2/2
✓ Branch 0 taken 208861 times.
✓ Branch 1 taken 89438 times.
298299 is_final_opt := SOME(is_final);
340
341 attributes := match Type.arrayElementType(ty)
342 270078 case Type.REAL() then convertRealVarAttributes(attrs, is_final_opt);
343 13133 case Type.INTEGER() then convertIntVarAttributes(attrs, is_final_opt);
344 11662 case Type.BOOLEAN() then convertBoolVarAttributes(attrs, is_final_opt);
345 1426 case Type.STRING() then convertStringVarAttributes(attrs, is_final_opt);
346 1981 case Type.ENUMERATION() then convertEnumVarAttributes(attrs, is_final_opt);
347 else NONE();
348 end match;
349 end convertVarAttributes;
350
351 function convertRealVarAttributes
352 input list<tuple<String, Binding>> attrs;
353 input Option<Boolean> isFinal;
354 output Option<DAE.VariableAttributes> attributes;
355 protected
356 String name;
357 Binding b;
358 Option<DAE.Exp> quantity = NONE(), unit = NONE(), displayUnit = NONE();
359 Option<DAE.Exp> min = NONE(), max = NONE(), start = NONE(), fixed = NONE(), nominal = NONE();
360 Option<DAE.StateSelect> state_select = NONE();
361 Option<DAE.Uncertainty> uncertain = NONE();
362 Option<DAE.StartOrigin> start_origin = NONE();
363 algorithm
364
2/2
✓ Branch 0 taken 679110 times.
✓ Branch 1 taken 270078 times.
949188 for attr in attrs loop
365 679110 (name, b) := attr;
366
367 () := match name
368 37989 case "displayUnit" algorithm displayUnit := convertVarAttribute(b); then ();
369 7466 case "fixed" algorithm fixed := convertVarAttribute(b); then ();
370 15077 case "max" algorithm max := convertVarAttribute(b); then ();
371 47826 case "min" algorithm min := convertVarAttribute(b); then ();
372 29214 case "nominal" algorithm nominal := convertVarAttribute(b); then ();
373 222383 case "quantity" algorithm quantity := convertVarAttribute(b); then ();
374 74138 case "start" algorithm start := convertVarAttribute(b);
375 74138 start_origin := convertStartOrigin(b); then ();
376 7060 case "stateSelect" algorithm state_select := convertStateSelectAttribute(b); then ();
377 // TODO: VAR_ATTR_REAL has no field for unbounded.
378 case "unbounded" then ();
379 169 case "uncertain" algorithm uncertain := convertUncertaintyAttribute(b); then ();
380 237787 case "unit" algorithm unit := convertVarAttribute(b); then ();
381
382 // The attributes should already be type checked, so we shouldn't get any
383 // unknown attributes here.
384 else
385 algorithm
386 ✗ Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo());
387 ✗ then
388 fail();
389 end match;
390 end for;
391
392 270078 attributes := SOME(DAE.VariableAttributes.VAR_ATTR_REAL(
393 quantity, unit, displayUnit, min, max, start, fixed, nominal,
394 state_select, uncertain, NONE(), NONE(), NONE(), isFinal, start_origin));
395 end convertRealVarAttributes;
396
397 function convertIntVarAttributes
398 input list<tuple<String, Binding>> attrs;
399 input Option<Boolean> isFinal;
400 output Option<DAE.VariableAttributes> attributes;
401 protected
402 String name;
403 Binding b;
404 Option<DAE.Exp> quantity = NONE(), min = NONE(), max = NONE();
405 Option<DAE.Exp> start = NONE(), fixed = NONE();
406 Option<DAE.StartOrigin> start_origin = NONE();
407 algorithm
408
2/2
✓ Branch 0 taken 21359 times.
✓ Branch 1 taken 13133 times.
34492 for attr in attrs loop
409 21359 (name, b) := attr;
410
411 () := match name
412 1 case "quantity" algorithm quantity := convertVarAttribute(b); then ();
413 11295 case "min" algorithm min := convertVarAttribute(b); then ();
414 9615 case "max" algorithm max := convertVarAttribute(b); then ();
415 285 case "start" algorithm start := convertVarAttribute(b);
416 285 start_origin := convertStartOrigin(b); then ();
417 163 case "fixed" algorithm fixed := convertVarAttribute(b); then ();
418
419 // The attributes should already be type checked, so we shouldn't get any
420 // unknown attributes here.
421 else
422 algorithm
423 ✗ Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo());
424 ✗ then
425 fail();
426 end match;
427 end for;
428
429 13133 attributes := SOME(DAE.VariableAttributes.VAR_ATTR_INT(
430 quantity, min, max, start, fixed,
431 NONE(), NONE(), NONE(), NONE(), isFinal, start_origin));
432 end convertIntVarAttributes;
433
434 function convertBoolVarAttributes
435 input list<tuple<String, Binding>> attrs;
436 input Option<Boolean> isFinal;
437 output Option<DAE.VariableAttributes> attributes;
438 protected
439 String name;
440 Binding b;
441 Option<DAE.Exp> quantity = NONE(), start = NONE(), fixed = NONE();
442 Option<DAE.StartOrigin> start_origin = NONE();
443 algorithm
444
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 11662 times.
13142 for attr in attrs loop
445 1480 (name, b) := attr;
446
447 () := match name
448 1 case "quantity" algorithm quantity := convertVarAttribute(b); then ();
449 1333 case "start" algorithm start := convertVarAttribute(b);
450 1333 start_origin := convertStartOrigin(b); then ();
451 146 case "fixed" algorithm fixed := convertVarAttribute(b); then ();
452
453 // The attributes should already be type checked, so we shouldn't get any
454 // unknown attributes here.
455 else
456 algorithm
457 ✗ Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo());
458 ✗ then
459 fail();
460 end match;
461 end for;
462
463 11662 attributes := SOME(DAE.VariableAttributes.VAR_ATTR_BOOL(
464 quantity, start, fixed, NONE(), NONE(), isFinal, start_origin));
465 end convertBoolVarAttributes;
466
467 function convertStringVarAttributes
468 input list<tuple<String, Binding>> attrs;
469 input Option<Boolean> isFinal;
470 output Option<DAE.VariableAttributes> attributes;
471 protected
472 String name;
473 Binding b;
474 Option<DAE.Exp> quantity = NONE(), start = NONE(), fixed = NONE();
475 Option<DAE.StartOrigin> start_origin = NONE();
476 algorithm
477
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 1426 times.
1461 for attr in attrs loop
478 35 (name, b) := attr;
479
480 () := match name
481 1 case "quantity" algorithm quantity := convertVarAttribute(b); then ();
482 31 case "start" algorithm start := convertVarAttribute(b);
483 31 start_origin := convertStartOrigin(b); then ();
484 3 case "fixed" algorithm fixed := convertVarAttribute(b); then ();
485
486 // The attributes should already be type checked, so we shouldn't get any
487 // unknown attributes here.
488 else
489 algorithm
490 ✗ Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo());
491 ✗ then
492 fail();
493 end match;
494 end for;
495
496 1426 attributes := SOME(DAE.VariableAttributes.VAR_ATTR_STRING(
497 quantity, start, fixed, NONE(), NONE(), isFinal, start_origin));
498 end convertStringVarAttributes;
499
500 function convertEnumVarAttributes
501 input list<tuple<String, Binding>> attrs;
502 input Option<Boolean> isFinal;
503 output Option<DAE.VariableAttributes> attributes;
504 protected
505 String name;
506 Binding b;
507 Option<DAE.Exp> quantity = NONE(), min = NONE(), max = NONE();
508 Option<DAE.Exp> start = NONE(), fixed = NONE();
509 Option<DAE.StartOrigin> start_origin = NONE();
510 algorithm
511
2/2
✓ Branch 0 taken 587 times.
✓ Branch 1 taken 1981 times.
2568 for attr in attrs loop
512 587 (name, b) := attr;
513
514 () := match name
515 173 case "fixed" algorithm fixed := convertVarAttribute(b); then ();
516 1 case "max" algorithm max := convertVarAttribute(b); then ();
517 2 case "min" algorithm min := convertVarAttribute(b); then ();
518 1 case "quantity" algorithm quantity := convertVarAttribute(b); then ();
519 410 case "start" algorithm start := convertVarAttribute(b);
520 410 start_origin := convertStartOrigin(b); then ();
521
522 // The attributes should already be type checked, so we shouldn't get any
523 // unknown attributes here.
524 else
525 algorithm
526 ✗ Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo());
527 ✗ then
528 fail();
529 end match;
530 end for;
531
532 1981 attributes := SOME(DAE.VariableAttributes.VAR_ATTR_ENUMERATION(
533 quantity, min, max, start, fixed, NONE(), NONE(), isFinal, start_origin));
534 end convertEnumVarAttributes;
535
536 function convertVarAttribute
537 input Binding binding;
538 output Option<DAE.Exp> attribute = SOME(Expression.toDAE(Binding.getTypedExp(binding)));
539 end convertVarAttribute;
540
541 function convertStateSelectAttribute
542 input Binding binding;
543 output Option<DAE.StateSelect> stateSelect;
544 protected
545 String name;
546 algorithm
547 7060 name := getStateSelectName(Expression.arrayFirstScalar(Binding.getTypedExp(binding)));
548 7060 stateSelect := SOME(lookupStateSelectMember(name));
549 end convertStateSelectAttribute;
550
551 function getStateSelectName
552 input Expression exp;
553 output String name;
554 protected
555 Expression e;
556 algorithm
557 name := match exp
558 7060 case Expression.ENUM_LITERAL() then exp.name;
559 ✗ case Expression.CREF() then ComponentRef.nodeName(exp.cref);
560 ✗ case Expression.CALL(call = Call.TYPED_ARRAY_CONSTRUCTOR(exp = e)) then getStateSelectName(e);
561 else
562 algorithm
563 ✗ Error.terminate(getInstanceName() +
564 " got invalid StateSelect expression " + Expression.toString(exp), sourceInfo());
565 ✗ then
566 fail();
567 end match;
568 end getStateSelectName;
569
570 function lookupStateSelectMember
571 input String name;
572 output DAE.StateSelect stateSelect;
573 algorithm
574 stateSelect := match name
575 case "never" then DAE.StateSelect.NEVER();
576 case "avoid" then DAE.StateSelect.AVOID();
577 case "default" then DAE.StateSelect.DEFAULT();
578 case "prefer" then DAE.StateSelect.PREFER();
579 case "always" then DAE.StateSelect.ALWAYS();
580 else
581 algorithm
582 ✗ Error.terminate(getInstanceName() + " got unknown StateSelect literal " + name, sourceInfo());
583 ✗ then
584 fail();
585 end match;
586 end lookupStateSelectMember;
587
588 function convertUncertaintyAttribute
589 input Binding binding;
590 output Option<DAE.Uncertainty> stateSelect;
591 protected
592 InstNode node;
593 String name;
594 Expression exp = Expression.arrayFirstScalar(Binding.getTypedExp(binding));
595 algorithm
596 name := match exp
597 169 case Expression.ENUM_LITERAL() then exp.name;
598 ✗ case Expression.CREF(cref = ComponentRef.CREF()) then ComponentRef.nodeName(exp.cref);
599 else
600 algorithm
601 ✗ Error.terminate(getInstanceName() +
602 " got invalid Uncertainty expression " + Expression.toString(exp), sourceInfo());
603 ✗ then
604 fail();
605 end match;
606
607 169 stateSelect := SOME(lookupUncertaintyMember(name));
608 end convertUncertaintyAttribute;
609
610 function lookupUncertaintyMember
611 input String name;
612 output DAE.Uncertainty stateSelect;
613 algorithm
614 stateSelect := match name
615 case "given" then DAE.Uncertainty.GIVEN();
616 case "sought" then DAE.Uncertainty.SOUGHT();
617 case "refine" then DAE.Uncertainty.REFINE();
618 case "propagate" then DAE.Uncertainty.PROPAGATE();
619 else
620 algorithm
621 ✗ Error.terminate(getInstanceName() + " got unknown Uncertainty literal " + name, sourceInfo());
622 ✗ then
623 fail();
624 end match;
625 end lookupUncertaintyMember;
626
627 function convertStartOrigin
628 input Binding binding;
629 output Option<DAE.StartOrigin> startOrigin;
630 algorithm
631
2/2
✓ Branch 1 taken 15736 times.
✓ Branch 2 taken 60461 times.
76197 startOrigin := SOME(
632 if Binding.isFromType(binding) then
633 DAE.StartOrigin.TYPE_CONFIDENCE(Binding.confidence(binding))
634 else
635 DAE.StartOrigin.CONFIDENCE(Binding.actualConfidence(binding), Binding.confidence(binding)));
636 end convertStartOrigin;
637
638 function convertEquations
639 input list<Equation> equations;
640 input output list<DAE.Element> elements = {};
641 algorithm
642
2/2
✓ Branch 1 taken 146602 times.
✓ Branch 2 taken 2265 times.
148867 for eq in listReverse(equations) loop
643 146602 elements := convertEquation(eq, elements);
644 end for;
645 end convertEquations;
646
647 function convertEquation
648 input Equation eq;
649 input output list<DAE.Element> elements;
650 algorithm
651 elements := match eq
652 local
653 Expression lhs, rhs;
654 DAE.Exp e1, e2, e3;
655 DAE.ComponentRef cr1, cr2;
656
657 case Equation.EQUALITY(lhs = lhs as Expression.CREF(), rhs = rhs as Expression.CREF())
658 guard Type.isScalarBuiltin(eq.ty)
659 algorithm
660 57400 cr1 := ComponentRef.toDAE(lhs.cref);
661 57400 cr2 := ComponentRef.toDAE(rhs.cref);
662 57400 then
663 DAE.Element.EQUEQUATION(cr1, cr2, eq.source) :: elements;
664
665 case Equation.EQUALITY()
666 algorithm
667 86958 e1 := Expression.toDAE(eq.lhs);
668 86958 e2 := Expression.toDAE(eq.rhs);
669
8/8
✓ Branch 1 taken 3487 times.
✓ Branch 2 taken 83471 times.
✓ Branch 5 taken 19820 times.
✓ Branch 6 taken 63651 times.
✓ Branch 8 taken 22540 times.
✓ Branch 9 taken 19820 times.
✓ Branch 10 taken 22540 times.
✓ Branch 11 taken 19820 times.
109498 then
670 (if Type.isComplex(eq.ty) then
671 DAE.Element.COMPLEX_EQUATION(e1, e2, eq.source)
672 elseif Type.isArray(eq.ty) then
673 DAE.Element.ARRAY_EQUATION(list(Dimension.toDAE(d) for d in Type.arrayDims(eq.ty)), e1, e2, eq.source)
674 else
675 DAE.Element.EQUATION(e1, e2, eq.source)) :: elements;
676
677 case Equation.FOR()
678 29 then convertForEquation(eq, isInitial = false) :: elements;
679
680 case Equation.IF()
681 161 then convertIfEquation(eq.branches, eq.source, isInitial = false) :: elements;
682
683 case Equation.WHEN()
684 263 then convertWhenEquation(eq.branches, eq.source) :: elements;
685
686 case Equation.ASSERT()
687 algorithm
688 1707 e1 := Expression.toDAE(eq.condition);
689 1707 e2 := Expression.toDAE(eq.message);
690 1707 e3 := Expression.toDAE(eq.level);
691 1707 then
692 DAE.Element.ASSERT(e1, e2, e3, eq.source) :: elements;
693
694 case Equation.TERMINATE()
695 5 then DAE.Element.TERMINATE(Expression.toDAE(eq.message), eq.source) :: elements;
696
697 case Equation.REINIT()
698 algorithm
699 27 cr1 := ComponentRef.toDAE(Expression.toCref(eq.cref));
700 27 e1 := Expression.toDAE(eq.reinitExp);
701 27 then
702 DAE.Element.REINIT(cr1, e1, eq.source) :: elements;
703
704 case Equation.NORETCALL()
705 52 then DAE.Element.NORETCALL(Expression.toDAE(eq.exp), eq.source) :: elements;
706
707 else
708 algorithm
709 ✗ Error.terminate(getInstanceName() + " got unknown equation " + Equation.toString(eq), sourceInfo());
710 ✗ then
711 fail();
712 end match;
713 end convertEquation;
714
715 function convertForEquation
716 input Equation forEquation;
717 input Boolean isInitial;
718 output DAE.Element forDAE;
719 protected
720 InstNode iterator;
721 Type ty;
722 Expression range;
723 list<Equation> body;
724 list<DAE.Element> dbody;
725 DAE.ElementSource source;
726 algorithm
727
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 31 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 31 times.
31 Equation.FOR(iterator = iterator, range = SOME(range), body = body, source = source) := forEquation;
728
729
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if isInitial then
730 2 dbody := convertInitialEquations(body);
731 else
732 29 dbody := convertEquations(body);
733 end if;
734
735
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
31 Component.ITERATOR(ty = ty) := InstNode.component(iterator);
736
737
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
31 if isInitial then
738
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
4 forDAE := DAE.Element.INITIAL_FOR_EQUATION(Type.toDAE(ty), Type.isArray(ty),
739 InstNode.name(iterator), 0, Expression.toDAE(range), dbody, source);
740 else
741
1/2
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
58 forDAE := DAE.Element.FOR_EQUATION(Type.toDAE(ty), Type.isArray(ty),
742 InstNode.name(iterator), 0, Expression.toDAE(range), dbody, source);
743 end if;
744 end convertForEquation;
745
746 function convertIfEquation
747 input list<Equation.Branch> ifBranches;
748 input DAE.ElementSource source;
749 input Boolean isInitial;
750 output DAE.Element ifEquation;
751 protected
752 list<Expression> conds = {};
753 list<list<Equation>> branches = {};
754 list<DAE.Exp> dconds;
755 list<list<DAE.Element>> dbranches;
756 list<DAE.Element> else_branch;
757 algorithm
758
2/2
✓ Branch 0 taken 592 times.
✓ Branch 1 taken 161 times.
753 for branch in ifBranches loop
759 (conds, branches) := match branch
760 case Equation.Branch.BRANCH()
761 592 then (branch.condition :: conds, branch.body :: branches);
762
763 case Equation.Branch.INVALID_BRANCH()
764 algorithm
765 ✗ Equation.Branch.triggerErrors(branch);
766 ✗ then
767 fail();
768 end match;
769 end for;
770
771
5/10
✗ Branch 0 not taken.
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 592 times.
✓ Branch 8 taken 161 times.
✓ Branch 9 taken 592 times.
✓ Branch 10 taken 161 times.
753 dbranches := if isInitial then
772 list(convertInitialEquations(b) for b in branches) else
773 list(convertEquations(b) for b in branches);
774
775 // Transform the last branch to an else-branch if its condition is true.
776
2/2
✓ Branch 2 taken 158 times.
✓ Branch 3 taken 3 times.
161 if Expression.isTrue(listHead(conds)) then
777
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
158 else_branch :: dbranches := dbranches;
778 158 conds := listRest(conds);
779 else
780 else_branch := {};
781 end if;
782
783
4/4
✓ Branch 0 taken 434 times.
✓ Branch 1 taken 161 times.
✓ Branch 2 taken 434 times.
✓ Branch 3 taken 161 times.
595 dconds := listReverse(Expression.toDAE(c) for c in conds);
784 161 dbranches := listReverseInPlace(dbranches);
785
786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 161 times.
161 ifEquation := if isInitial then
787 DAE.Element.INITIAL_IF_EQUATION(dconds, dbranches, else_branch, source) else
788 DAE.Element.IF_EQUATION(dconds, dbranches, else_branch, source);
789 end convertIfEquation;
790
791 function convertWhenEquation
792 input list<Equation.Branch> whenBranches;
793 input DAE.ElementSource source;
794 output DAE.Element whenEquation;
795 protected
796 DAE.Exp cond;
797 list<DAE.Element> els;
798 Option<DAE.Element> when_eq = NONE();
799 algorithm
800
2/2
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 263 times.
533 for b in listReverse(whenBranches) loop
801 when_eq := match b
802 case Equation.Branch.BRANCH()
803 algorithm
804 270 cond := Expression.toDAE(b.condition);
805 270 els := convertEquations(b.body);
806 270 then
807 SOME(DAE.Element.WHEN_EQUATION(cond, els, when_eq, source));
808 end match;
809 end for;
810
811
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 263 times.
263 SOME(whenEquation) := when_eq;
812 end convertWhenEquation;
813
814 function convertInitialEquations
815 input list<Equation> equations;
816 input output list<DAE.Element> elements = {};
817 algorithm
818
2/2
✓ Branch 1 taken 1818 times.
✓ Branch 2 taken 1376 times.
3194 for eq in listReverse(equations) loop
819 1818 elements := convertInitialEquation(eq, elements);
820 end for;
821 end convertInitialEquations;
822
823 function convertInitialEquation
824 input Equation eq;
825 input output list<DAE.Element> elements;
826 algorithm
827 elements := match eq
828 local
829 DAE.Exp e1, e2, e3;
830
831 case Equation.EQUALITY()
832 algorithm
833 1786 e1 := Expression.toDAE(eq.lhs);
834 1786 e2 := Expression.toDAE(eq.rhs);
835
8/8
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 1727 times.
✓ Branch 5 taken 47 times.
✓ Branch 6 taken 1680 times.
✓ Branch 8 taken 47 times.
✓ Branch 9 taken 47 times.
✓ Branch 10 taken 47 times.
✓ Branch 11 taken 47 times.
1833 then
836 (if Type.isComplex(eq.ty) then
837 DAE.Element.INITIAL_COMPLEX_EQUATION(e1, e2, eq.source)
838 elseif Type.isArray(eq.ty) then
839 DAE.Element.INITIAL_ARRAY_EQUATION(list(Dimension.toDAE(d) for d in Type.arrayDims(eq.ty)), e1, e2, eq.source)
840 else
841 DAE.Element.INITIALEQUATION(e1, e2, eq.source)) :: elements;
842
843 case Equation.FOR()
844 2 then convertForEquation(eq, isInitial = true) :: elements;
845
846 case Equation.IF()
847 ✗ then convertIfEquation(eq.branches, eq.source, isInitial = true) :: elements;
848
849 case Equation.ASSERT()
850 algorithm
851 29 e1 := Expression.toDAE(eq.condition);
852 29 e2 := Expression.toDAE(eq.message);
853 29 e3 := Expression.toDAE(eq.level);
854 29 then
855 DAE.Element.INITIAL_ASSERT(e1, e2, e3, eq.source) :: elements;
856
857 case Equation.TERMINATE()
858 ✗ then DAE.Element.INITIAL_TERMINATE(Expression.toDAE(eq.message), eq.source) :: elements;
859
860 case Equation.NORETCALL()
861 1 then DAE.Element.INITIAL_NORETCALL(Expression.toDAE(eq.exp), eq.source) :: elements;
862
863 else
864 algorithm
865 ✗ Error.terminate(getInstanceName() + " got unknown equation " + Equation.toString(eq), sourceInfo());
866 ✗ then
867 fail();
868 end match;
869 end convertInitialEquation;
870
871 function convertAlgorithms
872 input list<Algorithm> algorithms;
873 input output list<DAE.Element> elements;
874 algorithm
875
2/2
✓ Branch 1 taken 9633 times.
✓ Branch 2 taken 10874 times.
20507 for alg in listReverse(algorithms) loop
876 9633 elements := convertAlgorithm(alg, elements);
877 end for;
878 end convertAlgorithms;
879
880 function convertAlgorithm
881 input Algorithm alg;
882 input output list<DAE.Element> elements;
883 protected
884 list<DAE.Statement> stmts;
885 DAE.Algorithm dalg;
886 algorithm
887 9633 stmts := convertStatements(alg.statements);
888 9633 dalg := DAE.ALGORITHM_STMTS(stmts);
889 9633 elements := DAE.ALGORITHM(dalg, alg.source) :: elements;
890 end convertAlgorithm;
891
892 function convertStatement
893 input Statement stmt;
894 output DAE.Statement elem;
895 algorithm
896 elem := match stmt
897 local
898 DAE.Exp e1, e2, e3;
899 DAE.Type ty;
900 list<DAE.Statement> body;
901
902 86802 case Statement.ASSIGNMENT() then convertAssignment(stmt);
903
904 case Statement.FUNCTION_ARRAY_INIT()
905 algorithm
906 ✗ ty := Type.toDAE(stmt.ty);
907 ✗ then
908 DAE.Statement.STMT_ARRAY_INIT(stmt.name, ty, stmt.source);
909
910 571 case Statement.FOR() then convertForStatement(stmt);
911 4554 case Statement.IF() then convertIfStatement(stmt.branches, stmt.source);
912 81 case Statement.WHEN() then convertWhenStatement(stmt.branches, stmt.source);
913
914 case Statement.ASSERT()
915 algorithm
916 2883 e1 := Expression.toDAE(stmt.condition);
917 2883 e2 := Expression.toDAE(stmt.message);
918 2883 e3 := Expression.toDAE(stmt.level);
919 2883 then
920 DAE.Statement.STMT_ASSERT(e1, e2, e3, stmt.source);
921
922 case Statement.TERMINATE()
923 1 then DAE.Statement.STMT_TERMINATE(Expression.toDAE(stmt.message), stmt.source);
924
925 case Statement.REINIT()
926 algorithm
927 4 e1 := Expression.toDAE(stmt.cref);
928 4 e2 := Expression.toDAE(stmt.reinitExp);
929 4 then
930 DAE.Statement.STMT_REINIT(e1, e2, stmt.source);
931
932 case Statement.NORETCALL()
933 106 then DAE.Statement.STMT_NORETCALL(Expression.toDAE(stmt.exp), stmt.source);
934
935 case Statement.WHILE()
936 algorithm
937 206 e1 := Expression.toDAE(stmt.condition);
938 206 body := convertStatements(stmt.body);
939 206 then
940 DAE.Statement.STMT_WHILE(e1, body, stmt.source);
941
942 case Statement.RETURN()
943 7 then DAE.Statement.STMT_RETURN(stmt.source);
944
945 case Statement.BREAK()
946 2 then DAE.Statement.STMT_BREAK(stmt.source);
947
948 case Statement.FAILURE()
949 ✗ then DAE.Statement.STMT_FAILURE(convertStatements(stmt.body), stmt.source);
950
951 else
952 algorithm
953 ✗ Error.terminate(getInstanceName() + " got unknown statement " + Statement.toString(stmt), sourceInfo());
954 ✗ then
955 fail();
956 end match;
957 end convertStatement;
958
959 function convertAssignment
960 input Statement stmt;
961 output DAE.Statement daeStmt;
962 protected
963 Expression lhs, rhs;
964 DAE.ElementSource src;
965 Type ty;
966 DAE.Type dty;
967 DAE.Exp dlhs, drhs;
968 list<Expression> expl;
969 algorithm
970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86802 times.
86802 Statement.ASSIGNMENT(lhs, rhs, ty, src) := stmt;
971
972
2/2
✓ Branch 1 taken 544 times.
✓ Branch 2 taken 86258 times.
86802 if Type.isTuple(ty) then
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 544 times.
544 Expression.TUPLE(elements = expl) := lhs;
974
975 daeStmt := match expl
976 // () := call(...) => call(...)
977 ✗ case {} then DAE.Statement.STMT_NORETCALL(Expression.toDAE(rhs), src);
978
979 // (lhs) := call(...) => lhs := TSUB[call(...), 1]
980 case {lhs}
981 algorithm
982 ✗ dty := Type.toDAE(ty);
983 ✗ dlhs := Expression.toDAE(lhs);
984 ✗ drhs := DAE.Exp.TSUB(Expression.toDAE(rhs), 1, dty);
985
986 ✗ if Type.isArray(ty) then
987 ✗ daeStmt := DAE.Statement.STMT_ASSIGN_ARR(dty, dlhs, drhs, src);
988 else
989 ✗ daeStmt := DAE.Statement.STMT_ASSIGN(dty, dlhs, drhs, src);
990 end if;
991 then
992 daeStmt;
993
994 else
995 algorithm
996 544 dty := Type.toDAE(ty);
997 544 drhs := Expression.toDAE(rhs);
998
4/4
✓ Branch 0 taken 1217 times.
✓ Branch 1 taken 544 times.
✓ Branch 2 taken 1217 times.
✓ Branch 3 taken 544 times.
1761 then
999 DAE.Statement.STMT_TUPLE_ASSIGN(dty, list(Expression.toDAE(e) for e in expl), drhs, src);
1000 end match;
1001 else
1002 86258 dty := Type.toDAE(ty);
1003 86258 dlhs := Expression.toDAE(lhs);
1004 86258 drhs := Expression.toDAE(rhs);
1005
1006
2/2
✓ Branch 1 taken 1536 times.
✓ Branch 2 taken 84722 times.
86258 if Type.isArray(ty) then
1007 1536 daeStmt := DAE.Statement.STMT_ASSIGN_ARR(dty, dlhs, drhs, src);
1008 else
1009 84722 daeStmt := DAE.Statement.STMT_ASSIGN(dty, dlhs, drhs, src);
1010 end if;
1011 end if;
1012 end convertAssignment;
1013
1014 function convertForStatement
1015 input Statement forStmt;
1016 output DAE.Statement forDAE;
1017 protected
1018 InstNode iterator;
1019 Type ty;
1020 Expression range;
1021 list<Statement> body;
1022 list<DAE.Statement> dbody;
1023 DAE.ElementSource source;
1024 Statement.ForType for_type;
1025 list<tuple<DAE.ComponentRef, SourceInfo>> loop_vars;
1026 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters_dae;
1027 list<tuple<ComponentRef, array<Expression>>> sub_iters;
1028 algorithm
1029
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 571 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 571 times.
571 Statement.FOR(iterator = iterator, range = SOME(range), body = body, forType = for_type, source = source, sub_iters = sub_iters) := forStmt;
1030 571 dbody := convertStatements(body);
1031 571 ty := InstNode.getType(iterator);
1032
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 571 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
571 sub_iters_dae := list(
1033 (ComponentRef.toDAE(Util.tuple21(si)),
1034 listArray(list(Expression.toDAE(e) for e in arrayList(Util.tuple22(si)))))
1035 for si in sub_iters);
1036
1037 forDAE := match for_type
1038 case Statement.ForType.NORMAL()
1039
1/2
✓ Branch 3 taken 571 times.
✗ Branch 4 not taken.
1142 then DAE.Statement.STMT_FOR(Type.toDAE(ty), Type.isArray(ty),
1040 InstNode.name(iterator), Expression.toDAE(range), dbody, source, sub_iters_dae);
1041
1042 case Statement.ForType.PARALLEL()
1043 algorithm
1044 ✗ loop_vars := list(convertForStatementParallelVar(v) for v in for_type.vars);
1045 ✗ then
1046 DAE.Statement.STMT_PARFOR(Type.toDAE(ty), Type.isArray(ty),
1047 InstNode.name(iterator), Expression.toDAE(range), dbody, loop_vars, source);
1048 end match;
1049 end convertForStatement;
1050
1051 function convertForStatementParallelVar
1052 input tuple<ComponentRef, SourceInfo> var;
1053 output tuple<DAE.ComponentRef, SourceInfo> outVar;
1054 protected
1055 ComponentRef cref;
1056 DAE.ComponentRef dcref;
1057 SourceInfo info;
1058 algorithm
1059 ✗ (cref, info) := var;
1060 ✗ dcref := ComponentRef.toDAE(cref);
1061 ✗ outVar := (dcref, info);
1062 end convertForStatementParallelVar;
1063
1064 function convertIfStatement
1065 input list<tuple<Expression, list<Statement>>> ifBranches;
1066 input DAE.ElementSource source;
1067 output DAE.Statement ifStatement;
1068 protected
1069 Expression cond;
1070 DAE.Exp dcond;
1071 list<Statement> stmts;
1072 list<DAE.Statement> dstmts;
1073 Boolean first = true;
1074 Boolean single = listLength(ifBranches) == 1;
1075 DAE.Else else_stmt = DAE.Else.NOELSE();
1076 algorithm
1077
2/2
✓ Branch 1 taken 9610 times.
✓ Branch 2 taken 4554 times.
14164 for b in listReverse(ifBranches) loop
1078 9610 (cond, stmts) := b;
1079 9610 dcond := Expression.toDAE(cond);
1080 9610 dstmts := convertStatements(stmts);
1081
1082
4/4
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 6148 times.
✓ Branch 3 taken 3409 times.
✓ Branch 4 taken 53 times.
9610 if first and not single and Expression.isTrue(cond) then
1083 3409 else_stmt := DAE.Else.ELSE(dstmts);
1084 else
1085 6201 else_stmt := DAE.Else.ELSEIF(dcond, dstmts, else_stmt);
1086 end if;
1087
1088 first := false;
1089 end for;
1090
1091 // This should always be an ELSEIF due to branch selection in earlier phases.
1092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4554 times.
4554 DAE.Else.ELSEIF(dcond, dstmts, else_stmt) := else_stmt;
1093 4554 ifStatement := DAE.Statement.STMT_IF(dcond, dstmts, else_stmt, source);
1094 end convertIfStatement;
1095
1096 function convertWhenStatement
1097 input list<tuple<Expression, list<Statement>>> whenBranches;
1098 input DAE.ElementSource source;
1099 output DAE.Statement whenStatement;
1100 protected
1101 Expression co;
1102 list<ComponentRef> conditions;
1103 DAE.Exp cond;
1104 list<DAE.Statement> stmts;
1105 Option<DAE.Statement> when_stmt = NONE();
1106 algorithm
1107
2/2
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 81 times.
198 for b in listReverse(whenBranches) loop
1108 117 co := Util.tuple21(b);
1109
6/6
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 221 times.
✓ Branch 7 taken 117 times.
✓ Branch 8 taken 53 times.
✓ Branch 9 taken 117 times.
338 conditions := list(c for c guard(Type.isBoolean(ComponentRef.getSubscriptedType(c))) in UnorderedSet.toList(Expression.extractCrefs(co)));
1110 117 cond := Expression.toDAE(co);
1111 117 stmts := convertStatements(Util.tuple22(b));
1112
4/4
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 53 times.
✓ Branch 3 taken 117 times.
170 when_stmt := SOME(DAE.Statement.STMT_WHEN(cond, list(ComponentRef.toDAE(c) for c in conditions), false, stmts, when_stmt, source));
1113 end for;
1114
1115
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81 times.
81 SOME(whenStatement) := when_stmt;
1116 end convertWhenStatement;
1117
1118 function convertInitialAlgorithms
1119 input list<Algorithm> algorithms;
1120 input output list<DAE.Element> elements;
1121 algorithm
1122
2/2
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 1374 times.
1420 for alg in listReverse(algorithms) loop
1123 46 elements := convertInitialAlgorithm(alg, elements);
1124 end for;
1125 end convertInitialAlgorithms;
1126
1127 function convertInitialAlgorithm
1128 input Algorithm alg;
1129 input output list<DAE.Element> elements;
1130 protected
1131 list<DAE.Statement> stmts;
1132 DAE.Algorithm dalg;
1133 algorithm
1134 46 stmts := convertStatements(alg.statements);
1135 46 dalg := DAE.ALGORITHM_STMTS(stmts);
1136 46 elements := DAE.INITIALALGORITHM(dalg, alg.source) :: elements;
1137 end convertInitialAlgorithm;
1138
1139 public function convertFunctionTree
1140 input FunctionTree funcs;
1141 output AvlTreePathFunction.Tree dfuncs;
1142 algorithm
1143 dfuncs := match funcs
1144 local
1145 AvlTreePathFunction.Tree left, right;
1146 DAE.Function fn;
1147
1148 case FunctionTree.NODE()
1149 algorithm
1150 6232 fn := convertFunction(funcs.value);
1151 6232 left := convertFunctionTree(funcs.left);
1152 6232 right := convertFunctionTree(funcs.right);
1153 6232 then
1154 AvlTreePathFunction.Tree.NODE(funcs.key, SOME(fn), funcs.height, left, right);
1155
1156 case FunctionTree.LEAF()
1157 algorithm
1158 5153 fn := convertFunction(funcs.value);
1159 5153 then
1160 AvlTreePathFunction.Tree.LEAF(funcs.key, SOME(fn));
1161
1162 case FunctionTree.EMPTY()
1163 then AvlTreePathFunction.Tree.EMPTY();
1164
1165 end match;
1166 end convertFunctionTree;
1167
1168 protected function convertFunction
1169 input Function func;
1170 output DAE.Function dfunc;
1171 protected
1172 Class cls;
1173 list<DAE.Element> elems;
1174 DAE.FunctionDefinition def;
1175 Sections sections;
1176 algorithm
1177 11385 cls := InstNode.getClass(Function.instance(func));
1178
1179 dfunc := match cls
1180 case Class.TYPED_DERIVED(restriction = Restriction.FUNCTION())
1181 guard Function.isPartialDerivative(func)
1182 algorithm
1183 1 def := DAE.FunctionDefinition.FUNCTION_PARTIAL_DERIVATIVE(
1184 Function.getDerivedFunctionName(func), Function.getDerivedInputNames(func));
1185 1 then
1186 Function.toDAE(func, def);
1187
1188 case Class.INSTANCED_CLASS(sections = sections, restriction = Restriction.FUNCTION())
1189 algorithm
1190 9809 elems := convertFunctionParams(func.inputs, {});
1191
4/4
✓ Branch 0 taken 10164 times.
✓ Branch 1 taken 9809 times.
✓ Branch 2 taken 10164 times.
✓ Branch 3 taken 9809 times.
19973 elems := convertFunctionParams(list(InstNode.fromHandle(o) for o in func.outputs), elems);
1192 9809 elems := convertFunctionParams(func.locals, elems);
1193
1194 def := match sections
1195 // A function with an algorithm section.
1196 case Sections.SECTIONS()
1197 algorithm
1198 9500 elems := convertAlgorithms(sections.algorithms, elems);
1199 9500 then
1200 DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems));
1201
1202 // An external function.
1203 case Sections.EXTERNAL()
1204 277 then convertExternalDecl(sections, listReverse(elems));
1205
1206 // A function without either algorithm or external section.
1207 32 else DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems));
1208 end match;
1209 9809 then
1210 Function.toDAE(func, def);
1211
1212 case Class.INSTANCED_CLASS(restriction = Restriction.RECORD_CONSTRUCTOR())
1213 1575 then DAE.Function.RECORD_CONSTRUCTOR(Function.name(func),
1214 Function.makeDAEType(func),
1215 DAE.emptyElementSource);
1216
1217 else
1218 algorithm
1219 ✗ Error.terminate(getInstanceName() + " got unknown function", sourceInfo());
1220 ✗ then
1221 fail();
1222
1223 end match;
1224 end convertFunction;
1225
1226 function convertFunctionParams
1227 input list<InstNode> params;
1228 input output list<DAE.Element> elements;
1229 algorithm
1230
2/2
✓ Branch 0 taken 57256 times.
✓ Branch 1 taken 29427 times.
86683 for p in params loop
1231 57256 elements := convertFunctionParam(p) :: elements;
1232 end for;
1233 end convertFunctionParams;
1234
1235 function convertFunctionParam
1236 input InstNode node;
1237 output DAE.Element element;
1238 protected
1239 Component comp;
1240 Class cls;
1241 SourceInfo info;
1242 Option<DAE.VariableAttributes> var_attr;
1243 ComponentRef cref;
1244 Attributes attr;
1245 Type ty;
1246 Option<DAE.Exp> binding;
1247 list<tuple<String, Binding>> ty_attr;
1248 algorithm
1249 57256 comp := InstNode.component(node);
1250
1251 element := match comp
1252 case Component.COMPONENT(ty = ty, info = info, attributes = attr)
1253 algorithm
1254 57256 cref := ComponentRef.fromNode(node, ty);
1255 57256 binding := Binding.toDAEExp(comp.binding);
1256 57256 cls := InstNode.getClass(comp.classInst);
1257
4/4
✓ Branch 1 taken 74439 times.
✓ Branch 2 taken 57256 times.
✓ Branch 3 taken 74439 times.
✓ Branch 4 taken 57256 times.
131695 ty_attr := list((Modifier.name(m), Modifier.binding(m)) for m in Class.getTypeAttributes(cls));
1258 57256 var_attr := convertVarAttributes(ty_attr, ty, attr);
1259 57256 then
1260 makeDAEVar(cref, ty, binding, attr, InstNode.visibility(node), var_attr,
1261 comp.comment, FUNCTION_VARIABLE_CONVERSION_SETTINGS, info, false);
1262
1263 else
1264 algorithm
1265 ✗ Error.terminate(getInstanceName() + " got invalid component.", sourceInfo());
1266 ✗ then
1267 fail();
1268
1269 end match;
1270 end convertFunctionParam;
1271
1272 function convertExternalDecl
1273 input Sections extDecl;
1274 input list<DAE.Element> parameters;
1275 output DAE.FunctionDefinition funcDef;
1276 protected
1277 DAE.ExternalDecl decl;
1278 list<DAE.ExtArg> args;
1279 DAE.ExtArg ret_arg;
1280 algorithm
1281 funcDef := match extDecl
1282 case Sections.EXTERNAL()
1283 algorithm
1284
4/4
✓ Branch 0 taken 965 times.
✓ Branch 1 taken 277 times.
✓ Branch 2 taken 965 times.
✓ Branch 3 taken 277 times.
1242 args := list(convertExternalDeclArg(e) for e in extDecl.args);
1285 277 ret_arg := convertExternalDeclOutput(extDecl.outputRef);
1286 277 decl := DAE.ExternalDecl.EXTERNALDECL(extDecl.name, args, ret_arg, extDecl.language, extDecl.ann);
1287 277 then
1288 DAE.FunctionDefinition.FUNCTION_EXT(parameters, decl);
1289 end match;
1290 end convertExternalDecl;
1291
1292 function convertExternalDeclArg
1293 input Expression exp;
1294 output DAE.ExtArg arg;
1295 algorithm
1296 arg := match exp
1297 local
1298 Absyn.Direction dir;
1299 ComponentRef cref;
1300 Expression e;
1301
1302 case Expression.CREF(cref = cref as ComponentRef.CREF())
1303 algorithm
1304 874 dir := Prefixes.directionToAbsyn(Component.direction(InstNode.component(ComponentRef.node(cref))));
1305 874 then
1306 DAE.ExtArg.EXTARG(ComponentRef.toDAE(cref), dir, Type.toDAE(exp.ty));
1307
1308 case Expression.SIZE(exp = Expression.CREF(cref = cref as ComponentRef.CREF()), dimIndex = SOME(e))
1309 87 then DAE.ExtArg.EXTARGSIZE(ComponentRef.toDAE(cref), Type.toDAE(cref.ty), Expression.toDAE(e));
1310
1311 4 else DAE.ExtArg.EXTARGEXP(Expression.toDAE(exp), Type.toDAE(Expression.typeOf(exp)));
1312
1313 end match;
1314 end convertExternalDeclArg;
1315
1316 function convertExternalDeclOutput
1317 input ComponentRef cref;
1318 output DAE.ExtArg arg;
1319 algorithm
1320 arg := match cref
1321 local
1322 Absyn.Direction dir;
1323
1324 case ComponentRef.CREF()
1325 algorithm
1326 177 dir := Prefixes.directionToAbsyn(Component.direction(InstNode.component(ComponentRef.node(cref))));
1327 177 then
1328 DAE.ExtArg.EXTARG(ComponentRef.toDAE(cref), dir, Type.toDAE(cref.ty));
1329
1330 else DAE.ExtArg.NOEXTARG();
1331 end match;
1332 end convertExternalDeclOutput;
1333
1334 public
1335 function makeTypeVars
1336 input InstNode complexCls;
1337 output list<DAE.Var> typeVars;
1338 protected
1339 algorithm
1340 typeVars := match cls as InstNode.getClass(complexCls)
1341 case Class.INSTANCED_CLASS(restriction = Restriction.RECORD())
1342
4/4
✓ Branch 1 taken 81916 times.
✓ Branch 2 taken 12781 times.
✓ Branch 4 taken 81916 times.
✓ Branch 5 taken 12781 times.
189394 then list(makeTypeRecordVar(c) for c in ClassTree.getComponents(cls.elements));
1343
1344 case Class.INSTANCED_CLASS(restriction = Restriction.RECORD_CONSTRUCTOR())
1345
6/6
✓ Branch 3 taken 1575 times.
✓ Branch 4 taken 13722 times.
✓ Branch 5 taken 15297 times.
✓ Branch 6 taken 1575 times.
✓ Branch 7 taken 13722 times.
✓ Branch 8 taken 1575 times.
32169 then list(makeTypeRecordVar(c) for c guard not InstNode.isOutput(c)
1346 in ClassTree.getComponents(cls.elements));
1347
1348 case Class.INSTANCED_CLASS(elements = ClassTree.FLAT_TREE())
1349 ✗ then list(makeTypeVar(c) for c guard not InstNode.isOnlyOuter(c)
1350 in ClassTree.getComponents(cls.elements));
1351
1352 else {};
1353 end match;
1354 end makeTypeVars;
1355
1356 function makeTypeVar
1357 input InstNode component;
1358 output DAE.Var typeVar;
1359 protected
1360 Component comp;
1361 Attributes attr;
1362 algorithm
1363 ✗ comp := InstNode.component(InstNode.resolveOuter(component));
1364 ✗ attr := Component.getAttributes(comp);
1365
1366 ✗ typeVar := DAE.TYPES_VAR(
1367 InstNode.name(component),
1368 Attributes.toDAE(attr, InstNode.visibility(component)),
1369 Type.toDAE(Component.getType(comp)),
1370 Binding.toDAE(Component.getBinding(comp)),
1371 false,
1372 NONE()
1373 );
1374 end makeTypeVar;
1375
1376 function makeTypeRecordVar
1377 input InstNode component;
1378 output DAE.Var typeVar;
1379 protected
1380 Component comp;
1381 Attributes attr;
1382 Visibility vis;
1383 Binding binding;
1384 Boolean bind_from_outside;
1385 Type ty;
1386 algorithm
1387 95638 comp := InstNode.component(component);
1388 95638 attr := Component.getAttributes(comp);
1389
1390
2/2
✓ Branch 1 taken 94469 times.
✓ Branch 2 taken 1169 times.
95638 if Component.isFinal(comp) then
1391 vis := Visibility.PROTECTED;
1392 else
1393 94469 vis := InstNode.visibility(component);
1394 end if;
1395
1396 95638 binding := Component.getBinding(comp);
1397 95638 binding := Binding.mapExp(binding, stripScopePrefixExp);
1398 95638 binding := Flatten.flattenBinding(binding, NFFlatten.EMPTY_PREFIX);
1399 95638 bind_from_outside := Binding.source(binding) == NFBinding.Source.MODIFIER;
1400
1401 95638 ty := Component.getType(comp);
1402 95638 ty := Type.mapDims(ty, stripScopePrefixFromDim);
1403
1404
2/2
✓ Branch 0 taken 94921 times.
✓ Branch 1 taken 717 times.
190559 typeVar := DAE.TYPES_VAR(
1405 InstNode.name(component),
1406 Attributes.toDAE(attr, vis),
1407 Type.toDAE(ty),
1408 Binding.toDAE(binding),
1409 bind_from_outside,
1410 NONE()
1411 );
1412 end makeTypeRecordVar;
1413
1414 protected function stripScopePrefixFromDim
1415 input output Dimension dim;
1416 algorithm
1417 10844 dim := Dimension.mapExp(dim, stripScopePrefixCrefExp);
1418 end stripScopePrefixFromDim;
1419
1420 function stripScopePrefixExp
1421 input output Expression exp;
1422 algorithm
1423 24792 exp := Expression.map(exp, stripScopePrefixCrefExp);
1424 end stripScopePrefixExp;
1425
1426 function stripScopePrefixCrefExp
1427 input output Expression exp;
1428 algorithm
1429 () := match exp
1430 case Expression.CREF()
1431 algorithm
1432 192 exp.cref := stripScopePrefixCref(exp.cref);
1433 then
1434 ();
1435
1436 else ();
1437 end match;
1438 end stripScopePrefixCrefExp;
1439
1440 function stripScopePrefixCref
1441 input output ComponentRef cref;
1442 algorithm
1443
1444
2/2
✓ Branch 1 taken 170 times.
✓ Branch 2 taken 22 times.
192 if ComponentRef.isSimple(cref) then
1445 170 return;
1446 end if;
1447
1448 () := match cref
1449 case ComponentRef.CREF()
1450 algorithm
1451
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
22 if ComponentRef.isFromCref(cref.restCref) then
1452 ✗ cref.restCref := stripScopePrefixCref(cref.restCref);
1453 else
1454 22 cref.restCref := ComponentRef.EMPTY();
1455 end if;
1456 then
1457 ();
1458
1459 else ();
1460 end match;
1461
1462 end stripScopePrefixCref;
1463
1464 annotation(__OpenModelica_Interface="nf_frontend");
1465 end NFConvertDAE;
1466