Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 23.7% 44 / 0 / 186
Functions: -% 0 / 1 / 1
Branches: 66.7% 8 / 0 / 12

OMCompiler/Compiler/FFrontEnd/FGraphBuildEnv.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 FGraphBuildEnv
37 " file: FGraphBuildEnv.mo
38 package: FGraphBuildEnv
39 description: A node builder for Modelica constructs
40
41
42 This module builds nodes out of SCode.
43 The only difference between this and FGraphBuild.mo is that
44 it doesn't expand all nodes and is better suited for usage
45 in the old instantiation.
46 "
47
48 public import Absyn;
49 public import AbsynUtil;
50 public import SCode;
51 public import FCore;
52 public import FNode;
53 public import FGraph;
54 public import DAE;
55 public
56 type Name = FCore.Name;
57 type Id = FCore.Id;
58 type Seq = FCore.Seq;
59 type Next = FCore.Next;
60 type Node = FCore.Node;
61 type Data = FCore.Data;
62 type Kind = FCore.Kind;
63 type Ref = FCore.Ref;
64 type Refs = FCore.Refs;
65 type Children = FCore.Children;
66 type Parents = FCore.Parents;
67 type ImportTable = FCore.ImportTable;
68 type Extra = FCore.Extra;
69 type Visited = FCore.Visited;
70 type Import = FCore.Import;
71 type Graph = FCore.Graph;
72 type Scope = FCore.Scope;
73
74 protected
75 import Dump;
76 import List;
77 import AbsynToSCode;
78 import SCodeDump;
79 import SCodeInstUtil;
80 import SCodeUtil;
81 import Util;
82
83 public function mkProgramGraph
84 "builds nodes out of classes"
85 input SCode.Program inProgram;
86 input Kind inKind;
87 input output Graph graph;
88 protected
89 Ref topRef;
90 algorithm
91 33440 topRef := FGraph.top(graph);
92
93
2/2
✓ Branch 0 taken 330156 times.
✓ Branch 1 taken 33440 times.
363596 for cls in inProgram loop
94 330156 graph := mkClassGraph(cls, topRef, inKind, graph, true);
95 end for;
96 end mkProgramGraph;
97
98 protected function mkClassGraph
99 "Extends the graph with a class."
100 input SCode.Element inClass;
101 input Ref inParentRef;
102 input Kind inKind;
103 input Graph inGraph;
104 input Boolean checkDuplicate = false;
105 output Graph outGraph;
106 algorithm
107 outGraph := match(inClass, inGraph)
108 local
109 Graph g;
110
111 // class (we don't care here if is replaceable or not we can get that from the class)
112 case (SCode.CLASS(), g)
113 algorithm
114 330156 g := mkClassNode(inClass, DAE.NOPRE(), DAE.NOMOD(), inParentRef,
115 inKind, g, checkDuplicate);
116 then
117 g;
118
119 end match;
120 end mkClassGraph;
121
122 public function mkClassNode
123 input SCode.Element inClass;
124 input DAE.Prefix inPrefix;
125 input DAE.Mod inMod;
126 input Ref inParentRef;
127 input Kind inKind;
128 input Graph inGraph;
129 input Boolean checkDuplicate = false;
130 output Graph outGraph;
131 algorithm
132 outGraph := match inGraph
133 local
134 SCode.Element cls;
135 String name;
136 Graph g;
137 Node n;
138 Ref nr;
139
140 case g
141 algorithm
142 8395171 cls := SCodeInstUtil.expandEnumerationClass(inClass);
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8395171 times.
8395171 SCode.CLASS(name = name) := cls;
144 8395171 (g, n) := FGraph.node(g, name, {inParentRef}, FCore.CL(cls, inPrefix, inMod, inKind, FCore.CLS_UNTYPED()));
145 8395171 nr := FNode.toRef(n);
146 8395171 FNode.addChildRef(inParentRef, name, nr, checkDuplicate);
147 // g = mkRefNode(FNode.refNodeName, {}, nr, g);
148 then
149 g;
150
151 end match;
152 end mkClassNode;
153
154 public function mkConstrainClass
155 input SCode.Element inElement;
156 input Ref inParentRef;
157 input Kind inKind;
158 input Graph inGraph;
159 output Graph outGraph;
160 algorithm
161 outGraph := matchcontinue(inElement, inGraph)
162 local
163 Graph g;
164 Node n;
165 Ref nr;
166 SCode.ConstrainClass cc;
167
168 case (SCode.CLASS(prefixes = SCode.PREFIXES(replaceablePrefix = SCode.REPLACEABLE(SOME(cc)))), g)
169 algorithm
170 ✗ (g, n) := FGraph.node(g, FNode.ccNodeName, {inParentRef}, FCore.CC(cc));
171 ✗ nr := FNode.toRef(n);
172 ✗ FNode.addChildRef(inParentRef, FNode.ccNodeName, nr);
173 then
174 g;
175
176 case (SCode.COMPONENT(prefixes = SCode.PREFIXES(replaceablePrefix = SCode.REPLACEABLE(SOME(cc)))), g)
177 algorithm
178 ✗ (g, n) := FGraph.node(g, FNode.ccNodeName, {inParentRef}, FCore.CC(cc));
179 ✗ nr := FNode.toRef(n);
180 ✗ FNode.addChildRef(inParentRef, FNode.ccNodeName, nr);
181 then
182 g;
183
184 // no cc found in element!
185 else inGraph;
186
187 end matchcontinue;
188 end mkConstrainClass;
189
190 public function mkModNode
191 input Name inName "a name for this mod so we can call it from sub-mods";
192 input SCode.Mod inMod;
193 input Ref inParentRef;
194 input Kind inKind;
195 input Graph inGraph;
196 output Graph outGraph;
197 algorithm
198 outGraph := matchcontinue(inName, inMod, inGraph)
199 local
200 Name name;
201 Graph g;
202 Node n;
203 Ref nr;
204 SCode.Element e;
205 list<SCode.SubMod> sm;
206 Option<Absyn.Exp> b;
207
208 // no mods
209 case (_, SCode.NOMOD(), g) then g;
210
211 // no binding no sub-mods
212 case (_, SCode.MOD(subModLst = {}, binding = NONE()), g)
213 then
214 g;
215
216 // just a binding
217 case (name, SCode.MOD(subModLst = {}, binding = b as SOME(_)), g)
218 algorithm
219 ✗ (g, n) := FGraph.node(g, name, {inParentRef}, FCore.MO(inMod));
220 ✗ nr := FNode.toRef(n);
221 ✗ FNode.addChildRef(inParentRef, name, nr);
222 ✗ g := mkBindingNode(b, nr, inKind, g);
223 then
224 g;
225
226 // yeha, some mods for sure and a possible binding
227 case (name, SCode.MOD(subModLst = sm, binding = b), g)
228 algorithm
229 ✗ (g, n) := FGraph.node(g, name, {inParentRef}, FCore.MO(inMod));
230 ✗ nr := FNode.toRef(n);
231 ✗ FNode.addChildRef(inParentRef, name, nr);
232 ✗ g := mkSubMods(sm, nr, inKind, g);
233 ✗ g := mkBindingNode(b, nr, inKind, g);
234 then
235 g;
236
237 // ouch, a redeclare :)
238 case (name, SCode.REDECL(element = e), g)
239 algorithm
240 ✗ (g, n) := FGraph.node(g, name, {inParentRef}, FCore.MO(inMod));
241 ✗ nr := FNode.toRef(n);
242 ✗ FNode.addChildRef(inParentRef, name, nr);
243 ✗ g := mkElementNode(e, nr, inKind, g);
244 then
245 g;
246
247 // something bad happened!
248 case (name, _, g)
249 algorithm
250 ✗ print("FGraphBuildEnv.mkModNode failed with: " + name + " mod: " + SCodeDump.printModStr(inMod, SCodeDump.defaultOptions) + "\n");
251 then
252 g;
253
254 end matchcontinue;
255 end mkModNode;
256
257 public function mkSubMods
258 input list<SCode.SubMod> inSubMod;
259 input Ref inParentRef;
260 input Kind inKind;
261 input Graph inGraph;
262 output Graph outGraph;
263 algorithm
264 outGraph := match(inSubMod, inGraph)
265 local
266 list<SCode.SubMod> rest;
267 Name id;
268 SCode.Mod m;
269 Graph g;
270
271 // no more, we're done!
272 case ({}, g) then g;
273
274 // some sub-mods!
275 case (SCode.NAMEMOD(id, m)::rest, g)
276 algorithm
277 ✗ g := mkModNode(id, m, inParentRef, inKind, g);
278 ✗ g := mkSubMods(rest, inParentRef, inKind, g);
279 then
280 g;
281
282 end match;
283 end mkSubMods;
284
285 public function mkBindingNode
286 input Option<Absyn.Exp> inBinding;
287 input Ref inParentRef;
288 input Kind inKind;
289 input Graph inGraph;
290 output Graph outGraph;
291 algorithm
292 outGraph := match(inBinding, inGraph)
293 local
294 Absyn.Exp e;
295 Graph g;
296
297 // no binding
298 case (NONE(), g) then g;
299
300 // some binding
301 case (SOME(e), g)
302 algorithm
303 ✗ g := mkExpressionNode(FNode.bndNodeName, e, inParentRef, inKind, g);
304 then
305 g;
306
307 end match;
308 end mkBindingNode;
309
310 protected function mkClassChildren
311 "Extends the graph with a class's components."
312 input SCode.ClassDef inClassDef;
313 input Ref inParentRef;
314 input Kind inKind;
315 input Graph inGraph;
316 output Graph outGraph;
317 algorithm
318 outGraph := matchcontinue(inClassDef, inGraph)
319 local
320 list<SCode.Element> el;
321 Graph g;
322 SCode.ClassDef cdef;
323 Ref nr;
324 Absyn.TypeSpec ts;
325 SCode.Mod m;
326 Absyn.ArrayDim ad;
327 list<SCode.Equation> eqs, ieqs;
328 list<SCode.AlgorithmSection> als, ials;
329 list<SCode.ConstraintSection> constraintLst;
330 list<Absyn.NamedArg> clsattrs;
331 Option<SCode.ExternalDecl> externalDecl;
332
333 case (SCode.PARTS(
334 elementLst = el,
335 normalEquationLst = eqs,
336 initialEquationLst = ieqs,
337 normalAlgorithmLst = als,
338 initialAlgorithmLst = ials,
339 constraintLst = constraintLst,
340 clsattrs = clsattrs,
341 externalDecl = externalDecl
342 ), g)
343 algorithm
344 ✗ g := List.fold2(el, mkElementNode, inParentRef, inKind, g);
345 ✗ g := mkEqNode(FNode.eqNodeName, eqs, inParentRef, inKind, g);
346 ✗ g := mkEqNode(FNode.ieqNodeName, ieqs, inParentRef, inKind, g);
347 ✗ g := mkAlNode(FNode.alNodeName, als, inParentRef, inKind, g);
348 ✗ g := mkAlNode(FNode.ialNodeName, ials, inParentRef, inKind, g);
349 ✗ g := mkOptNode(FNode.optNodeName, constraintLst, clsattrs, inParentRef, inKind, g);
350 ✗ g := mkExternalNode(FNode.edNodeName, externalDecl, inParentRef, inKind, g);
351 then
352 g;
353
354 case (SCode.CLASS_EXTENDS(composition = cdef, modifications = m), g)
355 algorithm
356 ✗ g := mkClassChildren(cdef, inParentRef, inKind, g);
357 ✗ g := mkModNode(FNode.modNodeName, m, inParentRef, inKind, g);
358 ✗ g := mkRefNode(FNode.refNodeName, {}, inParentRef, g);
359 then
360 g;
361
362 case (SCode.DERIVED(typeSpec = ts, modifications = m), g)
363 algorithm
364 nr := inParentRef;
365 ✗ g := mkModNode(FNode.modNodeName, m, nr, inKind, g);
366 ✗ ad := AbsynUtil.typeSpecDimensions(ts);
367 ✗ g := mkDimsNode(FNode.tydimsNodeName, SOME(ad), nr, inKind, g);
368 ✗ g := mkRefNode(FNode.refNodeName, {}, nr, g);
369 then
370 g;
371
372 case (SCode.OVERLOAD(_), g)
373 algorithm
374 then
375 g;
376
377 case (SCode.PDER(_, _), g)
378 algorithm
379 then
380 g;
381
382 else inGraph;
383
384 end matchcontinue;
385 end mkClassChildren;
386
387 public function mkElementNode
388 "Extends the graph with an element."
389 input SCode.Element inElement;
390 input Ref inParentRef;
391 input Kind inKind;
392 input Graph inGraph;
393 output Graph outGraph;
394 algorithm
395 outGraph := match(inElement, inGraph)
396 local
397 Graph g;
398 SCode.Ident name;
399 Absyn.Path p;
400 Node n;
401 Ref nr;
402 SCode.Mod m;
403
404 // component
405 case (SCode.COMPONENT(), g)
406 algorithm
407 ✗ g := mkCompNode(inElement, inParentRef, inKind, g);
408 then
409 g;
410
411 // class
412 case (SCode.CLASS(), g)
413 algorithm
414 ✗ g := mkClassNode(inElement, DAE.NOPRE(), DAE.NOMOD(), inParentRef, inKind, g);
415 then
416 g;
417
418 case (SCode.EXTENDS(baseClassPath = p, modifications = m), g)
419 algorithm
420 // the extends is saved as a child with the extends name
421 ✗ name := FNode.mkExtendsName(p);
422 ✗ (g, n) := FGraph.node(g, name, {inParentRef}, FCore.EX(inElement, DAE.NOMOD()));
423 ✗ nr := FNode.toRef(n);
424 ✗ FNode.addChildRef(inParentRef, name, nr);
425 ✗ g := mkModNode(FNode.modNodeName, m, nr, inKind, g);
426 ✗ g := mkRefNode(FNode.refNodeName, {}, nr, g);
427 then
428 g;
429
430 case (SCode.IMPORT(), g)
431 algorithm
432 76638 g := mkImportNode(inElement, inParentRef, inKind, g);
433 then
434 g;
435
436 case (SCode.DEFINEUNIT(), g)
437 algorithm
438 ✗ g := mkUnitsNode(inElement, inParentRef, inKind, g);
439 then
440 g;
441
442 end match;
443 end mkElementNode;
444
445 public function mkUnitsNode
446 "@author: adrpo
447 create FNode.duNodeName if it doesn't
448 exist and add the given element to it"
449 input SCode.Element inElement;
450 input Ref inParentRef;
451 input Kind inKind;
452 input Graph inGraph;
453 output Graph outGraph;
454 algorithm
455 outGraph := matchcontinue inGraph
456 local
457 Graph g;
458 Node n;
459 Ref r;
460
461 // if is there add the unit to it
462 case g
463 algorithm
464 ✗ r := FNode.child(inParentRef, FNode.duNodeName);
465 ✗ FNode.addDefinedUnitToRef(r, inElement);
466 then
467 g;
468
469 // if not there create it
470 case g
471 algorithm
472 ✗ (g, n) := FGraph.node(g, FNode.duNodeName, {inParentRef}, FCore.DU({inElement}));
473 ✗ r := FNode.toRef(n);
474 ✗ FNode.addChildRef(inParentRef, FNode.duNodeName, r);
475 then
476 g;
477 end matchcontinue;
478 end mkUnitsNode;
479
480 public function mkImportNode
481 "@author: adrpo
482 create FNode.imNodeName if it doesn't
483 exist and add the given element to it"
484 input SCode.Element inElement;
485 input Ref inParentRef;
486 input Kind inKind;
487 input Graph inGraph;
488 output Graph outGraph;
489 algorithm
490 outGraph := matchcontinue inGraph
491 local
492 Graph g;
493 Node n;
494 Ref r;
495
496 // if is there add the import to it
497 case g
498 algorithm
499 76638 r := FNode.child(inParentRef, FNode.imNodeName);
500 61357 FNode.addImportToRef(r, inElement);
501 then
502 g;
503
504 // if not there create it
505 case g
506 algorithm
507 15281 (g, n) := FGraph.node(g, FNode.imNodeName, {inParentRef}, FCore.IM(FCore.emptyImportTable));
508 15281 r := FNode.toRef(n);
509 15281 FNode.addChildRef(inParentRef, FNode.imNodeName, r);
510 15281 FNode.addImportToRef(r, inElement);
511 then
512 g;
513
514 end matchcontinue;
515 end mkImportNode;
516
517 public function mkDimsNode
518 input Name inName "name to use for the array dims node: $dims (FNode.dimsNodeName) or $tydims (FNode.tydimsNodeName)";
519 input Option<Absyn.ArrayDim> inArrayDims;
520 input Ref inParentRef;
521 input Kind inKind;
522 input Graph inGraph;
523 output Graph outGraph;
524 algorithm
525 outGraph := match(inArrayDims, inGraph)
526 local
527 Node n;
528 Ref nr;
529 Absyn.ArrayDim a;
530 Graph g;
531
532 case (NONE(), g) then g;
533 case (SOME({}), g) then g;
534
535 // some array dims
536 case (SOME(a as _::_), g)
537 algorithm
538 ✗ (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.DIMS(inName, a));
539 ✗ nr := FNode.toRef(n);
540 ✗ FNode.addChildRef(inParentRef, inName, nr);
541 ✗ g := mkDimsNode_helper(0, a, nr, inKind, g);
542 then
543 g;
544
545 end match;
546 end mkDimsNode;
547
548 public function mkDimsNode_helper
549 input Integer inStartWith;
550 input Absyn.ArrayDim inArrayDims;
551 input Ref inParentRef;
552 input Kind inKind;
553 input Graph inGraph;
554 output Graph outGraph;
555 algorithm
556 outGraph := match(inStartWith, inArrayDims, inGraph)
557 local
558 Name name;
559 Absyn.ArrayDim rest;
560 Integer i;
561 Absyn.Exp e;
562 Graph g;
563
564 // we're done
565 case (_, {}, g) then g;
566
567 // nosub, saved as Absyn.END
568 case (i, Absyn.NOSUB()::rest, g)
569 algorithm
570 ✗ name := intString(i);
571 ✗ g := mkExpressionNode(name, Absyn.END(), inParentRef, inKind, g);
572 ✗ g := mkDimsNode_helper(i + 1, rest, inParentRef, inKind, g);
573 then
574 g;
575
576 // subscript, saved as exp
577 case (i, Absyn.SUBSCRIPT(e)::rest, g)
578 algorithm
579 ✗ name := intString(i);
580 ✗ g := mkExpressionNode(name, e, inParentRef, inKind, g);
581 ✗ g := mkDimsNode_helper(i + 1, rest, inParentRef, inKind, g);
582 then
583 g;
584
585 end match;
586 end mkDimsNode_helper;
587
588 public function mkCompNode
589 "Extends the graph with a component"
590 input SCode.Element inComp;
591 input Ref inParentRef;
592 input Kind inKind;
593 input Graph inGraph;
594 output Graph outGraph;
595 protected
596 String name;
597 Graph g;
598 Node n;
599 Ref nr;
600 SCode.Mod m;
601 Option<Absyn.Exp> cnd;
602 Absyn.ArrayDim ad;
603 Absyn.TypeSpec ts;
604 Data nd;
605 DAE.Var i;
606 algorithm
607
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1194991 times.
1194991 SCode.COMPONENT(name = name, attributes = SCode.ATTR(arrayDims = ad), typeSpec = ts, modifications = m, condition = cnd) := inComp;
608 1194991 (nd, i) := FNode.element2Data(inComp, inKind);
609 1194991 (g, n) := FGraph.node(inGraph, name, {inParentRef}, nd);
610 1194991 nr := FNode.toRef(n);
611 1194991 FNode.addChildRef(inParentRef, name, nr);
612 // add instance node
613 1194991 g := mkInstNode(i, nr, g);
614 // add ref node
615 1194991 g := mkRefNode(FNode.refNodeName, {}, nr, g);
616 outGraph := g;
617 end mkCompNode;
618
619 public function mkInstNode
620 "Extends the graph with an inst node"
621 input DAE.Var inVar;
622 input Ref inParentRef;
623 input Graph inGraph;
624 output Graph outGraph;
625 protected
626 Ref nr;
627 Node n;
628 Graph g;
629 algorithm
630 1194991 (g, n) := FGraph.node(inGraph, FNode.itNodeName, {inParentRef}, FCore.IT(inVar));
631 1194991 nr := FNode.toRef(n);
632 1194991 FNode.addChildRef(inParentRef, FNode.itNodeName, nr);
633 outGraph := g;
634 end mkInstNode;
635
636 public function mkConditionNode
637 input Option<Absyn.Exp> inCondition;
638 input Ref inParentRef;
639 input Kind inKind;
640 input Graph inGraph;
641 output Graph outGraph;
642 algorithm
643 outGraph := match(inCondition, inGraph)
644 local
645 Absyn.Exp e;
646 Graph g;
647
648 // no binding
649 case (NONE(), g) then g;
650
651 // some condition
652 case (SOME(e), g)
653 algorithm
654 ✗ g := mkExpressionNode(FNode.cndNodeName, e, inParentRef, inKind, g);
655 then
656 g;
657
658 end match;
659 end mkConditionNode;
660
661 public function mkExpressionNode
662 input Name inName;
663 input Absyn.Exp inExp;
664 input Ref inParentRef;
665 input Kind inKind;
666 input Graph inGraph;
667 output Graph outGraph;
668 algorithm
669 outGraph := match(inExp, inGraph)
670 local
671 Node n;
672 Ref nr;
673 Absyn.Exp e;
674 Graph g;
675
676 case (e, g)
677 algorithm
678 ✗ (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.EXP(inName, e));
679 ✗ nr := FNode.toRef(n);
680 ✗ FNode.addChildRef(inParentRef, inName, nr);
681 ✗ g := analyseExp(e, nr, inKind, g);
682 then
683 g;
684
685 end match;
686 end mkExpressionNode;
687
688 public function mkCrefsNodes
689 input list<Absyn.ComponentRef> inCrefs;
690 input Ref inParentRef;
691 input Kind inKind;
692 input Graph inGraph;
693 output Graph outGraph;
694 algorithm
695 outGraph := match(inCrefs, inGraph)
696 local
697 list<Absyn.ComponentRef> rest;
698 Graph g;
699 Absyn.ComponentRef cr;
700
701 // we're done
702 case ({}, g) then g;
703
704 // cref::rest
705 case (cr::rest, g)
706 algorithm
707 ✗ g := mkCrefNode(cr, inParentRef, inKind, g);
708 ✗ g := mkCrefsNodes(rest, inParentRef, inKind, g);
709 then
710 g;
711
712 end match;
713 end mkCrefsNodes;
714
715 public function mkCrefNode
716 input Absyn.ComponentRef inCref;
717 input Ref inParentRef;
718 input Kind inKind;
719 input Graph inGraph;
720 output Graph outGraph;
721 algorithm
722 outGraph := match inGraph
723 local
724 Node n;
725 Ref nr;
726 Graph g;
727 Name name;
728
729 case g
730 algorithm
731 ✗ name := Dump.printComponentRefStr(inCref);
732 ✗ (g, n) := FGraph.node(g, name, {inParentRef}, FCore.CR(inCref));
733 ✗ nr := FNode.toRef(n);
734 ✗ FNode.addChildRef(inParentRef, name, nr);
735 ✗ g := mkDimsNode(FNode.subsNodeName, List.mkOption(AbsynUtil.getSubsFromCref(inCref, true, true)), nr, inKind, g);
736 then
737 g;
738
739 end match;
740 end mkCrefNode;
741
742 public function mkTypeNode
743 input list<DAE.Type> inTypes "the types to add";
744 input Ref inParentRef;
745 input Name inName "name to search for";
746 input Graph inGraph;
747 output Graph outGraph;
748 algorithm
749 outGraph := matchcontinue inGraph
750 local
751 Ref nr, pr;
752 Option<Name> name;
753 Node n;
754 Graph g;
755
756 // type node present, update
757 case _
758 algorithm
759 // search in the parent node for a child with name FNode.tyNodeName
760 82270 pr := FNode.child(inParentRef, FNode.tyNodeName);
761 // search for the given name in FNode.tyNodeName
762 61280 nr := FNode.child(pr, inName);
763 45272 FNode.addTypesToRef(nr, inTypes);
764 then
765 inGraph;
766
767 // type node not present, add
768 case g
769 algorithm
770 // search in the parent node for a child with name FNode.tyNodeName
771
2/2
✓ Branch 0 taken 36998 times.
✓ Branch 1 taken 20990 times.
57988 failure(FNode.child(inParentRef, FNode.tyNodeName));
772 // add it
773 20990 (g, n) := FGraph.node(g, FNode.tyNodeName, {inParentRef}, FCore.ND(NONE()));
774 20990 pr := FNode.toRef(n);
775 20990 FNode.addChildRef(inParentRef, FNode.tyNodeName, pr);
776 20990 (g, n) := FGraph.node(g, inName, {pr}, FCore.FT(inTypes));
777 20990 nr := FNode.toRef(n);
778 20990 FNode.addChildRef(pr, inName, nr);
779 then
780 g;
781
782 // type node present, but inName not present in it
783 case g
784 algorithm
785 // search in the parent node for a child with name FNode.tyNodeName
786 16008 pr := FNode.child(inParentRef, FNode.tyNodeName);
787
2/2
✓ Branch 0 taken 16008 times.
✓ Branch 1 taken 16008 times.
32016 failure(FNode.child(pr, inName));
788 // add it
789 16008 (g, n) := FGraph.node(g, inName, {pr}, FCore.FT(inTypes));
790 16008 nr := FNode.toRef(n);
791 16008 FNode.addChildRef(pr, inName, nr);
792 then
793 g;
794
795 else
796 algorithm
797 ✗ pr := FGraph.top(inGraph);
798 ✗ print("FGraphBuildEnv.mkTypeNode: Error making type node: " + inName +
799 " in parent: " + FNode.name(FNode.fromRef(pr)) + "\n");
800 then
801 inGraph;
802
803 end matchcontinue;
804 end mkTypeNode;
805
806 public function mkEqNode
807 "equation node"
808 input Name inName;
809 input list<SCode.Equation> inEqs;
810 input Ref inParentRef;
811 input Kind inKind;
812 input Graph inGraph;
813 output Graph outGraph;
814 algorithm
815 outGraph := match(inEqs, inGraph)
816 local
817 Graph g;
818 Node n;
819 Ref nr;
820
821 case ({}, g) then g;
822
823 case (_, g)
824 algorithm
825 ✗ (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.EQ(inName, inEqs));
826 ✗ nr := FNode.toRef(n);
827 ✗ FNode.addChildRef(inParentRef, inName, nr);
828 ✗ g := List.fold2(inEqs, analyseEquation, nr, inKind, g);
829 then
830 g;
831
832 end match;
833 end mkEqNode;
834
835 public function mkAlNode
836 "algorithm node"
837 input Name inName;
838 input list<SCode.AlgorithmSection> inAlgs;
839 input Ref inParentRef;
840 input Kind inKind;
841 input Graph inGraph;
842 output Graph outGraph;
843 algorithm
844 outGraph := match(inAlgs, inGraph)
845 local
846 Graph g;
847 Node n;
848 Ref nr;
849
850 case ({}, g) then g;
851
852 case (_, g)
853 algorithm
854 ✗ (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.AL(inName, inAlgs));
855 ✗ nr := FNode.toRef(n);
856 ✗ FNode.addChildRef(inParentRef, inName, nr);
857 ✗ g := List.fold2(inAlgs, analyseAlgorithm, nr, inKind, g);
858 then
859 g;
860
861 end match;
862 end mkAlNode;
863
864 public function mkOptNode
865 "optimization node"
866 input Name inName;
867 input list<SCode.ConstraintSection> inConstraintLst;
868 input list<Absyn.NamedArg> inClsAttrs;
869 input Ref inParentRef;
870 input Kind inKind;
871 input Graph inGraph;
872 output Graph outGraph;
873 algorithm
874 outGraph := match(inConstraintLst, inClsAttrs, inGraph)
875 local
876 Graph g;
877 Node n;
878 Ref nr;
879
880 case ({}, {}, g) then g;
881
882 case (_, _, g)
883 algorithm
884 ✗ (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.OT(inConstraintLst, inClsAttrs));
885 ✗ nr := FNode.toRef(n);
886 ✗ FNode.addChildRef(inParentRef, inName, nr);
887 then
888 g;
889
890 end match;
891 end mkOptNode;
892
893 public function mkExternalNode
894 "optimization node"
895 input Name inName;
896 input Option<SCode.ExternalDecl> inExternalDeclOpt;
897 input Ref inParentRef;
898 input Kind inKind;
899 input Graph inGraph;
900 output Graph outGraph;
901 algorithm
902 outGraph := match(inExternalDeclOpt, inGraph)
903 local
904 Graph g;
905 Node n;
906 Ref nr;
907 SCode.ExternalDecl ed;
908 Option<Absyn.ComponentRef> ocr;
909 Option<Absyn.Exp> oae;
910 list<Absyn.Exp> exps;
911
912 case (NONE(), g) then g;
913
914 case (SOME(ed as SCode.EXTERNALDECL(output_ = ocr, args = exps)), g)
915 algorithm
916 ✗ (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.ED(ed));
917 ✗ nr := FNode.toRef(n);
918 ✗ FNode.addChildRef(inParentRef, inName, nr);
919 ✗ oae := Util.applyOption(ocr, AbsynUtil.crefExp);
920 ✗ g := mkCrefsFromExps(List.consOption(oae, exps), nr, inKind, g);
921 then
922 g;
923
924 end match;
925 end mkExternalNode;
926
927 public function mkCrefsFromExps
928 input list<Absyn.Exp> inExps;
929 input Ref inParentRef;
930 input Kind inKind;
931 input Graph inGraph;
932 output Graph outGraph;
933 algorithm
934 outGraph := match(inExps, inGraph)
935 local
936 Absyn.Exp e;
937 list<Absyn.Exp> rest;
938 list<Absyn.ComponentRef> crefs;
939 Graph g;
940
941 case ({}, g) then g;
942
943 case (e::rest, g)
944 algorithm
945 ✗ crefs := AbsynUtil.getCrefFromExp(e, true, true);
946 ✗ g := mkCrefsNodes(crefs, inParentRef, inKind, g);
947 ✗ g := mkCrefsFromExps(rest, inParentRef, inKind, g);
948 then
949 g;
950
951 end match;
952 end mkCrefsFromExps;
953
954 protected function analyseExp
955 "Recursively analyses an expression."
956 input Absyn.Exp inExp;
957 input Ref inRef;
958 input Kind inKind;
959 input Graph inGraph;
960 output Graph outGraph;
961 algorithm
962 ✗ (_, outGraph) := AbsynUtil.traverseExpBidir(inExp,
963 function analyseExpTraverserEnter(ref = inRef, kind = inKind), analyseExpTraverserExit, inGraph);
964 end analyseExp;
965
966 protected function analyseOptExp
967 "Recursively analyses an optional expression."
968 input Option<Absyn.Exp> inExp;
969 input Ref inRef;
970 input Kind inKind;
971 input Graph inGraph;
972 output Graph outGraph;
973 algorithm
974 outGraph := match(inExp, inGraph)
975 local
976 Absyn.Exp exp;
977 Graph g;
978
979 case (NONE(), g) then g;
980
981 case (SOME(exp), g)
982 algorithm
983 ✗ g := analyseExp(exp, inRef, inKind, g);
984 then
985 g;
986
987 end match;
988 end analyseOptExp;
989
990 protected function analyseExpTraverserEnter
991 "Traversal enter function for use in analyseExp."
992 input output Absyn.Exp inExp;
993 input Ref ref;
994 input Kind kind;
995 input output Graph graph;
996 algorithm
997 graph := match inExp
998 local
999 Absyn.ComponentRef cref;
1000 Absyn.ForIterators iters;
1001
1002 case Absyn.CREF(componentRef = cref)
1003 ✗ then analyseCref(cref, ref, kind, graph);
1004
1005 case Absyn.CALL(functionArgs = Absyn.FOR_ITER_FARG(iterators = iters))
1006 ✗ then addIterators(iters, ref, kind, graph);
1007
1008 case Absyn.CALL(function_ = cref)
1009 ✗ then analyseCref(cref, ref, kind, graph);
1010
1011 case Absyn.PARTEVALFUNCTION(function_ = cref)
1012 ✗ then analyseCref(cref, ref, kind, graph);
1013
1014 case Absyn.MATCHEXP()
1015 ✗ then addMatchScope(inExp, ref, kind, graph);
1016
1017 else graph;
1018 end match;
1019 end analyseExpTraverserEnter;
1020
1021 protected function analyseCref
1022 "Analyses a component reference."
1023 input Absyn.ComponentRef inCref;
1024 input Ref inParentRef;
1025 input Kind inKind;
1026 input Graph inGraph;
1027 output Graph outGraph;
1028 algorithm
1029 outGraph := match(inCref, inGraph)
1030 local
1031 Graph g;
1032
1033 case (Absyn.WILD(), g) then g;
1034
1035 case (_, g)
1036 algorithm
1037 ✗ g := mkCrefNode(inCref, inParentRef, inKind, g);
1038 then
1039 g;
1040
1041 end match;
1042 end analyseCref;
1043
1044 protected function analyseExpTraverserExit
1045 "Traversal exit function for use in analyseExp."
1046 input output Absyn.Exp exp;
1047 input output Graph graph;
1048 algorithm
1049 // nothing to do here!
1050 end analyseExpTraverserExit;
1051
1052 protected function analyseEquation
1053 "Analyses an equation."
1054 input SCode.Equation inEquation;
1055 input Ref inParentRef;
1056 input Kind inKind;
1057 input Graph inGraph;
1058 output Graph outGraph;
1059 algorithm
1060 ✗ (_, outGraph) := SCodeUtil.mapFoldEquations(inEquation,
1061 function analyseEquationTraverser(ref = inParentRef, kind = inKind), inGraph);
1062 end analyseEquation;
1063
1064 protected function analyseEquationTraverser
1065 "Traversal function for use in analyseEquation."
1066 input output SCode.Equation eq;
1067 input Ref ref;
1068 input Kind kind;
1069 input output Graph graph;
1070 algorithm
1071 (eq, graph) := match eq
1072 local
1073 SCode.Ident iter_name;
1074 Absyn.ComponentRef cref1;
1075
1076 case SCode.EQ_FOR(index = iter_name)
1077 algorithm
1078 ✗ graph := addIterators({Absyn.ITERATOR(iter_name, NONE(), NONE())}, ref, kind, graph);
1079 ✗ then
1080 SCodeUtil.mapFoldEquationExps(eq, function traverseExp(ref = ref, kind = kind), graph);
1081
1082 case SCode.EQ_REINIT(cref = Absyn.CREF(componentRef = cref1))
1083 algorithm
1084 ✗ graph := analyseCref(cref1, ref, kind, graph);
1085 ✗ then
1086 SCodeUtil.mapFoldEquationExps(eq, function traverseExp(ref = ref, kind = kind), graph);
1087
1088 else
1089 algorithm
1090 ✗ SCodeUtil.getEquationInfo(eq);
1091 ✗ then
1092 SCodeUtil.mapFoldEquationExps(eq, function traverseExp(ref = ref, kind = kind), graph);
1093
1094 end match;
1095 end analyseEquationTraverser;
1096
1097 protected function traverseExp
1098 "Traversal function used by analyseEquationTraverser and
1099 analyseStatementTraverser."
1100 input output Absyn.Exp exp;
1101 input output Graph graph;
1102 input Ref ref;
1103 input Kind kind;
1104 algorithm
1105 ✗ (exp, graph) := AbsynUtil.traverseExpBidir(exp,
1106 function analyseExpTraverserEnter(ref = ref, kind = kind), analyseExpTraverserExit, graph);
1107 end traverseExp;
1108
1109 protected function analyseAlgorithm
1110 "Analyses an algorithm."
1111 input SCode.AlgorithmSection inAlgorithm;
1112 input Ref inParentRef;
1113 input Kind inKind;
1114 input Graph inGraph;
1115 output Graph outGraph;
1116 protected
1117 list<SCode.Statement> stmts;
1118 algorithm
1119 ✗ SCode.ALGORITHM(stmts) := inAlgorithm;
1120 ✗ outGraph := List.fold2(stmts, analyseStatement, inParentRef, inKind, inGraph);
1121 end analyseAlgorithm;
1122
1123 protected function analyseStatement
1124 "Analyses a statement in an algorithm."
1125 input SCode.Statement inStatement;
1126 input Ref inParentRef;
1127 input Kind inKind;
1128 input Graph inGraph;
1129 output Graph outGraph;
1130 algorithm
1131 ✗ (_, outGraph) := SCodeUtil.mapFoldStatements(inStatement,
1132 function analyseStatementTraverser(ref = inParentRef, kind = inKind), inGraph);
1133 end analyseStatement;
1134
1135 protected function analyseStatementTraverser
1136 "Traversal function used by analyseStatement."
1137 input output SCode.Statement stmt;
1138 input Ref ref;
1139 input Kind kind;
1140 input output Graph graph;
1141 algorithm
1142 (stmt, graph) := match stmt
1143 local
1144
1145 case SCode.ALG_FOR()
1146 algorithm
1147 ✗ graph := addIterators({Absyn.ITERATOR(stmt.index, NONE(), NONE())}, ref, kind, graph);
1148 ✗ (_, graph) := SCodeUtil.mapFoldStatementExps(stmt,
1149 function traverseExp(ref = ref, kind = kind), graph);
1150 ✗ then
1151 (stmt, graph);
1152
1153 case SCode.ALG_PARFOR()
1154 algorithm
1155 ✗ graph := addIterators({Absyn.ITERATOR(stmt.index, NONE(), NONE())}, ref, kind, graph);
1156 ✗ (_, graph) := SCodeUtil.mapFoldStatementExps(stmt,
1157 function traverseExp(ref = ref, kind = kind), graph);
1158 ✗ then
1159 (stmt, graph);
1160
1161 else
1162 algorithm
1163 ✗ SCodeUtil.getStatementInfo(stmt);
1164 ✗ (_, graph) := SCodeUtil.mapFoldStatementExps(stmt,
1165 function traverseExp(ref = ref, kind = kind), graph);
1166 ✗ then
1167 (stmt, graph);
1168
1169 end match;
1170 end analyseStatementTraverser;
1171
1172 public function addIterators
1173 "adds iterators nodes"
1174 input Absyn.ForIterators inIterators;
1175 input Ref inParentRef;
1176 input Kind inKind;
1177 input Graph inGraph;
1178 output Graph outGraph;
1179 algorithm
1180 outGraph := matchcontinue inGraph
1181 local
1182 Graph g;
1183 Node n;
1184 Ref nr;
1185
1186 // FNode.forNodeName already present!
1187 case g
1188 algorithm
1189 ✗ nr := FNode.child(inParentRef, FNode.forNodeName);
1190 ✗ FNode.addIteratorsToRef(nr, inIterators);
1191 ✗ g := addIterators_helper(inIterators, nr, inKind, g);
1192 then
1193 g;
1194
1195 // FNode.forNodeName not present, add it
1196 case g
1197 algorithm
1198 ✗ (g, n) := FGraph.node(g, FNode.forNodeName, {inParentRef}, FCore.FS(inIterators));
1199 ✗ nr := FNode.toRef(n);
1200 ✗ FNode.addChildRef(inParentRef, FNode.forNodeName, nr);
1201 ✗ g := addIterators_helper(inIterators, nr, inKind, g);
1202 then
1203 g;
1204
1205 end matchcontinue;
1206 end addIterators;
1207
1208 public function addIterators_helper
1209 input Absyn.ForIterators inIterators;
1210 input Ref inParentRef;
1211 input Kind inKind;
1212 input Graph inGraph;
1213 output Graph outGraph;
1214 algorithm
1215 outGraph := match(inIterators, inGraph)
1216 local
1217 Node n;
1218 Ref nr;
1219 Name name;
1220 list<Absyn.ForIterator> rest;
1221 Absyn.ForIterator i;
1222 Graph g;
1223
1224 // we're done
1225 case ({}, g) then g;
1226
1227 // iterator::rest
1228 case ((i as Absyn.ITERATOR(name=name))::rest, g)
1229 algorithm
1230 ✗ (g, n) := FGraph.node(g, name, {inParentRef}, FCore.FI(i));
1231 ✗ nr := FNode.toRef(n);
1232 ✗ FNode.addChildRef(inParentRef, name, nr);
1233 ✗ g := addIterators_helper(rest, inParentRef, inKind, g);
1234 then
1235 g;
1236
1237 end match;
1238 end addIterators_helper;
1239
1240 public function addMatchScope
1241 "Extends the node with a match-expression, i.e. opens a new scope and
1242 adds the local declarations in the match to it."
1243 input Absyn.Exp inMatchExp;
1244 input Ref inParentRef;
1245 input Kind inKind;
1246 input Graph inGraph;
1247 output Graph outGraph;
1248 protected
1249 Node n;
1250 Ref nr;
1251 list<Absyn.ElementItem> local_decls;
1252 Graph g;
1253 algorithm
1254 ✗ (g, n) := FGraph.node(inGraph, FNode.matchNodeName, {inParentRef}, FCore.MS(inMatchExp));
1255 ✗ nr := FNode.toRef(n);
1256 ✗ FNode.addChildRef(inParentRef, FNode.matchNodeName, nr);
1257 ✗ Absyn.MATCHEXP(localDecls = local_decls) := inMatchExp;
1258 ✗ outGraph := addMatchScope_helper(local_decls, nr, inKind, g);
1259 end addMatchScope;
1260
1261 public function addMatchScope_helper
1262 input list<Absyn.ElementItem> inElements;
1263 input Ref inParentRef;
1264 input Kind inKind;
1265 input Graph inGraph;
1266 output Graph outGraph;
1267 algorithm
1268 outGraph := match(inElements, inGraph)
1269 local
1270 Absyn.Element element;
1271 list<Absyn.ElementItem> rest;
1272 Graph g;
1273 list<SCode.Element> el;
1274
1275 // we're done
1276 case ({}, g) then g;
1277
1278 // el::rest
1279 case (Absyn.ELEMENTITEM(element = element)::rest, g)
1280 algorithm
1281 // Translate the element item to a SCode element.
1282 ✗ el := AbsynToSCode.translateElement(element, SCode.PROTECTED());
1283 ✗ g := List.fold2(el, mkElementNode, inParentRef, inKind, g);
1284 ✗ g := addMatchScope_helper(rest, inParentRef, inKind, g);
1285 then
1286 g;
1287
1288 // el::rest
1289 case (_::rest, g)
1290 algorithm
1291 ✗ g := addMatchScope_helper(rest, inParentRef, inKind, g);
1292 then
1293 g;
1294
1295 end match;
1296 end addMatchScope_helper;
1297
1298 public function mkRefNode
1299 input Name inName;
1300 input Scope inTargetScope;
1301 input Ref inParentRef;
1302 input Graph inGraph;
1303 output Graph outGraph;
1304 algorithm
1305 outGraph := match inGraph
1306 local
1307 Node n;
1308 Ref rn;
1309 Graph g;
1310
1311 case g
1312 algorithm
1313 1194991 (g, n) := FGraph.node(g, inName, {inParentRef}, FCore.REF(inTargetScope));
1314 // make a ref
1315 1194991 rn := FNode.toRef(n);
1316 // add the ref node
1317 1194991 FNode.addChildRef(inParentRef, inName, rn);
1318 then
1319 g;
1320
1321 end match;
1322 end mkRefNode;
1323
1324 annotation(__OpenModelica_Interface="frontend");
1325 end FGraphBuildEnv;
1326