Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 40.0% 66 / 0 / 165
Functions: -% 0 / 1 / 1
Branches: 38.9% 14 / 0 / 36

OMCompiler/Compiler/FrontEnd/Dump.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 Dump
37 " file: Dump.mo
38 package: Dump
39 description: debug printing
40
41
42 Printing routines for debugging of the AST. These functions do
43 nothing but print the data structures to the standard output.
44
45 The main entrypoint for this module is the function Dump.dump
46 which takes an entire program as an argument, and prints it all
47 in Modelica source form. The other interface functions can be
48 used to print smaller portions of a program."
49
50 // public imports
51 import Absyn;
52 import File;
53 import File.Escape;
54
55 // protected imports
56 protected
57
58 import AbsynDumpTpl;
59 import Config;
60 import Flags;
61 import FlagsUtil;
62 import List;
63 import Print;
64 import Tpl;
65 import Util;
66
67 public
68
69 uniontype DumpOptions
70 record DUMPOPTIONS
71 String fileName;
72 end DUMPOPTIONS;
73 end DumpOptions;
74
75 constant DumpOptions defaultDumpOptions = DUMPOPTIONS("");
76
77 function boolUnparseFileFromInfo "Returns true if the filename in the SOURCEINFO should be unparsed"
78 input SourceInfo info;
79 input DumpOptions options;
80 output Boolean b;
81 algorithm
82 b := match (options,info)
83 case (DUMPOPTIONS(fileName=""),_) then true; // The default is to not filter
84
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
5 case (DUMPOPTIONS(),SOURCEINFO()) then options.fileName == info.fileName;
85 end match;
86 end boolUnparseFileFromInfo;
87
88 public function unparseStr
89 "Prettyprints the Program, i.e. the whole AST, to a string."
90 input Absyn.Program inProgram;
91 input Boolean markup = false "
92 Used by MathCore, and dependencies to other modules requires this to also be in OpenModelica.
93 Contact peter.aronsson@mathcore.com for an explanation.
94
95 Note: This will be used for a different purpose in OpenModelica once we redesign Dump to use templates
96 ... by sending in DumpOptions (for example to add markup, etc)
97 ";
98 input DumpOptions options = defaultDumpOptions;
99 output String outString;
100 protected
101 Boolean status;
102 algorithm
103 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
104 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
105 196 status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
106 196 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
107 196 outString := Tpl.tplString2(AbsynDumpTpl.dump, inProgram, options);
108 196 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
109 end unparseStr;
110
111 public function unparseClassList
112 "Prettyprints a list of classes"
113 input list<Absyn.Class> inClasses;
114 output String outString;
115 protected
116 Boolean status;
117 algorithm
118 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
119 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
120 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
121 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
122 ✗ outString := Tpl.tplString2(AbsynDumpTpl.dump, Absyn.PROGRAM(inClasses, Absyn.TOP()), defaultDumpOptions);
123 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
124 end unparseClassList;
125
126 public function unparseClassStr
127 "Prettyprints a Class."
128 input Absyn.Class inClass;
129 output String outString;
130 algorithm
131 protected
132 Boolean status;
133 algorithm
134 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
135 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
136 1 status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
137 1 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
138 1 outString := Tpl.tplString3(AbsynDumpTpl.dumpClass, inClass, "", defaultDumpOptions);
139 1 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
140 end unparseClassStr;
141
142 public function unparseWithin
143 "Prettyprints a within statement."
144 input Absyn.Within inWithin;
145 output String outString;
146 protected
147 Boolean status;
148 algorithm
149 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
150 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
151 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
152 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
153 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpWithin, inWithin);
154 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
155 end unparseWithin;
156
157 public function unparseClassAttributesStr
158 "Prettyprints Class attributes."
159 input Absyn.Class inClass;
160 output String outString;
161 algorithm
162 outString := match inClass
163 local
164 String s1,s2,s2_1,s3,str;
165 Boolean p,f,e;
166 Absyn.Restriction r;
167
168 case Absyn.CLASS(partialPrefix = p,finalPrefix = f,encapsulatedPrefix = e,restriction = r)
169 algorithm
170 ✗ s1 := if p then "partial " else "";
171 ✗ s2 := if f then "final " else "";
172 ✗ s2_1 := if e then "encapsulated " else "";
173 ✗ s3 := unparseRestrictionStr(r);
174 ✗ str := stringAppendList({s2_1,s1,s2,s3});
175 then
176 str;
177 end match;
178 end unparseClassAttributesStr;
179
180 public function unparseCommentOption
181 "Prettyprints a Comment."
182 input Option<Absyn.Comment> inComment;
183 output String outString;
184 algorithm
185 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpCommentOpt, inComment);
186 end unparseCommentOption;
187
188 public function unparseRestrictionStr
189 "Prettyprints the class restriction."
190 input Absyn.Restriction inRestriction;
191 output String outString;
192 algorithm
193 6 outString := Tpl.tplString(AbsynDumpTpl.dumpRestriction, inRestriction);
194 end unparseRestrictionStr;
195
196 public function unparseEachStr
197 "Prettyprints the each keyword."
198 input Absyn.Each inEach;
199 output String outString;
200 algorithm
201 outString := match inEach
202 case Absyn.EACH() then "each ";
203 case Absyn.NON_EACH() then "";
204 end match;
205 end unparseEachStr;
206
207 public function unparseElementArgStr "Prettyprints an Absyn.ElementArg"
208 input Absyn.ElementArg inElementArg;
209 output String outString;
210 protected
211 Boolean status;
212 algorithm
213 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
214 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
215 8 status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
216 8 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
217 8 outString := Tpl.tplString(AbsynDumpTpl.dumpElementArg,inElementArg);
218 8 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
219 end unparseElementArgStr;
220
221 public function shouldSeparateAfterElementArg
222 input list<Absyn.ElementArg> args;
223 output list<tuple<Absyn.ElementArg,Boolean>> outArgs;
224 protected
225 Integer numNonComment=0, cur=0;
226 Boolean b;
227 algorithm
228
2/2
✓ Branch 0 taken 135138 times.
✓ Branch 1 taken 85279 times.
220417 for arg in args loop
229 numNonComment := match arg
230 case Absyn.ELEMENTARGCOMMENT() then numNonComment;
231 135137 else numNonComment + 1;
232 end match;
233 end for;
234 outArgs := {};
235
2/2
✓ Branch 0 taken 135138 times.
✓ Branch 1 taken 85279 times.
220417 for arg in args loop
236 b := match arg
237 case Absyn.ELEMENTARGCOMMENT() then false;
238 else
239 algorithm
240 135137 cur := cur + 1;
241
2/2
✓ Branch 0 taken 80755 times.
✓ Branch 1 taken 54382 times.
135137 then cur < numNonComment;
242 end match;
243
2/2
✓ Branch 0 taken 80755 times.
✓ Branch 1 taken 54382 times.
215893 outArgs := (arg,b)::outArgs;
244 end for;
245 85279 outArgs := listReverse(outArgs);
246 end shouldSeparateAfterElementArg;
247
248 public function unparseElementItemStr
249 "Prettyprints and ElementItem."
250 input Absyn.ElementItem inElementItem;
251 output String outString;
252 protected
253 Boolean status;
254 algorithm
255 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
256 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
257 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
258 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
259 ✗ outString := Tpl.tplString2(AbsynDumpTpl.dumpElementItem, inElementItem, defaultDumpOptions);
260 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
261 end unparseElementItemStr;
262
263 public function unparseAnnotation
264 "Prettyprint an annotation."
265 input Absyn.Annotation inAnnotation;
266 output String outString;
267 protected
268 Boolean status;
269 algorithm
270 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
271 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
272 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
273 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
274 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpAnnotation, inAnnotation);
275 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
276 end unparseAnnotation;
277
278 public function unparseAnnotationOption
279 "Prettyprint an annotation."
280 input Option<Absyn.Annotation> inAbsynAnnotation;
281 output String outString;
282 algorithm
283 outString := match inAbsynAnnotation
284 local
285 Absyn.Annotation ann;
286 ✗ case SOME(ann) then unparseAnnotation(ann);
287 else "";
288 end match;
289 end unparseAnnotationOption;
290
291 public function unparseInnerOuterStr
292 "Prettyprints the inner or outer keyword to a string."
293 input Absyn.InnerOuter inInnerOuter;
294 output String outString;
295 algorithm
296 outString:= match inInnerOuter
297 case Absyn.INNER() then "inner ";
298 case Absyn.OUTER() then "outer ";
299 case Absyn.INNER_OUTER() then "inner outer ";
300 case Absyn.NOT_INNER_OUTER() then "";
301 end match;
302 end unparseInnerOuterStr;
303
304 protected function unparseGroupImport
305 input Absyn.GroupImport gimp;
306 output String str;
307 algorithm
308 str := match gimp
309 local
310 String name,rename;
311 case Absyn.GROUP_IMPORT_NAME(name=name) then name;
312 case Absyn.GROUP_IMPORT_RENAME(rename=rename,name=name)
313 ✗ then rename + " = " + name;
314 end match;
315 end unparseGroupImport;
316
317 public function unparseImportStr
318 "Prettyprints an Import to a string."
319 input Absyn.Import inImport;
320 output String outString;
321 protected
322 Boolean status;
323 algorithm
324 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
325 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
326 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
327 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
328 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpImport, inImport);
329 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
330 end unparseImportStr;
331
332 protected function unparseVariabilitySymbolStr "
333 Returns a prettyprinted string of variability.
334 "
335 input Absyn.Variability inVariability;
336 output String outString;
337 algorithm
338 outString:=
339 match inVariability
340 case Absyn.VAR() then "";
341 case Absyn.DISCRETE() then "discrete ";
342 case Absyn.PARAM() then "parameter ";
343 case Absyn.CONST() then "constant ";
344 end match;
345 end unparseVariabilitySymbolStr;
346
347 public function unparseDirectionSymbolStr "Returns a prettyprinted string of direction."
348 input Absyn.Direction inDirection;
349 output String outString;
350 algorithm
351 outString:=
352 match inDirection
353 case Absyn.BIDIR() then "";
354 case Absyn.INPUT() then "input ";
355 case Absyn.OUTPUT() then "output ";
356 end match;
357 end unparseDirectionSymbolStr;
358
359 public function directionSymbol "
360 Returns a string for the direction.
361 "
362 input Absyn.Direction inDirection;
363 output String outString;
364 algorithm
365 outString:= match inDirection
366 case Absyn.BIDIR() then "";
367 case Absyn.INPUT() then "input";
368 case Absyn.OUTPUT() then "output";
369 end match;
370 end directionSymbol;
371
372 public function unparseParallelismSymbolStr
373 input Absyn.Parallelism inParallelism;
374 output String outString;
375 algorithm
376 outString:=
377 match inParallelism
378 case Absyn.NON_PARALLEL() then "";
379 case Absyn.PARGLOBAL() then "parglobal ";
380 case Absyn.PARLOCAL() then "parlocal ";
381 end match;
382 end unparseParallelismSymbolStr;
383
384 public function unparseComponentCondition "Prints a ComponentCondition option to a string."
385 input Option<Absyn.ComponentCondition> inComponentCondition;
386 output String outString;
387 protected
388 Boolean status;
389 algorithm
390 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
391 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
392 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
393 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
394 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpComponentCondition, inComponentCondition);
395 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
396 end unparseComponentCondition;
397
398 public function printArraydimStr "
399 Prettyprints an ArrayDim to a string.
400 "
401 input Absyn.ArrayDim s;
402 output String str;
403 algorithm
404 42 str := printSubscriptsStr(s);
405 end printArraydimStr;
406
407 public function printSubscriptStr "
408 Prettyprints an Subscript to a string.
409 "
410 input Absyn.Subscript inSubscript;
411 output String outString;
412 algorithm
413 outString:=
414 match inSubscript
415 local
416 String s;
417 Absyn.Exp e1;
418 case Absyn.NOSUB() then ":";
419 case Absyn.SUBSCRIPT(subscript = e1)
420 algorithm
421 1743 s := printExpStr(e1);
422 then
423 s;
424 end match;
425 end printSubscriptStr;
426
427 public function unparseModificationStr
428 "Prettyprints a Modification to a string."
429 input Absyn.Modification inModification;
430 output String outString;
431 protected
432 Boolean status;
433 algorithm
434 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
435 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
436 1 status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
437 1 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
438 1 outString := Tpl.tplString(AbsynDumpTpl.dumpModification, inModification);
439 1 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
440 end unparseModificationStr;
441
442 public function equationName
443 input Absyn.Equation eq;
444 output String name;
445 algorithm
446 name := match eq
447 case Absyn.EQ_IF() then "if";
448 case Absyn.EQ_EQUALS() then "equals";
449 case Absyn.EQ_PDE() then "pde";
450 case Absyn.EQ_CONNECT() then "connect";
451 case Absyn.EQ_WHEN_E() then "when";
452 case Absyn.EQ_NORETCALL() then "function call";
453 case Absyn.EQ_FAILURE() then "failure";
454 end match;
455 end equationName;
456
457 public function unparseClassPart
458 "Prettyprints an Equation to a string."
459 input Absyn.ClassPart classPart;
460 output String outString;
461 protected
462 Boolean status;
463 algorithm
464 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
465 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
466 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
467 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
468 ✗ outString := Tpl.tplString3(AbsynDumpTpl.dumpClassPart, classPart, 0, defaultDumpOptions);
469 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
470 end unparseClassPart;
471
472 public function unparseEquationStr
473 "Prettyprints an Equation to a string."
474 input Absyn.Equation inEquation;
475 output String outString;
476 protected
477 Boolean status;
478 algorithm
479 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
480 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
481 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
482 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
483 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpEquation, inEquation);
484 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
485 end unparseEquationStr;
486
487 public function unparseEquationItemStr
488 "Prettyprints an EquationItem to a string."
489 input Absyn.EquationItem inEquation;
490 output String outString;
491 protected
492 Boolean status;
493 algorithm
494 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
495 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
496 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
497 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
498 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpEquationItem, inEquation);
499 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
500 end unparseEquationItemStr;
501
502 public function unparseEquationItemStrLst
503 "Prettyprints and EquationItem list to a string."
504 input list<Absyn.EquationItem> inEquationItems;
505 input String inSeparator;
506 output String outString;
507 algorithm
508 ✗ outString := stringDelimitList(
509 List.map(inEquationItems, unparseEquationItemStr), inSeparator);
510 end unparseEquationItemStrLst;
511
512 public function unparseAlgorithmStrLst
513 "Prettyprints an AlgorithmItem list to a string."
514 input list<Absyn.AlgorithmItem> inAlgorithmItems;
515 input String inSeparator;
516 output String outString;
517 algorithm
518 ✗ outString := stringDelimitList(
519 List.map(inAlgorithmItems, unparseAlgorithmStr), inSeparator);
520 end unparseAlgorithmStrLst;
521
522 public function unparseAlgorithmStr
523 "Helper function to unparseAlgorithmStr"
524 input Absyn.AlgorithmItem inAlgorithmItem;
525 output String outString;
526 protected
527 Boolean status;
528 algorithm
529 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
530 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
531 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
532 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
533 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpAlgorithmItem, inAlgorithmItem);
534 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
535 end unparseAlgorithmStr;
536
537 public function printComponentRefStr "Print a ComponentRef and return as a string."
538 input Absyn.ComponentRef inComponentRef;
539 output String outString;
540 algorithm
541 outString := match inComponentRef
542 local
543 String subsstr,s_1,s,crs,s_2,s_3;
544 list<Absyn.Subscript> subs;
545 Absyn.ComponentRef cr;
546
547 case Absyn.CREF_IDENT(name = s,subscripts = subs)
548 algorithm
549 131307 subsstr := printSubscriptsStr(subs);
550 131307 s_1 := stringAppend(s, subsstr);
551 then
552 s_1;
553
554 case Absyn.CREF_QUAL(name = s,subscripts = subs,componentRef = cr)
555 algorithm
556 14288 crs := printComponentRefStr(cr);
557 14288 subsstr := printSubscriptsStr(subs);
558 14288 s_1 := stringAppend(s, subsstr);
559 14288 s_2 := stringAppend(s_1, ".");
560 14288 s_3 := stringAppend(s_2, crs);
561 then
562 s_3;
563
564 case Absyn.CREF_FULLYQUALIFIED(componentRef = cr)
565 algorithm
566 1 crs := printComponentRefStr(cr);
567 1 s_3 := stringAppend(".", crs);
568 then
569 s_3;
570
571 case Absyn.ALLWILD() then "__";
572
573 ✗ case Absyn.WILD() then if Config.acceptMetaModelicaGrammar() then "_" else "";
574
575 end match;
576 end printComponentRefStr;
577
578 public function printSubscriptsStr "Prettyprint a Subscript list to a string."
579 input list<Absyn.Subscript> inAbsynSubscriptLst;
580 output String outString;
581 algorithm
582 outString := match inAbsynSubscriptLst
583 local
584 String s,s_1,s_2;
585 list<Absyn.Subscript> l;
586
587 case {} then "";
588
589 case l
590 algorithm
591 1446 s := printListStr(l, printSubscriptStr, ",");
592 1446 s_1 := stringAppend("[", s);
593 1446 s_2 := stringAppend(s_1, "]");
594 then
595 s_2;
596 end match;
597 end printSubscriptsStr;
598
599 public function printFunctionArgsStr "
600 Prettyprint FunctionArgs to a string.
601 "
602 input Absyn.FunctionArgs inFunctionArgs;
603 output String outString;
604 algorithm
605 outString:=
606 matchcontinue inFunctionArgs
607 local
608 String s1,s2,s3,str,estr,istr;
609 list<Absyn.Exp> expargs;
610 list<Absyn.NamedArg> nargs;
611 Absyn.Exp exp;
612 Absyn.ForIterators iterators;
613 case Absyn.FUNCTIONARGS(args = (expargs as (_ :: _)),argNames = (nargs as (_ :: _)))
614 algorithm
615 ✗ s1 := printListStr(expargs, printExpStr, ", ") "Both positional and named arguments" ;
616 ✗ s2 := stringAppend(s1, ", ");
617 ✗ s3 := printListStr(nargs, printNamedArgStr, ", ");
618 ✗ str := stringAppend(s2, s3);
619 then
620 str;
621 case Absyn.FUNCTIONARGS(args = {},argNames = nargs)
622 algorithm
623 ✗ str := printListStr(nargs, printNamedArgStr, ", ") "Only named arguments" ;
624 then
625 str;
626 case Absyn.FUNCTIONARGS(args = expargs,argNames = {})
627 algorithm
628 ✗ str := printListStr(expargs, printExpStr, ", ") "Only positional arguments" ;
629 then
630 str;
631 case Absyn.FOR_ITER_FARG(exp = exp,iterators = iterators)
632 algorithm
633 ✗ estr := printExpStr(exp);
634 ✗ istr := printIteratorsStr(iterators);
635 ✗ str := stringAppendList({estr," for ", istr});
636 then
637 str;
638 end matchcontinue;
639 end printFunctionArgsStr;
640
641 function printIteratorsStr
642 " @author adrpo
643 prints iterators: i in exp1, j in exp2, k in exp3"
644 input Absyn.ForIterators iterators;
645 output String iteratorsStr;
646 algorithm
647 iteratorsStr := matchcontinue iterators
648 local
649 String s, s1, s2;
650 Absyn.Exp guardExp,exp;
651 Absyn.Ident id;
652 Absyn.ForIterators rest;
653 Absyn.ForIterator x;
654 case {} then "";
655 case {Absyn.ITERATOR(id, SOME(guardExp), SOME(exp))}
656 algorithm
657 ✗ s1 := printExpStr(exp);
658 ✗ s2 := printExpStr(guardExp);
659 ✗ s := stringAppendList({id, " guard ", s2, " in ", s1});
660 then s;
661 case {Absyn.ITERATOR(id, NONE(), SOME(exp))}
662 algorithm
663 ✗ s1 := printExpStr(exp);
664 ✗ s := stringAppendList({id, " in ", s1});
665 then s;
666 case {Absyn.ITERATOR(id, NONE(), NONE())} then id;
667 case x::rest
668 algorithm
669 ✗ s1 := printIteratorsStr({x});
670 ✗ s2 := printIteratorsStr(rest);
671 ✗ s := stringAppendList({s1, ", ", s2});
672 then s;
673 end matchcontinue;
674 end printIteratorsStr;
675
676 public function printNamedArgStr
677 "Prettyprint NamedArg to a string."
678 input Absyn.NamedArg inNamedArg;
679 output String outString;
680 algorithm
681 outString:=
682 match inNamedArg
683 local
684 String s1,s2,str,ident;
685 Absyn.Exp e;
686 case Absyn.NAMEDARG(argName = ident,argValue = e)
687 algorithm
688 35 s1 := stringAppend(ident, " = ");
689 35 s2 := printExpStr(e);
690 35 str := stringAppend(s1, s2);
691 then
692 str;
693 end match;
694 end printNamedArgStr;
695
696 public function printNamedArgValueStr
697 "Prettyprint NamedArg value to a string."
698 input Absyn.NamedArg inNamedArg;
699 output String outString;
700 algorithm
701 outString:=
702 match inNamedArg
703 local
704 String str;
705 Absyn.Exp e;
706 case Absyn.NAMEDARG(argValue = e)
707 algorithm
708 28 str := printExpStr(e);
709 then
710 str;
711 end match;
712 end printNamedArgValueStr;
713
714 public function shouldParenthesize
715 "Determines whether an operand in an expression needs parentheses around it."
716 input Absyn.Exp inOperand;
717 input Absyn.Exp inOperator;
718 input Boolean inLhs;
719 output Boolean outShouldParenthesize;
720 algorithm
721 outShouldParenthesize := match inOperand
722 local
723 Integer diff;
724
725 case Absyn.UNARY() then true;
726
727 else
728 algorithm
729 ✗ diff := Util.intCompare(expPriority(inOperand, inLhs),
730 expPriority(inOperator, inLhs));
731 ✗ then
732 shouldParenthesize2(diff, inOperand, inLhs);
733
734 end match;
735 end shouldParenthesize;
736
737 protected function shouldParenthesize2
738 input Integer inPrioDiff;
739 input Absyn.Exp inOperand;
740 input Boolean inLhs;
741 output Boolean outShouldParenthesize;
742 algorithm
743 outShouldParenthesize := match inPrioDiff
744 case 1 then true;
745 ✗ case 0 then if inLhs then isNonAssociativeExp(inOperand) else
746 not isAssociativeExp(inOperand);
747 else false;
748 end match;
749 end shouldParenthesize2;
750
751 protected function isAssociativeExp
752 "Determines whether the given expression represents an associative operation or not."
753 input Absyn.Exp inExp;
754 output Boolean outIsAssociative;
755 algorithm
756 outIsAssociative := match inExp
757 local
758 Absyn.Operator op;
759
760 ✗ case Absyn.BINARY(op = op) then isAssociativeOp(op);
761 case Absyn.LBINARY() then true;
762 else false;
763 end match;
764 end isAssociativeExp;
765
766 protected function isAssociativeOp
767 "Determines whether the given operator is associative or not."
768 input Absyn.Operator inOperator;
769 output Boolean outIsAssociative;
770 algorithm
771 outIsAssociative := match inOperator
772 case Absyn.ADD() then true;
773 case Absyn.ADD_EW() then true;
774 case Absyn.MUL_EW() then true;
775 else false;
776 end match;
777 end isAssociativeOp;
778
779 protected function isNonAssociativeExp
780 input Absyn.Exp exp;
781 output Boolean isNonAssociative;
782 algorithm
783 isNonAssociative := match exp
784 ✗ case Absyn.BINARY() then isNonAssociativeOp(exp.op);
785 else false;
786 end match;
787 end isNonAssociativeExp;
788
789 protected function isNonAssociativeOp
790 input Absyn.Operator operator;
791 output Boolean isNonAssociative;
792 algorithm
793 isNonAssociative := match operator
794 case Absyn.POW() then true;
795 case Absyn.POW_EW() then true;
796 else false;
797 end match;
798 end isNonAssociativeOp;
799
800 public function expPriority
801 "Returns an integer priority given an expression, which is used by
802 printOperatorStr to add parentheses around operands when dumping expressions.
803 The inLhs argument should be true if the expression occurs on the left side
804 of a binary operation, otherwise false. This is because we don't need to add
805 parentheses to expressions such as x * y / z, but x / (y * z) needs them, so
806 the priorities of some binary operations differ depending on which side they
807 are."
808 input Absyn.Exp inExp;
809 input Boolean inLhs;
810 output Integer outPriority;
811 algorithm
812 outPriority := match(inExp, inLhs)
813 local
814 Absyn.Operator op;
815
816 ✗ case (Absyn.BINARY(op = op), false) then priorityBinopRhs(op);
817 ✗ case (Absyn.BINARY(op = op), true) then priorityBinopLhs(op);
818 case (Absyn.UNARY(), _) then 4;
819 ✗ case (Absyn.LBINARY(op = op), _) then priorityLBinop(op);
820 case (Absyn.LUNARY(), _) then 7;
821 case (Absyn.RELATION(), _) then 6;
822 case (Absyn.RANGE(), _) then 10;
823 case (Absyn.IFEXP(), _) then 11;
824 else 0;
825 end match;
826 end expPriority;
827
828 protected function priorityBinopLhs
829 "Returns the priority for a binary operation on the left hand side. Add and
830 sub has the same priority, and mul and div too, in contrast with
831 priorityBinopRhs."
832 input Absyn.Operator inOp;
833 output Integer outPriority;
834 algorithm
835 outPriority := match inOp
836 case Absyn.ADD() then 5;
837 case Absyn.SUB() then 5;
838 case Absyn.MUL() then 2;
839 case Absyn.DIV() then 2;
840 case Absyn.POW() then 1;
841 case Absyn.ADD_EW() then 5;
842 case Absyn.SUB_EW() then 5;
843 case Absyn.MUL_EW() then 2;
844 case Absyn.DIV_EW() then 2;
845 case Absyn.POW_EW() then 1;
846 end match;
847 end priorityBinopLhs;
848
849 protected function priorityBinopRhs
850 "Returns the priority for a binary operation on the right hand side. Add and
851 sub has different priorities, and mul and div too, in contrast with
852 priorityBinopLhs."
853 input Absyn.Operator inOp;
854 output Integer outPriority;
855 algorithm
856 outPriority := match inOp
857 case Absyn.ADD() then 6;
858 case Absyn.SUB() then 5;
859 case Absyn.MUL() then 2;
860 case Absyn.DIV() then 2;
861 case Absyn.POW() then 1;
862 case Absyn.ADD_EW() then 6;
863 case Absyn.SUB_EW() then 5;
864 case Absyn.MUL_EW() then 3;
865 case Absyn.DIV_EW() then 2;
866 case Absyn.POW_EW() then 1;
867 end match;
868 end priorityBinopRhs;
869
870 protected function priorityLBinop
871 input Absyn.Operator inOp;
872 output Integer outPriority;
873 algorithm
874 outPriority := match inOp
875 case Absyn.AND() then 8;
876 case Absyn.OR() then 9;
877 end match;
878 end priorityLBinop;
879
880 protected function printOperandStr
881 "Prints an operand to a string."
882 input Absyn.Exp inOperand "The operand expression.";
883 input Absyn.Exp inOperation "The unary/binary operation which the operand belongs to.";
884 input Boolean inLhs "True if the operand is the left hand operand, otherwise false.";
885 output String outString;
886 algorithm
887 outString := matchcontinue inLhs
888 local
889 String op_str;
890
891 // Print parentheses around an operand if the priority of the operation is
892 // less than the priority of the operand.
893 case _
894 algorithm
895 ✗ true := shouldParenthesize(inOperand, inOperation, inLhs);
896 ✗ op_str := printExpStr(inOperand);
897 ✗ op_str := stringAppendList({"(", op_str, ")"});
898 then
899 op_str;
900
901 ✗ else printExpStr(inOperand);
902
903 end matchcontinue;
904 end printOperandStr;
905
906 public function printExpLstStr "exp
907
908 Prints a list of expressions to a string
909 "
910 input list<Absyn.Exp> expl;
911 output String outString;
912 algorithm
913 28 outString := stringDelimitList(List.map(expl,printExpStr),", ");
914 end printExpLstStr;
915
916 public function printExpStr "
917 This function prints a complete expression.
918 "
919 input Absyn.Exp inExp;
920 output String outString;
921 protected
922 Boolean status;
923 algorithm
924 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
925 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
926 33747 status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
927 33747 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
928 33747 outString := Tpl.tplString(AbsynDumpTpl.dumpExp, inExp);
929 33747 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
930 end printExpStr;
931
932 public function printCodeStr
933 "Prettyprint Code to a string."
934 input Absyn.CodeNode inCode;
935 output String outString;
936 protected
937 Boolean status;
938 algorithm
939 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
940 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
941 ✗ status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
942 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
943 ✗ outString := Tpl.tplString(AbsynDumpTpl.dumpCodeNode, inCode);
944 ✗ FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
945 end printCodeStr;
946
947 protected function printListStr
948 "Same as printList, except it returns a string instead of printing"
949 input list<Type_a> inTypeALst;
950 input FuncTypeType_aToString inFuncTypeTypeAToString;
951 input String inString;
952 output String outString;
953 replaceable type Type_a subtypeof Any;
954 partial function FuncTypeType_aToString
955 input Type_a inTypeA;
956 output String outString;
957 end FuncTypeType_aToString;
958 algorithm
959 outString := matchcontinue (inTypeALst,inFuncTypeTypeAToString,inString)
960 local
961 String s,srest,s_1,s_2,sep;
962 Type_a h;
963 FuncTypeType_aToString r;
964 list<Type_a> t;
965 case ({},_,_) then "";
966 case ({h},r,_)
967 algorithm
968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1446 times.
1446 s := r(h);
969 then
970 s;
971 case ((h :: t),r,sep)
972 algorithm
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
264 s := r(h);
974 264 srest := printListStr(t, r, sep);
975 264 s_1 := stringAppend(s, sep);
976 264 s_2 := stringAppend(s_1, srest);
977 then
978 s_2;
979 end matchcontinue;
980 end printListStr;
981
982 public function opSymbol
983 "Make a string describing different operators."
984 input Absyn.Operator inOperator;
985 output String outString;
986 algorithm
987 outString := match inOperator
988 /* arithmetic operators */
989 case Absyn.ADD() then " + ";
990 case Absyn.SUB() then " - ";
991 case Absyn.MUL() then " * ";
992 case Absyn.DIV() then " / ";
993 case Absyn.POW() then " ^ ";
994 case Absyn.UMINUS() then "-";
995 case Absyn.UPLUS() then "+";
996 /* element-wise arithmetic operators */
997 case Absyn.ADD_EW() then " .+ ";
998 case Absyn.SUB_EW() then " .- ";
999 case Absyn.MUL_EW() then " .* ";
1000 case Absyn.DIV_EW() then " ./ ";
1001 case Absyn.POW_EW() then " .^ ";
1002 case Absyn.UMINUS_EW() then " .-";
1003 case Absyn.UPLUS_EW() then " .+";
1004 /* logical operators */
1005 case Absyn.AND() then " and ";
1006 case Absyn.OR() then " or ";
1007 case Absyn.NOT() then "not ";
1008 /* relational operators */
1009 case Absyn.LESS() then " < ";
1010 case Absyn.LESSEQ() then " <= ";
1011 case Absyn.GREATER() then " > ";
1012 case Absyn.GREATEREQ() then " >= ";
1013 case Absyn.EQUAL() then " == ";
1014 case Absyn.NEQUAL() then " <> ";
1015 end match;
1016 end opSymbol;
1017
1018 public function opSymbolCompact
1019 "same as opSymbol but without spaces included
1020 used for operator overload resolving.
1021 Some of them are not supported ?? but have them
1022 anyway"
1023 input Absyn.Operator inOperator;
1024 output String outString;
1025 algorithm
1026 outString := match inOperator
1027 /* arithmetic operators */
1028 case Absyn.ADD() then "+";
1029 case Absyn.SUB() then "-";
1030 case Absyn.MUL() then "*";
1031 case Absyn.DIV() then "/";
1032 case Absyn.POW() then "^";
1033 case Absyn.UMINUS() then "-";
1034 case Absyn.UPLUS() then "+";
1035 /* element-wise arithmetic operators */
1036 case Absyn.ADD_EW() then "+";
1037 case Absyn.SUB_EW() then "-";
1038 case Absyn.MUL_EW() then "*";
1039 case Absyn.DIV_EW() then "/";
1040 case Absyn.POW_EW() then "^";
1041 case Absyn.UMINUS_EW() then "-";
1042 // case (Absyn.UPLUS_EW()) then "+";
1043 /* logical operators */
1044 case Absyn.AND() then "and";
1045 case Absyn.OR() then "or";
1046 case Absyn.NOT() then "not";
1047 /* relational operators */
1048 case Absyn.LESS() then "<";
1049 case Absyn.LESSEQ() then "<=";
1050 case Absyn.GREATER() then ">";
1051 case Absyn.GREATEREQ() then ">=";
1052 case Absyn.EQUAL() then "==";
1053 case Absyn.NEQUAL() then "<>";
1054 else fail();
1055 end match;
1056 end opSymbolCompact;
1057
1058 /*
1059 *
1060 * Utility functions
1061 * These are utility functions used in some of the other functions.
1062 *
1063 */
1064
1065 public function printOption "
1066 Prints an option value given a print function.
1067 "
1068 input Option<Type_a> inTypeAOption;
1069 input FuncTypeType_aTo inFuncTypeTypeATo;
1070 replaceable type Type_a subtypeof Any;
1071 partial function FuncTypeType_aTo
1072 input Type_a inTypeA;
1073 end FuncTypeType_aTo;
1074 algorithm
1075 ():= match inTypeAOption
1076 local
1077 Type_a x;
1078 case NONE()
1079 algorithm
1080 ✗ Print.printBuf("NONE()");
1081 then
1082 ();
1083 case SOME(x)
1084 algorithm
1085 ✗ Print.printBuf("SOME(");
1086 ✗ inFuncTypeTypeATo(x);
1087 ✗ Print.printBuf(")");
1088 then
1089 ();
1090 end match;
1091 end printOption;
1092
1093 public function printList "
1094 Prints a list of values given a print function.
1095 "
1096 input list<Type_a> inTypeALst;
1097 input FuncTypeType_aTo inFuncTypeTypeATo;
1098 input String inString;
1099 replaceable type Type_a subtypeof Any;
1100 partial function FuncTypeType_aTo
1101 input Type_a inTypeA;
1102 end FuncTypeType_aTo;
1103 algorithm
1104 ():=
1105 matchcontinue (inTypeALst,inFuncTypeTypeATo,inString)
1106 local
1107 Type_a h;
1108 FuncTypeType_aTo r;
1109 list<Type_a> t;
1110 String sep;
1111 case ({},_,_) then ();
1112 case ({h},r,_)
1113 algorithm
1114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 r(h);
1115 then
1116 ();
1117 case ((h :: t),r,sep)
1118 algorithm
1119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 r(h);
1120 2 Print.printBuf(sep);
1121 2 printList(t, r, sep);
1122 then
1123 ();
1124 end matchcontinue;
1125 end printList;
1126
1127 protected function printStringCommentOption "
1128 Print a string comment option on the Print buffer
1129 "
1130 input Option<String> inStringOption;
1131 algorithm
1132 () := match inStringOption
1133 local String str,s;
1134 case NONE()
1135 algorithm
1136 ✗ Print.printBuf("NONE()");
1137 then
1138 ();
1139 case SOME(s)
1140 algorithm
1141 ✗ str := stringAppendList({"SOME(\"",s,"\")"});
1142 ✗ Print.printBuf(str);
1143 then
1144 ();
1145 end match;
1146 end printStringCommentOption;
1147
1148 public function unparseTypeSpec
1149 input Absyn.TypeSpec inTypeSpec;
1150 output String outString;
1151 protected
1152 Boolean status;
1153 algorithm
1154 // adrpo: make sure WE DO NOT HAVE this config flag set here: #5680
1155 // -m, --modelicaOutput Enables valid modelica output for flat modelica.
1156 746 status := Flags.getConfigBool(Flags.MODELICA_OUTPUT);
1157 746 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, false);
1158 746 outString := Tpl.tplString(AbsynDumpTpl.dumpTypeSpec, inTypeSpec);
1159 746 FlagsUtil.setConfigBool(Flags.MODELICA_OUTPUT, status);
1160 end unparseTypeSpec;
1161
1162 public function printTypeSpec
1163 input Absyn.TypeSpec typeSpec;
1164 protected
1165 String str;
1166 algorithm
1167 ✗ str := unparseTypeSpec(typeSpec);
1168 ✗ print(str);
1169 end printTypeSpec;
1170
1171 public function stdout "
1172 Prints the text sent to the print buffer (Print.mo) to stdout (i.e.
1173 using MetaModelica Compiler (MMC) standard print). After printing, the print buffer is cleared.
1174 "
1175 protected
1176 String str;
1177 algorithm
1178 ✗ str := Print.getString();
1179 ✗ print(str);
1180 ✗ Print.clearBuf();
1181 end stdout;
1182
1183 public function writePath
1184 input File.File file;
1185 input Absyn.Path path;
1186 input Escape escape=Escape.None;
1187 input String delimiter=".";
1188 input Boolean initialDot=true;
1189 protected
1190 Absyn.Path p=path;
1191 algorithm
1192 while true loop
1193 p := match p
1194 case Absyn.IDENT()
1195 algorithm
1196 2244 File.writeEscape(file, p.name, escape);
1197 2244 return;
1198 then fail();
1199 case Absyn.QUALIFIED()
1200 algorithm
1201 2578 File.writeEscape(file, p.name, escape);
1202 2578 File.writeEscape(file, delimiter, escape);
1203 2578 then p.path;
1204 case Absyn.FULLYQUALIFIED()
1205 algorithm
1206 ✗ if initialDot then
1207 ✗ File.writeEscape(file, delimiter, escape);
1208 end if;
1209 ✗ then p.path;
1210 end match;
1211 end while;
1212 end writePath;
1213
1214 annotation(__OpenModelica_Interface="frontend_dump");
1215 end Dump;
1216