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 |