Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 197
Functions: -% 0 / 1 / 1
Branches: 0.0% 0 / 0 / 10

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