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 / 119
Functions: -% 0 / 1 / 1
Branches: 0.0% 0 / 0 / 22

OMCompiler/Compiler/Script/BlockCallRewrite.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 BlockCallRewrite
37 " file: BlockCallRewrite.mo
38 package: BlockCallRewrite
39 description: This module implements an extension for properties modelling for calling blocks as functions.
40 It rewrites block calls into block instantiations.
41 "
42
43 public import Absyn;
44
45 protected import Dump;
46
47 public function rewriteBlockCall
48 input Absyn.Program inPg "Model containing block calls";
49 input Absyn.Program inDefs "Block definitions";
50 output Absyn.Program newOut "Standard Modelica output";
51 algorithm
52
53 newOut := match inDefs
54 local
55 Absyn.Program pg2;
56 String res;
57 case _
58 algorithm
59 ✗ pg2 := parseProgram(inPg, inDefs);
60
61 ✗ res := Dump.unparseStr(pg2, false);
62 ✗ print(res);
63
64 then
65 pg2;
66 end match;
67 end rewriteBlockCall;
68
69 protected function parseProgram
70 input Absyn.Program inPg, defs;
71 output Absyn.Program outPg = inPg;
72 algorithm
73 outPg := match outPg
74 case Absyn.PROGRAM()
75 algorithm
76 ✗ outPg.classes := parseClasses(outPg.classes, defs);
77 then outPg;
78 end match;
79 end parseProgram;
80
81 public function parseClasses
82 input list<Absyn.Class> classes;
83 input Absyn.Program defs;
84
85 output list<Absyn.Class> out_classes;
86 algorithm
87 out_classes := match classes
88 local
89 list<Absyn.Class> r_classes, nr_classes;
90 Absyn.Class cls, n_cls;
91 case {} then {};
92 case cls :: r_classes
93 algorithm
94 ✗ nr_classes := parseClasses(r_classes, defs);
95 ✗ n_cls := parseClass(cls, defs);
96 then
97 n_cls :: nr_classes;
98 end match;
99 end parseClasses;
100
101 public function parseClass
102 input Absyn.Class in_class;
103 input Absyn.Program defs;
104
105
106 output Absyn.Class out_class;
107 algorithm
108 out_class := match in_class
109 local
110 Absyn.ClassDef body;
111 case out_class as Absyn.CLASS(body=body)
112 algorithm
113 ✗ out_class.body := parseClassDef(body, defs);
114 then
115 out_class;
116 end match;
117 end parseClass;
118
119 protected function parseClassDef
120 input Absyn.ClassDef in_def;
121 input Absyn.Program defs;
122
123 output Absyn.ClassDef out_def;
124 algorithm
125 out_def := match in_def
126 local
127 list<String> typeVars ;
128 list<Absyn.NamedArg> classAttrs ;
129 list<Absyn.ClassPart> classParts, nclsp;
130 list<Absyn.Annotation> ann ;
131 Option<String> comment;
132 list<Absyn.EquationItem> eqs;
133 list<Absyn.ElementItem> elems;
134 case Absyn.PARTS(typeVars, classAttrs, classParts, ann, comment)
135 algorithm
136 ✗ (nclsp, eqs, elems) := parseClassParts(classParts, defs, {}, {}, 0);
137 ✗ then
138 Absyn.PARTS(typeVars, classAttrs, Absyn.PUBLIC(elems)::Absyn.EQUATIONS(eqs)::nclsp, ann, comment);
139 end match;
140 end parseClassDef;
141
142 protected function parseClassParts
143 input list<Absyn.ClassPart> classes;
144 input Absyn.Program defs;
145 input list<Absyn.EquationItem> oldEqs;
146 input list<Absyn.ElementItem> oldElems;
147 input Integer instNo;
148
149 output list<Absyn.ClassPart> out_classes;
150 output list<Absyn.EquationItem> eqs;
151 output list<Absyn.ElementItem> elems;
152 output Integer newInstNo;
153 algorithm
154 (out_classes, eqs, elems, newInstNo) := match classes
155 local
156 list<Absyn.ClassPart> r_classes, nr_classes;
157 Absyn.ClassPart cls, n_cls;
158 list<Absyn.EquationItem> eqs1, eqs2;
159 list<Absyn.ElementItem> elems1, elems2;
160 Integer count, count1;
161 case {} then ({}, oldEqs, oldElems, instNo);
162 case cls :: r_classes
163 algorithm
164 ✗ (n_cls,eqs2, elems2, count1) := parseClassPart(cls, defs, oldEqs, oldElems, instNo);
165 ✗ (nr_classes, eqs1, elems1, count) := parseClassParts(r_classes, defs, eqs2, elems2, count1);
166 //print("classparts" + intString(count) + intString(count1) + "\n");
167 ✗ then
168 (n_cls :: nr_classes, eqs1, elems1, count);
169 end match;
170 end parseClassParts;
171
172 protected function parseClassPart
173 input Absyn.ClassPart in_def;
174 input Absyn.Program defs;
175 input list<Absyn.EquationItem> oldEqs;
176 input list<Absyn.ElementItem> oldElems;
177 input Integer instNo;
178
179 output Absyn.ClassPart out_def;
180 output list<Absyn.EquationItem> reqs;
181 output list<Absyn.ElementItem> relems;
182 output Integer newInstNo;
183 algorithm
184 (out_def, reqs, relems, newInstNo) := match in_def
185 local
186 list<Absyn.ElementItem> elems;
187 list<Absyn.Exp> exps;
188 list<Absyn.EquationItem> eqs, neqs;
189 list<Absyn.AlgorithmItem> algs;
190 Absyn.ExternalDecl externalDecl;
191 Option<Absyn.Annotation> annotation_ ;
192 list<Absyn.EquationItem> eqs1;
193 list<Absyn.ElementItem> elems1;
194 Integer count;
195 case Absyn.PUBLIC(elems) //TODO
196 ✗ then
197 (Absyn.PUBLIC(elems), {}, {}, instNo);
198 case Absyn.PROTECTED(elems) //TODO
199 ✗ then
200 (Absyn.PROTECTED(elems), {}, {}, instNo); //TODO
201 case Absyn.CONSTRAINTS(exps)
202 ✗ then
203 (Absyn.CONSTRAINTS(exps), {}, {}, instNo);
204 case Absyn.EQUATIONS(eqs)
205 algorithm
206 ✗ (neqs, eqs1, elems1, count) := parseEquations(eqs, defs, oldEqs, oldElems, instNo);
207 //print("equations" + intString(count) + "\n");
208 ✗ then
209 (Absyn.EQUATIONS(neqs), eqs1, elems1, count);
210 case Absyn.INITIALEQUATIONS(eqs)
211 algorithm
212 ✗ (neqs, eqs1, elems1, count) := parseEquations(eqs, defs, oldEqs, oldElems, instNo);
213 //print("equations" + intString(count) + "\n");
214 ✗ then
215 (Absyn.INITIALEQUATIONS(neqs), eqs1, elems1, count);
216 case Absyn.ALGORITHMS(algs) //TODO
217 ✗ then
218 (Absyn.ALGORITHMS(algs), {}, {}, instNo);
219 case Absyn.INITIALALGORITHMS(algs) //TODO
220 ✗ then
221 (Absyn.INITIALALGORITHMS(algs), {}, {}, instNo);
222 case Absyn.EXTERNAL(externalDecl, annotation_)
223 ✗ then
224 (Absyn.EXTERNAL(externalDecl, annotation_), {}, {}, instNo);
225 end match;
226 end parseClassPart;
227
228 protected function parseEquations
229 input list<Absyn.EquationItem> classes;
230 input Absyn.Program defs;
231 input list<Absyn.EquationItem> oldEqs;
232 input list<Absyn.ElementItem> oldElems;
233 input Integer instNo;
234
235 output list<Absyn.EquationItem> out_classes;
236 output list<Absyn.EquationItem> eqs;
237 output list<Absyn.ElementItem> elems;
238 output Integer newInstNo;
239 algorithm
240 (out_classes, eqs, elems, newInstNo) := match classes
241 local
242 Absyn.Equation eq, neq;
243 Option<Absyn.Comment> cmt;
244 String comment;
245 SourceInfo info ;
246 list<Absyn.EquationItem> r_classes, nr_classes;
247 list<Absyn.EquationItem> eqs1, eqs2;
248 list<Absyn.ElementItem> elems1, elems2;
249 Integer count, count1;
250 case {} then ({}, oldEqs, oldElems, instNo);
251 case Absyn.EQUATIONITEM(eq, cmt, info) :: r_classes
252 algorithm
253 //print("in equation item\n");
254 ✗ (neq, eqs2, elems2, count1) := parseEquation(eq, defs, oldEqs, oldElems, instNo);
255 ✗ (nr_classes, eqs1, elems1, count) := parseEquations(r_classes, defs, eqs2, elems2, count1);
256
257 ✗ then
258 (Absyn.EQUATIONITEM(neq, cmt, info) :: nr_classes, eqs1, elems1, count);
259 case Absyn.EQUATIONITEMCOMMENT(comment) :: r_classes
260 algorithm
261 ✗ (nr_classes, eqs1, elems1, count) := parseEquations(r_classes, defs, oldEqs, oldElems, instNo);
262 ✗ then
263 (Absyn.EQUATIONITEMCOMMENT(comment) :: nr_classes, eqs1, elems1, count);
264 end match;
265 end parseEquations;
266
267 protected function parseEquation
268 input Absyn.Equation in_eq;
269 input Absyn.Program defs;
270 input list<Absyn.EquationItem> oldEqs;
271 input list<Absyn.ElementItem> oldElems;
272 input Integer instNo;
273
274 output Absyn.Equation out_eq;
275 output list<Absyn.EquationItem> eqs;
276 output list<Absyn.ElementItem> elems;
277 output Integer newInstNo;
278 algorithm
279 (out_eq, eqs, elems, newInstNo) := match in_eq
280 local
281 Absyn.Exp exp1, exp2, nexp1, nexp2;
282 Absyn.EquationItem eqi;
283 list<Absyn.EquationItem> leq1, leq2, nleq1, nleq2;
284 list<tuple<Absyn.Exp, list<Absyn.EquationItem>>> tup1;
285 Absyn.ComponentRef cr1, cr2, domain;
286 Absyn.ForIterators fi;
287 Absyn.FunctionArgs farg;
288 list<Absyn.EquationItem> eqs1, eqs2, eqs3;
289 list<Absyn.ElementItem> elems1, elems2, elems3;
290 Integer count, count1, count2;
291 case Absyn.EQ_IF(exp1, leq1, tup1, leq2)
292 algorithm
293 // print("IF STATEMENT\n");
294 ✗ (nexp1, eqs1, elems1, count) := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
295 ✗ (nleq1, eqs2, elems2, count1) := parseEquations(leq1, defs, eqs1, elems1, count);
296 ✗ (nleq2, eqs3, elems3, count2) := parseEquations(leq2, defs, eqs2, elems2, count1);
297 //print("IF STATEMENT2\n");
298 //ntup1 = parseEquationTuple(tup1); TODO
299 ✗ then
300 (Absyn.EQ_IF(nexp1, nleq1, tup1, nleq2), eqs3, elems3, count2);
301 case Absyn.EQ_EQUALS(exp1, exp2)
302 algorithm
303 // print("EQUALS STATEMENT\n");
304 ✗ (nexp1, eqs1, elems1, count) := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
305 ✗ (nexp2, eqs2, elems2, count1) := parseExpression(exp2, defs, eqs1, elems1, count);
306 // print("EQ_Equals count1 " + intString(count1) + "\n");
307 ✗ then
308 (Absyn.EQ_EQUALS(nexp1, nexp2), eqs2, elems2, count1);
309
310 case Absyn.EQ_PDE(exp1, exp2, domain)
311 algorithm
312 // print("EQUALS STATEMENT\n");
313 ✗ (nexp1, eqs1, elems1, count) := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
314 ✗ (nexp2, eqs2, elems2, count1) := parseExpression(exp2, defs, eqs1, elems1, count);
315 // print("EQ_Equals count1 " + intString(count1) + "\n");
316 ✗ then
317 (Absyn.EQ_PDE(nexp1, nexp2, domain), eqs2, elems2, count1);
318
319 case Absyn.EQ_CONNECT(cr1, cr2)
320 ✗ then
321 (Absyn.EQ_CONNECT(cr1, cr2), oldEqs, oldElems, instNo);
322 case Absyn.EQ_FOR(fi, leq1)
323 algorithm
324 ✗ (nleq1, eqs2, elems2, count) := parseEquations(leq1, defs, oldEqs, oldElems, instNo);
325 ✗ then
326 (Absyn.EQ_FOR(fi, nleq1), eqs2, elems2, count);
327 case Absyn.EQ_WHEN_E(exp1, leq1, tup1)
328 algorithm
329 ✗ nexp1 := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
330 ✗ nleq1 := parseEquations(leq1, defs, oldEqs, oldElems, instNo);
331 //ntup1 = parseEquationTuple(tup1); TODO
332 ✗ then
333 (Absyn.EQ_WHEN_E(nexp1, nleq1, tup1), oldEqs, oldElems, instNo);
334 case Absyn.EQ_NORETCALL(cr1, farg)
335 ✗ then
336 (Absyn.EQ_NORETCALL(cr1, farg), oldEqs, oldElems, instNo);
337 case Absyn.EQ_FAILURE(eqi)
338 algorithm
339 //neqi = parseEquation(eqi);
340 ✗ then
341 (Absyn.EQ_FAILURE(eqi), oldEqs, oldElems, instNo);
342 end match;
343 end parseEquation;
344
345
346 protected function parseExpression
347 input Absyn.Exp in_eq;
348 input Absyn.Program defs;
349 input list<Absyn.EquationItem> oldEqs;
350 input list<Absyn.ElementItem> oldElems;
351 input Integer instNo;
352
353 output Absyn.Exp out_eq;
354 output list<Absyn.EquationItem> eqs;
355 output list<Absyn.ElementItem> elems;
356 output Integer newInstNo;
357 algorithm
358 (out_eq, eqs, elems, newInstNo) := match in_eq
359 local
360 Absyn.Exp exp1, exp2, nexp1, nexp2, ife, nife;
361 Absyn.Operator op;
362 list<Absyn.EquationItem> eqs1, eqs2, eqs3, eqs4;
363 list<Absyn.ElementItem> elems1, elems2, elems3, elems4;
364 Integer count, count2, count3, count4;
365 list<tuple<Absyn.Exp, Absyn.Exp>> elif, nelif;
366
367 case Absyn.BINARY(exp1, op, exp2)
368 algorithm
369 ✗ (nexp1, eqs1, elems1, count) := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
370 ✗ (nexp2, eqs2, elems2, count2) := parseExpression(exp2, defs, eqs1, elems1, count);
371 ✗ then (Absyn.BINARY(nexp1, op, nexp2), eqs2, elems2, count2);
372
373 case Absyn.LBINARY(exp1, op, exp2)
374 algorithm
375 ✗ (nexp1, eqs1, elems1, count) := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
376 ✗ (nexp2, eqs2, elems2, count2) := parseExpression(exp2, defs, eqs1, elems1, count);
377 ✗ then (Absyn.LBINARY(nexp1, op, nexp2), eqs2, elems2, count2);
378
379 case Absyn.UNARY(op, exp2)
380 algorithm
381 ✗ (nexp2, eqs2, elems2, count) := parseExpression(exp2, defs, oldEqs, oldElems, instNo);
382 ✗ then (Absyn.UNARY(op, nexp2), eqs2, elems2, count);
383
384 case Absyn.LUNARY(op, exp2)
385 algorithm
386 ✗ (nexp2, eqs2, elems2, count) := parseExpression(exp2, defs, oldEqs, oldElems, instNo);
387 ✗ then (Absyn.LUNARY(op, nexp2), eqs2, elems2, count);
388
389 case Absyn.IFEXP(ife, exp1, exp2, elif)
390 algorithm
391 ✗ (nife, eqs1, elems1, count) := parseExpression(ife, defs, oldEqs, oldElems, instNo);
392 ✗ (nexp1, eqs2, elems2, count2) := parseExpression(exp1, defs, eqs1, elems1, count);
393 ✗ (nexp2, eqs3, elems3, count3) := parseExpression(exp2, defs, eqs2, elems2, count2);
394 ✗ (nelif, eqs4, elems4, count4) := parseExpressionTuple(elif, defs, eqs3, elems3, count3);
395 ✗ then (Absyn.IFEXP(nife, nexp1, nexp2, nelif), eqs4, elems4, count4);
396
397 case Absyn.CALL()
398 algorithm
399 //print("call" + intString(instNo) + "\n");
400 ✗ (nexp1, eqs1, elems1, count) := parseCall(in_eq, defs, instNo, oldEqs, oldElems);
401 then (nexp1, eqs1, elems1, count);
402 case _
403 ✗ then (in_eq, oldEqs, oldElems, instNo);
404 end match;
405 end parseExpression;
406
407
408 protected function parseExpressionTuple
409 input list<tuple<Absyn.Exp, Absyn.Exp>> tuple_list;
410 input Absyn.Program defs;
411 input list<Absyn.EquationItem> oldEqs;
412 input list<Absyn.ElementItem> oldElems;
413 input Integer instNo;
414
415 output list<tuple<Absyn.Exp, Absyn.Exp>> out_tuple_list;
416 output list<Absyn.EquationItem> eqs;
417 output list<Absyn.ElementItem> elems;
418 output Integer newInstNo;
419 algorithm
420 (out_tuple_list, eqs, elems, newInstNo) := match tuple_list
421 local
422 list<tuple<Absyn.Exp, Absyn.Exp>> r_tuple_list, ntuples;
423 list<Absyn.EquationItem> eqs1, eqs3;
424 list<Absyn.ElementItem> elems1, elems3;
425 Integer count1, count3;
426 Absyn.Exp exp1, exp2, nexp1, nexp2;
427 case {} then ({}, oldEqs, oldElems, instNo);
428 case (exp1, exp2):: r_tuple_list
429 algorithm
430 // print("in equation item\n");
431 ✗ (nexp1, eqs1, elems1, count1) := parseExpression(exp1, defs, oldEqs, oldElems, instNo);
432 ✗ (nexp2,_,_,_) := parseExpression(exp2, defs, eqs1, elems1, count1);
433 ✗ (ntuples, eqs3, elems3, count3) := parseExpressionTuple(r_tuple_list, defs, eqs1, elems1, count1);
434 ✗ then
435 ((nexp1, nexp2) :: ntuples, eqs3, elems3, count3);
436 end match;
437 end parseExpressionTuple;
438
439
440 /**
441 When a function call is found, we check if it is in the block definitions, and if it is we replace it
442 */
443 protected function parseCall
444 input Absyn.Exp in_eq;
445 input Absyn.Program defs;
446 input Integer instNo;
447 input list<Absyn.EquationItem> oldEqs;
448 input list<Absyn.ElementItem> oldElems;
449
450 output Absyn.Exp res_expr;
451 output list<Absyn.EquationItem> newEqs;
452 output list<Absyn.ElementItem> newElems;
453 output Integer newInstNo;
454 algorithm
455 (res_expr, newEqs, newElems, newInstNo) := matchcontinue in_eq
456
457 local
458 Absyn.FunctionArgs fargs;
459 String elName;
460 Absyn.ElementItem elem;
461 Absyn.Ident id;
462 list<Absyn.ElementArg> mods;
463 list<Absyn.EquationItem> eqs;
464 Integer count;
465
466 case Absyn.CALL(function_ = Absyn.CREF_IDENT(id, _), functionArgs = fargs)
467 algorithm
468 //print("Found function call " + id + "\n");
469 ✗ (eqs, mods, true, count) := getDefinition(id, instNo, defs, fargs, oldEqs, {});
470 ✗ elName := "_autogen_" + id + intString(instNo);
471 //print("Parsed function call " + id + "\n");
472 // create element, instert modifiers here
473 ✗ elem := Absyn.ELEMENTITEM(Absyn.ELEMENT(false, NONE(), Absyn.NOT_INNER_OUTER(), Absyn.COMPONENTS(Absyn.ATTR(false, false, Absyn.NON_PARALLEL(), Absyn.VAR(), Absyn.BIDIR(), Absyn.NONFIELD(), {}),
474 Absyn.TPATH(Absyn.IDENT(id), NONE()), {Absyn.COMPONENTITEM(Absyn.COMPONENT(elName,{}, SOME(Absyn.CLASSMOD(mods, Absyn.NOMOD()))), NONE(), NONE())}), Absyn.dummyInfo, NONE()));
475 ✗ then (Absyn.CREF(Absyn.CREF_QUAL(elName, {}, Absyn.CREF_IDENT("out", {}))), eqs, elem::oldElems, count);
476
477 case Absyn.CALL() then (in_eq, oldEqs, {}, instNo);
478 end matchcontinue;
479 end parseCall;
480
481 protected function getDefinition
482 input Absyn.Ident id;
483 input Integer instNo;
484 input Absyn.Program defs;
485 input Absyn.FunctionArgs fargs;
486 input list<Absyn.EquationItem> oldEqs "equations to add to component";
487 input list<Absyn.ElementArg> oldModif ;
488
489 output list<Absyn.EquationItem> newEqs;
490 output list<Absyn.ElementArg> newModif;
491 output Boolean found;
492 output Integer newInstNo;
493 algorithm
494 (newEqs, newModif, found, newInstNo) := match defs
495 case Absyn.PROGRAM()
496 ✗ then
497 parseClassesDefs(id, instNo, defs.classes, fargs, oldEqs, oldModif);
498 end match;
499 end getDefinition;
500
501
502 /**
503 Get the block definitions, go through all packages
504 */
505 protected function parseClassesDefs
506 input Absyn.Ident id;
507 input Integer instNo;
508 input list<Absyn.Class> classes;
509 input Absyn.FunctionArgs fargs;
510 input list<Absyn.EquationItem> oldEqs "equations to add to component";
511 input list<Absyn.ElementArg> oldModif ;
512
513 output list<Absyn.EquationItem> newEqs;
514 output list<Absyn.ElementArg> newModif;
515 output Boolean found;
516 output Integer newInstNo;
517 algorithm
518 (newEqs, newModif, found, newInstNo) := matchcontinue classes
519 local
520 list<Absyn.Class> r_classes;
521 Absyn.Ident id2;
522 list<Absyn.ElementArg> mods;
523 list<Absyn.ClassPart> classParts;
524 list<Absyn.EquationItem> eqs;
525 ✗ case {} then ({}, {}, false, instNo);
526 //R_PACKAGE
527 case Absyn.CLASS(_, _, _, _, Absyn.R_PACKAGE(), Absyn.PARTS(_, _, classParts, _, _), _) :: _
528 algorithm
529 // print("In package: "); print(id2); print("\n");
530
531 ✗ (eqs, mods, true) := lookThroughClasses(id, instNo, fargs, classParts, oldEqs, oldModif);
532 ✗ then
533 (eqs, mods, true, instNo + 1) ;
534 case Absyn.CLASS(id2, _, _, _, Absyn.R_BLOCK(), Absyn.PARTS(_, _, classParts, _, _), _) :: _
535 algorithm
536 //print("TESTING1: "); print(id); print(" "); print(id2); print("\n");
537 ✗ true := (id2 == id);
538 ✗ (eqs, mods) := parseArgs("_autogen_" + id + intString(instNo), classParts, fargs, oldEqs, oldModif);
539 //print("TESTING2: "); print(id); print(" "); print(id2); print("\n");
540 ✗ then
541 (eqs, mods, true, instNo + 1) ;
542 ✗ case _ :: r_classes then parseClassesDefs(id, instNo, r_classes, fargs, oldEqs, oldModif);
543 end matchcontinue;
544 end parseClassesDefs;
545
546 protected function lookThroughClasses
547 input Absyn.Ident id;
548 input Integer instNo;
549 input Absyn.FunctionArgs fargs;
550 input list<Absyn.ClassPart> classes "fields to be initialize";
551 input list<Absyn.EquationItem> oldEqs "equations to add to component";
552 input list<Absyn.ElementArg> oldModif ;
553
554 output list<Absyn.EquationItem> newEqs "equations to add to component";
555 output list<Absyn.ElementArg> newModif "modifiers to add to component";
556 output Boolean found;
557
558 algorithm
559 (newEqs, newModif, found) := matchcontinue classes
560 local
561 list<Absyn.ClassPart> r_classes;
562 list<Absyn.ElementItem> elems1;
563 list<Absyn.EquationItem> eq1;
564 list<Absyn.ElementArg> modif;
565
566 case {}
567 ✗ then (oldEqs, oldModif, false);
568 case Absyn.PUBLIC(elems1) :: _
569 algorithm
570 ✗ (eq1, modif, true) := lookThroughElems(id, instNo, fargs, elems1, oldEqs, oldModif);
571 ✗ then (eq1, modif, true);
572 case _ :: r_classes
573 ✗ then
574 lookThroughClasses(id, instNo, fargs, r_classes, oldEqs, oldModif);
575 end matchcontinue;
576 end lookThroughClasses;
577
578
579 protected function lookThroughElems
580 input Absyn.Ident id;
581 input Integer instNo;
582 input Absyn.FunctionArgs fargs;
583 input list<Absyn.ElementItem> elems "fields to be initialized";
584 input list<Absyn.EquationItem> oldEqs "equations to add to component";
585 input list<Absyn.ElementArg> oldModif "current list of modifiers";
586
587 output list<Absyn.EquationItem> newEqs "equations to add to component";
588 output list<Absyn.ElementArg> newModif "modifiers to add to component";
589 output Boolean found;
590 algorithm
591 (newEqs, newModif, found) := matchcontinue elems
592 local
593 list<Absyn.ElementItem> r_elems;
594 list<Absyn.EquationItem> eqs;
595 list<Absyn.ElementArg> mods;
596 list<Absyn.ClassPart> classParts;
597 Absyn.Ident id2;
598
599 ✗ case {} then (oldEqs, oldModif, false);
600 case Absyn.ELEMENTITEM(Absyn.ELEMENT(_,_,_,
601 Absyn.CLASSDEF(_, Absyn.CLASS(id2, _, _, _, Absyn.R_BLOCK(), Absyn.PARTS(_, _, classParts, _, _), _)),_,_)) :: _
602 algorithm
603 ✗ true := (id2 == id);
604 ✗ (eqs, mods) := parseArgs("_autogen_" + id + intString(instNo), classParts, fargs, oldEqs, oldModif);
605 ✗ then
606 (eqs, mods, true);
607 case Absyn.ELEMENTITEM(Absyn.ELEMENT(_,_,_,
608 Absyn.CLASSDEF(_, Absyn.CLASS(_, _, _, _, Absyn.R_PACKAGE(), Absyn.PARTS(_, _, classParts, _, _), _)),_,_)) :: _
609 algorithm
610 ✗ (eqs, mods, true) := lookThroughClasses(id, instNo, fargs, classParts, oldEqs, oldModif);
611 ✗ then (eqs, mods, true);
612 case _ :: r_elems
613 ✗ then
614 lookThroughElems(id, instNo, fargs, r_elems, oldEqs, oldModif);
615 end matchcontinue;
616 end lookThroughElems;
617
618
619 protected function parseArgs
620 input String elemId;
621 input list<Absyn.ClassPart> classes;
622 input Absyn.FunctionArgs fargs;
623 input list<Absyn.EquationItem> oldEqs "equations to add to component";
624 input list<Absyn.ElementArg> oldModif ;
625
626 output list<Absyn.EquationItem> eqs;
627 output list<Absyn.ElementArg> mods;
628
629 algorithm
630 (eqs, mods) := match fargs
631 local
632 list<Absyn.Exp> args "args" ;
633 list<Absyn.NamedArg> argNames "argNames" ;
634 list<Absyn.EquationItem> eqs1;
635 list<Absyn.ElementArg> mods1;
636
637 case Absyn.FUNCTIONARGS(args, argNames)
638 algorithm
639 ✗ (eqs1, mods1) := matchArgsClass(elemId, args, classes, oldEqs, oldModif);
640 ✗ then
641 matchNamedArgsClass(elemId, argNames, classes, eqs1, mods1);
642 end match;
643 end parseArgs;
644
645 /**
646 uniontype NamedArg "The NamedArg uniontype consist of an Identifier for the argument and an expression
647 giving the value of the argument"
648 record NAMEDARG
649 Ident argName "argName" ;
650 Exp argValue "argValue" ;
651 end NAMEDARG;
652
653 end NamedArg;
654 */
655
656 protected function matchArgsClass
657 input String elemId;
658 input list<Absyn.Exp> args "positional arguments" ;
659 input list<Absyn.ClassPart> classes "fields to be initialize";
660 input list<Absyn.EquationItem> oldEqs "equations to add to component";
661 input list<Absyn.ElementArg> oldModif ;
662
663 output list<Absyn.EquationItem> newEqs "equations to add to component";
664 output list<Absyn.ElementArg> newModif "modifiers to add to component";
665
666 algorithm
667 (newEqs, newModif) := match(classes, args)
668 local
669 list<Absyn.ClassPart> r_classes;
670 list<Absyn.ElementItem> elems1;
671 list<Absyn.EquationItem> eq1;
672 list<Absyn.Exp> r_args;
673 list<Absyn.ElementArg> modif;
674
675 case(_, {}) then (oldEqs, oldModif);
676 case({}, _) then (oldEqs, oldModif);
677 case(Absyn.PUBLIC(elems1) :: r_classes, _)
678 algorithm
679 ✗ (eq1, modif, r_args) := matchArgsElems(elemId, args, elems1, oldEqs, oldModif);
680 ✗ then
681 matchArgsClass(elemId, r_args, r_classes, eq1, modif);
682 case(_ :: r_classes, _)
683 algorithm
684 ✗ then
685 matchArgsClass(elemId, args, r_classes, oldEqs, oldModif);
686 end match;
687 end matchArgsClass;
688
689
690 protected function matchArgsElems
691 input String elemId;
692 input list<Absyn.Exp> args "positional arguments" ;
693 input list<Absyn.ElementItem> elems "fields to be initialized";
694 input list<Absyn.EquationItem> oldEqs "equations to add to component";
695 input list<Absyn.ElementArg> oldModif "current list of modifiers";
696
697 output list<Absyn.EquationItem> newEqs "equations to add to component";
698 output list<Absyn.ElementArg> newModif "modifiers to add to component";
699 output list<Absyn.Exp> newArgs "non initialized positional arguments" ;
700 algorithm
701 (newEqs, newModif, newArgs) := match(args, elems)
702 local
703 list<Absyn.ElementItem> r_elems;
704 list<Absyn.EquationItem> eqs;
705 list<Absyn.ElementArg> modif;
706 list<Absyn.ComponentItem> comps;
707 list<Absyn.Exp> r_args;
708
709 case({}, _) then (oldEqs, oldModif, args);
710 case(_, {}) then (oldEqs, oldModif, args);
711 case(_::r_args, Absyn.ELEMENTITEM(Absyn.ELEMENT(_,_,_,Absyn.COMPONENTS(Absyn.ATTR(_,_,_,Absyn.PARAM(),_,_), _, comps),_,_)) :: r_elems)
712 algorithm
713 ✗ (modif, r_args) := matchParamArgs(args, comps, oldModif);
714 ✗ then
715 matchArgsElems(elemId, r_args, r_elems, oldEqs, modif) ;
716 case(_::r_args, Absyn.ELEMENTITEM(Absyn.ELEMENT(_,_,_,Absyn.COMPONENTS(Absyn.ATTR(_,_,_,Absyn.VAR(),_,_), _, comps),_,_)) :: r_elems)
717 algorithm
718 ✗ (eqs, r_args) := matchVarArgs(elemId, args, comps, oldEqs);
719 ✗ then
720 matchArgsElems(elemId, r_args, r_elems, eqs, oldModif);
721 case(_, _ :: r_elems)
722 ✗ then
723 matchArgsElems(elemId, args, r_elems, oldEqs, oldModif);
724 end match;
725 end matchArgsElems;
726
727
728 protected function matchParamArgs
729 input list<Absyn.Exp> args "positional arguments" ;
730 input list<Absyn.ComponentItem> comps "fields to be initialized";
731 input list<Absyn.ElementArg> oldModif ;
732
733 output list<Absyn.ElementArg> newModif "modifiers to add to component";
734 output list<Absyn.Exp> newArgs "non initialized positional arguments" ;
735 algorithm
736 (newModif, newArgs) := match(comps, args)
737 local
738 list<Absyn.ComponentItem> r_comps;
739 list<Absyn.Exp> r_args;
740 Absyn.Exp arg;
741 Absyn.Ident cName;
742 Absyn.ElementArg modif;
743
744 case({}, _) then (oldModif, args);
745 case(_, {}) then (oldModif, args);
746 case(Absyn.COMPONENTITEM(Absyn.COMPONENT(cName,_,_), _, _) :: r_comps, arg::r_args)
747 algorithm
748 ✗ modif := Absyn.MODIFICATION(false, Absyn.NON_EACH(), Absyn.IDENT(cName), SOME(Absyn.CLASSMOD({}, Absyn.EQMOD(arg, Absyn.dummyInfo))),
749 NONE(), Absyn.dummyInfo);
750 ✗ then
751 matchParamArgs(r_args, r_comps, modif::oldModif);
752
753 end match;
754 end matchParamArgs;
755
756
757 protected function matchVarArgs
758 input String elemId;
759 input list<Absyn.Exp> args "positional arguments" ;
760 input list<Absyn.ComponentItem> comps "fields to be initialized";
761 input list<Absyn.EquationItem> oldEqs ;
762
763 output list<Absyn.EquationItem> newEqs "modifiers to add to component";
764 output list<Absyn.Exp> newArgs "non initialized positional arguments" ;
765 algorithm
766 (newEqs, newArgs) := match(comps, args)
767 local
768 list<Absyn.ComponentItem> r_comps;
769 list<Absyn.Exp> r_args;
770 Absyn.Exp arg;
771 Absyn.Ident cName;
772 Absyn.EquationItem eq;
773
774 case({}, _) then (oldEqs, args);
775 case(Absyn.COMPONENTITEM(Absyn.COMPONENT(cName,_,_), _, _) :: r_comps, arg::r_args)
776 algorithm
777 ✗ eq := Absyn.EQUATIONITEM(Absyn.EQ_EQUALS(Absyn.CREF(Absyn.CREF_QUAL(elemId, {}, Absyn.CREF_IDENT(cName, {}))), arg), NONE(), Absyn.dummyInfo);
778 ✗ then
779 matchVarArgs(elemId, r_args, r_comps, eq::oldEqs);
780
781 end match;
782 end matchVarArgs;
783
784
785 protected function matchNamedArgsClass
786 input String elemId;
787 input list<Absyn.NamedArg> nargs "positional arguments" ;
788 input list<Absyn.ClassPart> classes "fields to be initialize";
789 input list<Absyn.EquationItem> oldEqs "equations to add to component";
790 input list<Absyn.ElementArg> oldModif ;
791
792 output list<Absyn.EquationItem> newEqs "equations to add to component";
793 output list<Absyn.ElementArg> newModif "modifiers to add to component";
794
795 algorithm
796 (newEqs, newModif) := match(classes, nargs)
797 local
798 list<Absyn.EquationItem> eq1;
799 list<Absyn.NamedArg> r_nargs;
800 list<Absyn.ElementArg> modif;
801 Absyn.Ident argName "argName" ;
802 Absyn.Exp argValue "argValue" ;
803
804 case(_, {}) then (oldEqs, oldModif);
805 case({}, _) then (oldEqs, oldModif); // TODO fix to fail
806 case(_, Absyn.NAMEDARG(argName, argValue)::r_nargs)
807 algorithm
808 ✗ (eq1, modif) := matchNamedArgClass(elemId, argName, argValue, classes, oldEqs, oldModif);
809 ✗ then
810 matchNamedArgsClass(elemId, r_nargs, classes, eq1, modif);
811 end match;
812 end matchNamedArgsClass;
813
814 protected function matchNamedArgClass
815 input String elemId;
816 input Absyn.Ident argName "argName" ;
817 input Absyn.Exp argValue "argValue" ;
818 input list<Absyn.ClassPart> classes "fields to be initialize";
819 input list<Absyn.EquationItem> oldEqs "equations to add to component";
820 input list<Absyn.ElementArg> oldModif ;
821
822 output list<Absyn.EquationItem> newEqs "equations to add to component";
823 output list<Absyn.ElementArg> newModif "modifiers to add to component";
824
825 algorithm
826 (newEqs, newModif) := matchcontinue classes
827 local
828 list<Absyn.ClassPart> r_classes;
829 list<Absyn.ElementItem> elems1;
830 list<Absyn.EquationItem> eq1;
831 list<Absyn.ElementArg> modif;
832
833 ✗ case {} then (oldEqs, oldModif);
834 case Absyn.PUBLIC(elems1) :: _
835 algorithm
836 ✗ (eq1, modif, true) := matchNamedArgElems(elemId, argName, argValue, elems1, oldEqs, oldModif);
837 ✗ then
838 (eq1, modif);
839 case _ :: r_classes
840 algorithm
841 ✗ then
842 matchNamedArgClass(elemId, argName, argValue, r_classes, oldEqs, oldModif);
843 end matchcontinue;
844 end matchNamedArgClass;
845
846
847 protected function matchNamedArgElems
848 input String elemId;
849 input Absyn.Ident argName "argName" ;
850 input Absyn.Exp argValue "argValue" ;
851 input list<Absyn.ElementItem> elems "fields to be initialized";
852 input list<Absyn.EquationItem> oldEqs "equations to add to component";
853 input list<Absyn.ElementArg> oldModif "current list of modifiers";
854
855 output list<Absyn.EquationItem> newEqs "equations to add to component";
856 output list<Absyn.ElementArg> newModif "modifiers to add to component";
857 output Boolean found;
858 algorithm
859 (newEqs, newModif, found) := matchcontinue elems
860 local
861 list<Absyn.ElementItem> r_elems;
862 list<Absyn.EquationItem> eqs;
863 list<Absyn.ElementArg> modif;
864 list<Absyn.ComponentItem> comps;
865
866 ✗ case {} then (oldEqs, oldModif, false);
867 case Absyn.ELEMENTITEM(Absyn.ELEMENT(_,_,_,Absyn.COMPONENTS(Absyn.ATTR(_,_,_,Absyn.PARAM(),_,_), _, comps),_,_)) :: _
868 algorithm
869 ✗ (modif, true) := matchParamNamedArg(argName, argValue, comps, oldModif);
870 ✗ then
871 (oldEqs, modif, true) ;
872 case Absyn.ELEMENTITEM(Absyn.ELEMENT(_,_,_,Absyn.COMPONENTS(Absyn.ATTR(_,_,_,Absyn.VAR(),_,_), _, comps),_,_)) :: _
873 algorithm
874 ✗ (eqs, true) := matchVarNamedArg(elemId, argName, argValue, comps, oldEqs);
875 ✗ then
876 (eqs, oldModif, true);
877 case _ :: r_elems
878 ✗ then
879 matchNamedArgElems(elemId, argName, argValue, r_elems, oldEqs, oldModif);
880 end matchcontinue;
881 end matchNamedArgElems;
882
883
884 protected function matchParamNamedArg
885 input Absyn.Ident argName "argName" ;
886 input Absyn.Exp argValue "argValue" ;
887 input list<Absyn.ComponentItem> comps "fields to be initialized";
888 input list<Absyn.ElementArg> oldModif ;
889
890 output list<Absyn.ElementArg> newModif "modifiers to add to component";
891 output Boolean found;
892 algorithm
893 (newModif, found) := match comps
894 local
895 list<Absyn.ComponentItem> r_comps;
896 Absyn.Ident cName;
897 Absyn.ElementArg modif;
898
899 case {} then (oldModif, false);
900 case Absyn.COMPONENTITEM(Absyn.COMPONENT(cName,_,_), _, _) :: _ guard cName == argName
901 algorithm
902 ✗ modif := Absyn.MODIFICATION(false, Absyn.NON_EACH(), Absyn.IDENT(cName), SOME(Absyn.CLASSMOD({}, Absyn.EQMOD(argValue, Absyn.dummyInfo))),
903 NONE(), Absyn.dummyInfo);
904 then
905 (modif::oldModif, true);
906 case _ :: r_comps
907 algorithm
908 ✗ then
909 matchParamNamedArg(argName, argValue, r_comps, oldModif);
910
911 end match;
912 end matchParamNamedArg;
913
914
915 protected function matchVarNamedArg
916 input String elemId;
917 input Absyn.Ident argName "argName" ;
918 input Absyn.Exp argValue "argValue" ;
919 input list<Absyn.ComponentItem> comps "fields to be initialized";
920 input list<Absyn.EquationItem> oldEqs ;
921
922 output list<Absyn.EquationItem> newEqs "modifiers to add to component";
923 output Boolean found;
924 algorithm
925 (newEqs, found) := match comps
926 local
927 list<Absyn.ComponentItem> r_comps;
928 Absyn.Ident cName;
929 Absyn.EquationItem eq;
930
931 case {} then (oldEqs, false);
932 case Absyn.COMPONENTITEM(Absyn.COMPONENT(cName,_,_), _, _) :: _ guard cName == argName
933 algorithm
934 ✗ eq := Absyn.EQUATIONITEM(Absyn.EQ_EQUALS(Absyn.CREF(Absyn.CREF_QUAL(elemId, {}, Absyn.CREF_IDENT(cName, {}))), argValue), NONE(), Absyn.dummyInfo);
935 then
936 (eq::oldEqs, true);
937 case _ :: r_comps
938 algorithm
939 ✗ then
940 matchVarNamedArg(elemId, argName, argValue, r_comps, oldEqs);
941 end match;
942 end matchVarNamedArg;
943
944 annotation(__OpenModelica_Interface="dump_extra");
945 end BlockCallRewrite;
946