OMCompiler/Compiler/NSimCode/NSimGenericCall.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 uniontype NSimGenericCall | ||
| 37 | "file: NSimGenericCall.mo | ||
| 38 | package: NSimGenericCall | ||
| 39 | description: This file contains the data types and functions for generic for loop calls. | ||
| 40 | " | ||
| 41 | public | ||
| 42 | // self import | ||
| 43 | import SimGenericCall = NSimGenericCall; | ||
| 44 | |||
| 45 | protected | ||
| 46 | // NB import | ||
| 47 | import NBEquation.{Equation, EquationPointer, Iterator, IfEquationBody, WhenEquationBody, WhenStatement}; | ||
| 48 | |||
| 49 | // NF import | ||
| 50 | import ComponentRef = NFComponentRef; | ||
| 51 | import ConvertDAE = NFConvertDAE; | ||
| 52 | import DAE; | ||
| 53 | import DAEUtil; | ||
| 54 | import OldExpression = Expression; | ||
| 55 | import Expression = NFExpression; | ||
| 56 | import Operator = NFOperator; | ||
| 57 | import SimplifyExp = NFSimplifyExp; | ||
| 58 | import Statement = NFStatement; | ||
| 59 | |||
| 60 | // old backend import | ||
| 61 | import OldSimCode = SimCode; | ||
| 62 | import OldBackendDAE = BackendDAE; | ||
| 63 | |||
| 64 | import NSimCode.Identifier; | ||
| 65 | |||
| 66 | public | ||
| 67 | record SINGLE_GENERIC_CALL | ||
| 68 | Integer index; | ||
| 69 | list<SimIterator> iters; | ||
| 70 | Expression lhs; | ||
| 71 | Expression rhs; | ||
| 72 | Boolean resizable; | ||
| 73 | end SINGLE_GENERIC_CALL; | ||
| 74 | |||
| 75 | record IF_GENERIC_CALL | ||
| 76 | Integer index; | ||
| 77 | list<SimIterator> iters; | ||
| 78 | list<SimBranch> branches; | ||
| 79 | Boolean resizable; | ||
| 80 | end IF_GENERIC_CALL; | ||
| 81 | |||
| 82 | record WHEN_GENERIC_CALL | ||
| 83 | Integer index; | ||
| 84 | list<SimIterator> iters; | ||
| 85 | list<SimBranch> branches; | ||
| 86 | Boolean resizable; | ||
| 87 | end WHEN_GENERIC_CALL; | ||
| 88 | |||
| 89 | function mapShallow | ||
| 90 | input output SimGenericCall call; | ||
| 91 | input mapExp func; | ||
| 92 | partial function mapExp | ||
| 93 | input output Expression exp; | ||
| 94 | end mapExp; | ||
| 95 | algorithm | ||
| 96 | call := match call | ||
| 97 | case SINGLE_GENERIC_CALL() algorithm | ||
| 98 |
1/2✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
|
309 | call.lhs := func(call.lhs); |
| 99 |
1/2✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
|
309 | call.rhs := func(call.rhs); |
| 100 | then call; | ||
| 101 | case IF_GENERIC_CALL() algorithm | ||
| 102 |
4/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
|
12 | call.branches := list(SimBranch.mapShallow(branch, func) for branch in call.branches); |
| 103 | then call; | ||
| 104 | case WHEN_GENERIC_CALL() algorithm | ||
| 105 |
4/4✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
|
3 | call.branches := list(SimBranch.mapShallow(branch, func) for branch in call.branches); |
| 106 | then call; | ||
| 107 | else call; | ||
| 108 | end match; | ||
| 109 | end mapShallow; | ||
| 110 | |||
| 111 | function toString | ||
| 112 | input SimGenericCall call; | ||
| 113 | output String str; | ||
| 114 | algorithm | ||
| 115 | str := match call | ||
| 116 | 5 | case SINGLE_GENERIC_CALL() then "(" + intString(call.index) + ") [SNGL]: " | |
| 117 | + List.toString(call.iters, SimIterator.toString) + "\n\t" | ||
| 118 | + Expression.toString(call.lhs) + " = " + Expression.toString(call.rhs); | ||
| 119 | ✗ | case IF_GENERIC_CALL() then "(" + intString(call.index) + ") [-IF-]: " | |
| 120 | + List.toString(call.iters, SimIterator.toString) + "\n\t" | ||
| 121 | + List.toStringCustom(call.branches, SimBranch.toString, "", "", "\telse", ""); | ||
| 122 | ✗ | case WHEN_GENERIC_CALL() then "(" + intString(call.index) + ") [WHEN]: " | |
| 123 | + List.toString(call.iters, SimIterator.toString) + "\n\t" | ||
| 124 | + List.toStringCustom(call.branches, SimBranch.toString, "", "", "\telse", ""); | ||
| 125 | else "CALL_NOT_SUPPORTED"; | ||
| 126 | end match; | ||
| 127 | end toString; | ||
| 128 | |||
| 129 | function fromIdentifier | ||
| 130 | input tuple<Identifier, Integer> ident_tpl; | ||
| 131 | output SimGenericCall call; | ||
| 132 | protected | ||
| 133 | Pointer<Equation> eqn_ptr; | ||
| 134 | Integer index; | ||
| 135 | Boolean resizable; | ||
| 136 | Equation body, eqn; | ||
| 137 | algorithm | ||
| 138 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 375 times.
|
375 | (Identifier.IDENTIFIER(eqn = eqn_ptr, resizable = resizable), index) := ident_tpl; |
| 139 | 375 | eqn := Pointer.access(eqn_ptr); | |
| 140 | call := match eqn | ||
| 141 | local | ||
| 142 | list<SimIterator> iters; | ||
| 143 | |||
| 144 | case Equation.FOR_EQUATION(body = {body as Equation.IF_EQUATION()}) algorithm | ||
| 145 | 3 | iters := SimIterator.fromIterator(eqn.iter); | |
| 146 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | then IF_GENERIC_CALL( |
| 147 | index = index, | ||
| 148 | iters = iters, | ||
| 149 | branches = SimBranch.fromIfBody(body.body), | ||
| 150 | resizable = resizable); | ||
| 151 | |||
| 152 | case Equation.FOR_EQUATION(body = {body as Equation.WHEN_EQUATION()}) algorithm | ||
| 153 | 1 | iters := SimIterator.fromIterator(eqn.iter); | |
| 154 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | then WHEN_GENERIC_CALL( |
| 155 | index = index, | ||
| 156 | iters = iters, | ||
| 157 | branches = SimBranch.fromWhenBody(body.body), | ||
| 158 | resizable = resizable); | ||
| 159 | |||
| 160 | case Equation.FOR_EQUATION(body = {body}) algorithm | ||
| 161 | 371 | iters := SimIterator.fromIterator(eqn.iter); | |
| 162 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 354 times.
|
388 | then SINGLE_GENERIC_CALL( |
| 163 | index = index, | ||
| 164 | iters = iters, | ||
| 165 | lhs = Util.getOption(Equation.getLHS(body)), | ||
| 166 | rhs = Util.getOption(Equation.getRHS(body)), | ||
| 167 | resizable = resizable); | ||
| 168 | |||
| 169 | else algorithm | ||
| 170 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for incorrect equation: " + Equation.toString(eqn)}); | |
| 171 | ✗ | then fail(); | |
| 172 | end match; | ||
| 173 | end fromIdentifier; | ||
| 174 | |||
| 175 | function convert | ||
| 176 | input SimGenericCall call; | ||
| 177 | output OldSimCode.SimGenericCall old_call; | ||
| 178 | algorithm | ||
| 179 | old_call := match call | ||
| 180 |
4/4✓ Branch 0 taken 604 times.
✓ Branch 1 taken 521 times.
✓ Branch 2 taken 604 times.
✓ Branch 3 taken 521 times.
|
1125 | case SINGLE_GENERIC_CALL() then OldSimCode.SINGLE_GENERIC_CALL( |
| 181 | index = call.index, | ||
| 182 | iters = list(SimIterator.convert(iter) for iter in call.iters), | ||
| 183 | lhs = Expression.toDAE(call.lhs), | ||
| 184 | rhs = setRelationAsub(Expression.toDAE(call.rhs), relationAsub(call.iters)), | ||
| 185 | resizable = call.resizable); | ||
| 186 |
8/8✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 3 times.
|
14 | case IF_GENERIC_CALL() then OldSimCode.IF_GENERIC_CALL( |
| 187 | index = call.index, | ||
| 188 | iters = list(SimIterator.convert(iter) for iter in call.iters), | ||
| 189 | branches = list(SimBranch.convert(branch) for branch in call.branches), | ||
| 190 | resizable = call.resizable); | ||
| 191 |
8/8✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 1 time.
|
3 | case WHEN_GENERIC_CALL() then OldSimCode.WHEN_GENERIC_CALL( |
| 192 | index = call.index, | ||
| 193 | iters = list(SimIterator.convert(iter) for iter in call.iters), | ||
| 194 | branches = list(SimBranch.convert(branch) for branch in call.branches), | ||
| 195 | resizable = call.resizable); | ||
| 196 | else algorithm | ||
| 197 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for incorrect call: " + toString(call)}); | |
| 198 | ✗ | then fail(); | |
| 199 | end match; | ||
| 200 | end convert; | ||
| 201 | |||
| 202 | function relationAsub | ||
| 203 | "The relations of an event condition in a loop have one storedRelations[] slot per | ||
| 204 | iteration. For a single iterator with a literal range the slot of the current iteration | ||
| 205 | is index + (iterator - start)/step, see DAE.RELATION.optionExpisASUB." | ||
| 206 | input list<SimIterator> iters; | ||
| 207 | output Option<tuple<DAE.Exp, Integer, Integer>> asub; | ||
| 208 | algorithm | ||
| 209 | asub := match iters | ||
| 210 | local | ||
| 211 | ComponentRef name; | ||
| 212 | Integer start, step; | ||
| 213 | case {SimIterator.SIM_ITERATOR_RANGE(name = name, start = Expression.INTEGER(start), step = Expression.INTEGER(step))} | ||
| 214 | 438 | then SOME((DAE.CREF(ComponentRef.toDAE(name), DAE.T_INTEGER_DEFAULT), start, step)); | |
| 215 | else NONE(); | ||
| 216 | end match; | ||
| 217 | end relationAsub; | ||
| 218 | |||
| 219 | function setRelationAsub | ||
| 220 | "sets the iteration offset of the relations with a storedRelations[] slot" | ||
| 221 | input output DAE.Exp exp; | ||
| 222 | input Option<tuple<DAE.Exp, Integer, Integer>> asub; | ||
| 223 | algorithm | ||
| 224 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 693 times.
✓ Branch 2 taken 610 times.
✓ Branch 3 taken 83 times.
|
693 | if isSome(asub) then |
| 225 | 610 | (exp, _) := OldExpression.traverseExpBottomUp(exp, setRelationAsubExp, asub); | |
| 226 | end if; | ||
| 227 | end setRelationAsub; | ||
| 228 | |||
| 229 | function setRelationAsubExp | ||
| 230 | input output DAE.Exp exp; | ||
| 231 | input output Option<tuple<DAE.Exp, Integer, Integer>> asub; | ||
| 232 | algorithm | ||
| 233 | exp := match exp | ||
| 234 | case DAE.RELATION(optionExpisASUB = NONE()) guard(exp.index >= 0) | ||
| 235 | 12 | then DAE.RELATION(exp.exp1, exp.operator, exp.exp2, exp.index, asub); | |
| 236 | else exp; | ||
| 237 | end match; | ||
| 238 | end setRelationAsubExp; | ||
| 239 | |||
| 240 | function setRelationAsubStatements | ||
| 241 | "sets the iteration offset of the relations in for-statements, see relationAsub" | ||
| 242 | input output list<DAE.Statement> stmts; | ||
| 243 | input Option<tuple<DAE.Exp, Integer, Integer>> asub = NONE(); | ||
| 244 | protected | ||
| 245 | list<DAE.Statement> acc = {}; | ||
| 246 | Option<tuple<DAE.Exp, Integer, Integer>> for_asub; | ||
| 247 | algorithm | ||
| 248 |
2/2✓ Branch 0 taken 1241 times.
✓ Branch 1 taken 1075 times.
|
2316 | for stmt in stmts loop |
| 249 | stmt := match stmt | ||
| 250 | local | ||
| 251 | DAE.Statement new_stmt; | ||
| 252 | case new_stmt as DAE.STMT_FOR() algorithm | ||
| 253 | for_asub := match new_stmt.range | ||
| 254 | local | ||
| 255 | Integer start, step; | ||
| 256 | case DAE.RANGE(start = DAE.ICONST(start), step = NONE()) | ||
| 257 | 101 | then SOME((DAE.CREF(DAE.CREF_IDENT(new_stmt.iter, new_stmt.type_, {}), new_stmt.type_), start, 1)); | |
| 258 | case DAE.RANGE(start = DAE.ICONST(start), step = SOME(DAE.ICONST(step))) | ||
| 259 | 2 | then SOME((DAE.CREF(DAE.CREF_IDENT(new_stmt.iter, new_stmt.type_, {}), new_stmt.type_), start, step)); | |
| 260 | else NONE(); | ||
| 261 | end match; | ||
| 262 | 103 | new_stmt.statementLst := setRelationAsubStatements(new_stmt.statementLst, for_asub); | |
| 263 | then new_stmt; | ||
| 264 | else algorithm | ||
| 265 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 1138 times.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 1058 times.
|
1138 | if isSome(asub) then |
| 266 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
|
80 | ({new_stmt}, _) := DAEUtil.traverseDAEStmts({stmt}, setRelationAsubStmtExp, asub); |
| 267 | else | ||
| 268 | new_stmt := stmt; | ||
| 269 | end if; | ||
| 270 | then new_stmt; | ||
| 271 | end match; | ||
| 272 | acc := stmt :: acc; | ||
| 273 | end for; | ||
| 274 | 1075 | stmts := listReverse(acc); | |
| 275 | end setRelationAsubStatements; | ||
| 276 | |||
| 277 | function setRelationAsubStmtExp | ||
| 278 | input output DAE.Exp exp; | ||
| 279 | input DAE.Statement stmt; | ||
| 280 | input output Option<tuple<DAE.Exp, Integer, Integer>> asub; | ||
| 281 | algorithm | ||
| 282 | 172 | exp := setRelationAsub(exp, asub); | |
| 283 | end setRelationAsubStmtExp; | ||
| 284 | |||
| 285 | uniontype SimIterator | ||
| 286 | record SIM_ITERATOR_RANGE | ||
| 287 | ComponentRef name; | ||
| 288 | Expression start; | ||
| 289 | Expression step; | ||
| 290 | Expression stop; | ||
| 291 | Expression size; | ||
| 292 | list<DependentIterator> sub_iter; | ||
| 293 | end SIM_ITERATOR_RANGE; | ||
| 294 | |||
| 295 | record SIM_ITERATOR_LIST | ||
| 296 | ComponentRef name; | ||
| 297 | list<Integer> lst; | ||
| 298 | Integer size; | ||
| 299 | list<DependentIterator> sub_iter; | ||
| 300 | end SIM_ITERATOR_LIST; | ||
| 301 | |||
| 302 | function toString | ||
| 303 | input SimIterator iter; | ||
| 304 | output String str; | ||
| 305 | function subIterString | ||
| 306 | input list<DependentIterator> sub_iter; | ||
| 307 | output String str = List.toStringCustom(list(Util.tuple21(tpl) for tpl in sub_iter), ComponentRef.toString, "", "(", ", ", ")", false); | ||
| 308 | end subIterString; | ||
| 309 | algorithm | ||
| 310 | str := match iter | ||
| 311 | 5 | case SIM_ITERATOR_RANGE() then "{" + ComponentRef.toString(iter.name) + " | start:" + Expression.toString(iter.start) + ", step:" + Expression.toString(iter.step) + ", stop:" + Expression.toString(iter.stop) + ", size: " + Expression.toString(iter.size) + "}" + subIterString(iter.sub_iter); | |
| 312 | ✗ | case SIM_ITERATOR_LIST() then "{" + ComponentRef.toString(iter.name) + " | list: " + List.toString(iter.lst, intString, List.Style.FLAT_CURLY_SHORT) + "}" + subIterString(iter.sub_iter); | |
| 313 | end match; | ||
| 314 | end toString; | ||
| 315 | |||
| 316 | function fromIterator | ||
| 317 | "create sim iterator from backend iterator. | ||
| 318 | Note: needs to reverse the order of iterators since it needs to be mapped inner first" | ||
| 319 | input Iterator iter; | ||
| 320 | output list<SimIterator> sim_iter = {}; | ||
| 321 | protected | ||
| 322 | list<ComponentRef> names; | ||
| 323 | list<Expression> ranges; | ||
| 324 | list<Option<Iterator>> maps; | ||
| 325 | ComponentRef name; | ||
| 326 | Operator addOp, mulOp; | ||
| 327 | Expression range, step, size; | ||
| 328 | Option<Iterator> map; | ||
| 329 | list<Integer> lst; | ||
| 330 | list<DependentIterator> sub_iter; | ||
| 331 | algorithm | ||
| 332 | 1658 | (names, ranges, maps) := Iterator.getFrames(iter); | |
| 333 |
2/2✓ Branch 1 taken 950 times.
✓ Branch 2 taken 1658 times.
|
2608 | for tpl in List.zip3(names, ranges, maps) loop |
| 334 | 950 | (name, range, map) := tpl; | |
| 335 | sim_iter := match range | ||
| 336 | case Expression.RANGE() algorithm | ||
| 337 | 938 | step := Util.getOptionOrDefault(range.step, Expression.INTEGER(1)); | |
| 338 | 938 | addOp := Operator.makeAdd(Expression.typeOf(range.start)); | |
| 339 | 938 | mulOp := Operator.makeMul(Expression.typeOf(range.start)); | |
| 340 | // build the size expression (stop-start)/step+1 | ||
| 341 | 938 | size := Expression.MULTARY({range.stop}, {range.start}, addOp); | |
| 342 | 938 | size := Expression.MULTARY({size}, {step}, mulOp); | |
| 343 | 938 | size := Expression.MULTARY({size, Expression.INTEGER(1)}, {}, addOp); | |
| 344 | 938 | size := SimplifyExp.simplify(size); | |
| 345 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 938 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 938 times.
|
938 | sub_iter := if isSome(map) then subIterators(Util.getOption(map)) else {}; |
| 346 | 938 | then SIM_ITERATOR_RANGE(name, range.start, step, range.stop, size, sub_iter) :: sim_iter; | |
| 347 | |||
| 348 | case Expression.ARRAY() guard(range.literal) algorithm | ||
| 349 |
4/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 12 times.
|
96 | lst := list(Expression.integerValue(e) for e in range.elements); |
| 350 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
12 | sub_iter := if isSome(map) then subIterators(Util.getOption(map)) else {}; |
| 351 | 12 | then SIM_ITERATOR_LIST(name, lst, listLength(lst), sub_iter) :: sim_iter; | |
| 352 | |||
| 353 | else algorithm | ||
| 354 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for incorrect iterator domain: " + Expression.toString(range)}); | |
| 355 | ✗ | then fail(); | |
| 356 | end match; | ||
| 357 | end for; | ||
| 358 | end fromIterator; | ||
| 359 | |||
| 360 | function subIterators | ||
| 361 | "creates a list dependent sub iterators. the ranges can only be an array" | ||
| 362 | input Iterator iter; | ||
| 363 | output list<DependentIterator> sub_iter = {}; | ||
| 364 | protected | ||
| 365 | list<ComponentRef> names; | ||
| 366 | list<Expression> ranges; | ||
| 367 | ComponentRef name; | ||
| 368 | Expression range; | ||
| 369 | algorithm | ||
| 370 | // sub iterators are not allowed to have sub iterators themselves | ||
| 371 | ✗ | (names, ranges, _) := Iterator.getFrames(iter); | |
| 372 | ✗ | for tpl in listReverse(List.zip(names, ranges)) loop | |
| 373 | ✗ | (name, range) := tpl; | |
| 374 | sub_iter := match range | ||
| 375 | ✗ | case Expression.ARRAY() then (name, range.elements) :: sub_iter; | |
| 376 | else algorithm | ||
| 377 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed for incorrect iterator domain: " + Expression.toString(range)}); | |
| 378 | ✗ | then fail(); | |
| 379 | end match; | ||
| 380 | end for; | ||
| 381 | end subIterators; | ||
| 382 | |||
| 383 | function convert | ||
| 384 | input SimIterator iter; | ||
| 385 | output OldBackendDAE.SimIterator old_iter; | ||
| 386 | function convertSubIterator | ||
| 387 | input tuple<ComponentRef, array<Expression>> sub_iter; | ||
| 388 | output tuple<DAE.ComponentRef, array<DAE.Exp>> old_sub_iter = (ComponentRef.toDAE(Util.tuple21(sub_iter)), listArray(list(Expression.toDAE(e) for e in Util.tuple22(sub_iter)))); | ||
| 389 | end convertSubIterator; | ||
| 390 | algorithm | ||
| 391 | old_iter := match iter | ||
| 392 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1452 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1452 times.
|
1452 | case SIM_ITERATOR_RANGE() then OldBackendDAE.SIM_ITERATOR_RANGE(ComponentRef.toDAE(iter.name), Expression.toDAE(iter.start), Expression.toDAE(iter.step), Expression.toDAE(iter.stop), Expression.toDAE(iter.size), Expression.getInteger(iter.size, false), list(convertSubIterator(si) for si in iter.sub_iter)); |
| 393 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
12 | case SIM_ITERATOR_LIST() then OldBackendDAE.SIM_ITERATOR_LIST(ComponentRef.toDAE(iter.name), iter.lst, iter.size, list(convertSubIterator(si) for si in iter.sub_iter)); |
| 394 | end match; | ||
| 395 | end convert; | ||
| 396 | end SimIterator; | ||
| 397 | |||
| 398 | type DependentIterator = tuple<ComponentRef, array<Expression>> "represents a dependent sub iterator"; | ||
| 399 | |||
| 400 | uniontype SimBranch | ||
| 401 | record SIM_BRANCH | ||
| 402 | Expression condition; | ||
| 403 | list<tuple<Expression, Expression>> body; | ||
| 404 | end SIM_BRANCH; | ||
| 405 | |||
| 406 | record SIM_BRANCH_STMT | ||
| 407 | Expression condition; | ||
| 408 | list<Statement> body; | ||
| 409 | end SIM_BRANCH_STMT; | ||
| 410 | |||
| 411 | function mapShallow | ||
| 412 | input output SimBranch branch; | ||
| 413 | input mapExp func; | ||
| 414 | protected | ||
| 415 | partial function mapExp | ||
| 416 | input output Expression exp; | ||
| 417 | end mapExp; | ||
| 418 | algorithm | ||
| 419 | branch := match branch | ||
| 420 | case SIM_BRANCH() algorithm | ||
| 421 |
6/8✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
|
18 | branch.body := list((func(Util.tuple21(tpl)), func(Util.tuple22(tpl))) for tpl in branch.body); |
| 422 | then branch; | ||
| 423 | case SIM_BRANCH_STMT() algorithm | ||
| 424 |
4/4✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
|
3 | branch.body := list(Statement.mapExp(stmt, func) for stmt in branch.body); |
| 425 | then branch; | ||
| 426 | else branch; | ||
| 427 | end match; | ||
| 428 | end mapShallow; | ||
| 429 | |||
| 430 | function toString | ||
| 431 | input SimBranch branch; | ||
| 432 | output String str; | ||
| 433 | protected | ||
| 434 | Expression lhs, rhs; | ||
| 435 | algorithm | ||
| 436 | str := match branch | ||
| 437 | case SIM_BRANCH() algorithm | ||
| 438 | ✗ | str := if Expression.isEnd(branch.condition) then "\n" else "if " + Expression.toString(branch.condition) + " then\n"; | |
| 439 | ✗ | for tpl in branch.body loop | |
| 440 | ✗ | (lhs, rhs) := tpl; | |
| 441 | ✗ | str := str + "\t " + Expression.toString(lhs) + " = " + Expression.toString(rhs) + "\n"; | |
| 442 | end for; | ||
| 443 | then str; | ||
| 444 | case SIM_BRANCH_STMT() algorithm | ||
| 445 | ✗ | str := if Expression.isEnd(branch.condition) then "\n" else "when " + Expression.toString(branch.condition) + " then\n"; | |
| 446 | ✗ | str := str + List.toString(branch.body, function Statement.toString(indent = ""), List.Style.NEWLINE_TAB); | |
| 447 | then str; | ||
| 448 | else "SIM BRANCH NOT KNOWN"; | ||
| 449 | end match; | ||
| 450 | end toString; | ||
| 451 | |||
| 452 | function fromIfBody | ||
| 453 | input IfEquationBody if_body; | ||
| 454 | output list<SimBranch> branches; | ||
| 455 | protected | ||
| 456 | list<tuple<Expression, Expression>> body = {}; | ||
| 457 | SimBranch branch; | ||
| 458 | algorithm | ||
| 459 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
|
12 | for eqn in listReverse(if_body.then_eqns) loop |
| 460 | // ToDo: what if there are more complex things inside? | ||
| 461 | 6 | body := (Util.getOption(Equation.getLHS(Pointer.access(eqn))), Util.getOption(Equation.getRHS(Pointer.access(eqn)))) :: body; | |
| 462 | end for; | ||
| 463 | 6 | branch := SIM_BRANCH(if_body.condition, body); | |
| 464 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
|
6 | if isSome(if_body.else_if) then |
| 465 | 3 | branches := branch :: fromIfBody(Util.getOption(if_body.else_if)); | |
| 466 | else | ||
| 467 | branches := {branch}; | ||
| 468 | end if; | ||
| 469 | end fromIfBody; | ||
| 470 | |||
| 471 | function fromWhenBody | ||
| 472 | input WhenEquationBody when_body; | ||
| 473 | output list<SimBranch> branches; | ||
| 474 | protected | ||
| 475 | SimBranch branch; | ||
| 476 | algorithm | ||
| 477 |
4/4✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
|
2 | branch := SIM_BRANCH_STMT(when_body.condition, list(WhenStatement.toStatement(stmt) for stmt in when_body.when_stmts)); |
| 478 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
|
1 | if isSome(when_body.else_when) then |
| 479 | ✗ | branches := branch :: fromWhenBody(Util.getOption(when_body.else_when)); | |
| 480 | else | ||
| 481 | branches := {branch}; | ||
| 482 | end if; | ||
| 483 | end fromWhenBody; | ||
| 484 | |||
| 485 | function convert | ||
| 486 | input SimBranch branch; | ||
| 487 | output OldSimCode.SimBranch old_branch; | ||
| 488 | protected | ||
| 489 | Option<DAE.Exp> old_condition; | ||
| 490 | list<tuple<DAE.Exp, DAE.Exp>> old_body = {}; | ||
| 491 | Expression lhs, rhs; | ||
| 492 | algorithm | ||
| 493 | old_branch := match branch | ||
| 494 | case SIM_BRANCH() algorithm | ||
| 495 | old_condition := match branch.condition | ||
| 496 | case Expression.END() then NONE(); | ||
| 497 | 3 | else SOME(Expression.toDAE(branch.condition)); | |
| 498 | end match; | ||
| 499 | |||
| 500 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
|
12 | for tpl in listReverse(branch.body) loop |
| 501 | 6 | (lhs, rhs) := tpl; | |
| 502 | 6 | old_body := (Expression.toDAE(lhs), Expression.toDAE(rhs)) :: old_body; | |
| 503 | end for; | ||
| 504 | |||
| 505 | 6 | then OldSimCode.SIM_BRANCH( | |
| 506 | condition = old_condition, | ||
| 507 | body = old_body); | ||
| 508 | |||
| 509 | case SIM_BRANCH_STMT() algorithm | ||
| 510 | old_condition := match branch.condition | ||
| 511 | case Expression.END() then NONE(); | ||
| 512 | 1 | else SOME(Expression.toDAE(branch.condition)); | |
| 513 | end match; | ||
| 514 | |||
| 515 | 1 | then OldSimCode.SIM_BRANCH_STMT( | |
| 516 | condition = old_condition, | ||
| 517 | body = ConvertDAE.convertStatements(branch.body)); | ||
| 518 | |||
| 519 | else fail(); | ||
| 520 | end match; | ||
| 521 | end convert; | ||
| 522 | end SimBranch; | ||
| 523 | |||
| 524 | annotation(__OpenModelica_Interface="nbackend"); | ||
| 525 | end NSimGenericCall; | ||
| 526 |