OMCompiler/Compiler/NFFrontEnd/NFBinding.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 NFBinding | ||
| 37 | |||
| 38 | public | ||
| 39 | import BaseModelica; | ||
| 40 | import Expression = NFExpression; | ||
| 41 | import NFInstNode.InstNode; | ||
| 42 | import NFInstNode; | ||
| 43 | import Type = NFType; | ||
| 44 | import NFPrefixes.{Variability, Purity}; | ||
| 45 | import ErrorTypes; | ||
| 46 | import Mutable; | ||
| 47 | import Subscript = NFSubscript; | ||
| 48 | |||
| 49 | protected | ||
| 50 | import Absyn; | ||
| 51 | import Binding = NFBinding; | ||
| 52 | import Component = NFComponent; | ||
| 53 | import ComponentRef = NFComponentRef; | ||
| 54 | import Pointer; | ||
| 55 | import PointerWeak; | ||
| 56 | import Variable = NFVariable; | ||
| 57 | import DAE; | ||
| 58 | import Dump; | ||
| 59 | import Error; | ||
| 60 | |||
| 61 | public | ||
| 62 | constant Binding EMPTY_BINDING = UNBOUND(); | ||
| 63 | constant Integer NO_CONFIDENCE = 99999; // Value has no significance other than being large, and visible when debugging. | ||
| 64 | |||
| 65 | type EachType = enumeration( | ||
| 66 | NOT_EACH, | ||
| 67 | EACH | ||
| 68 | ); | ||
| 69 | |||
| 70 | type EvalState = enumeration( | ||
| 71 | NOT_EVALUATED, | ||
| 72 | EVALUATING, | ||
| 73 | EVALUATED | ||
| 74 | ); | ||
| 75 | |||
| 76 | type Source = enumeration( | ||
| 77 | BINDING "The binding comes from a binding equation.", | ||
| 78 | TYPE "The binding is an attribute modifier of a type, see Inst.markTypeModifier.", | ||
| 79 | MODIFIER "The binding comes from a modifier.", | ||
| 80 | GENERATED "The binding was generated by the frontend." | ||
| 81 | ); | ||
| 82 | |||
| 83 | record UNBOUND | ||
| 84 | end UNBOUND; | ||
| 85 | |||
| 86 | record RAW_BINDING | ||
| 87 | Absyn.Exp bindingExp; | ||
| 88 | NFInstNode.ScopeRef scope "Weakly: the scope owns the class this binding | ||
| 89 | sits in."; | ||
| 90 | list<Subscript> subs; | ||
| 91 | EachType eachType; | ||
| 92 | Source source; | ||
| 93 | Integer confidence; | ||
| 94 | SourceInfo info; | ||
| 95 | end RAW_BINDING; | ||
| 96 | |||
| 97 | record UNTYPED_BINDING | ||
| 98 | Expression bindingExp; | ||
| 99 | Boolean isProcessing; | ||
| 100 | NFInstNode.ScopeRef scope "See RAW_BINDING.scope."; | ||
| 101 | EachType eachType; | ||
| 102 | Source source; | ||
| 103 | Integer confidence; | ||
| 104 | SourceInfo info; | ||
| 105 | end UNTYPED_BINDING; | ||
| 106 | |||
| 107 | record TYPED_BINDING | ||
| 108 | Expression bindingExp; | ||
| 109 | Type bindingType; | ||
| 110 | Variability variability; | ||
| 111 | Purity purity; | ||
| 112 | EachType eachType; | ||
| 113 | Mutable<EvalState> evalState; | ||
| 114 | Boolean isFlattened; | ||
| 115 | Source source; | ||
| 116 | Integer confidence; | ||
| 117 | SourceInfo info; | ||
| 118 | end TYPED_BINDING; | ||
| 119 | |||
| 120 | record FLAT_BINDING | ||
| 121 | Expression bindingExp; | ||
| 122 | Variability variability; | ||
| 123 | Source source; | ||
| 124 | Integer confidence; | ||
| 125 | end FLAT_BINDING; | ||
| 126 | |||
| 127 | record CEVAL_BINDING | ||
| 128 | "Used by the constant evaluation for generated bindings (e.g. record | ||
| 129 | bindings constructed from the record fields) that should be discarded | ||
| 130 | during flattening." | ||
| 131 | Expression bindingExp; | ||
| 132 | end CEVAL_BINDING; | ||
| 133 | |||
| 134 | record INVALID_BINDING | ||
| 135 | Binding binding; | ||
| 136 | list<ErrorTypes.TotalMessage> errors; | ||
| 137 | end INVALID_BINDING; | ||
| 138 | |||
| 139 | record WILD end WILD; | ||
| 140 | |||
| 141 | public | ||
| 142 | function fromAbsyn | ||
| 143 | input Option<Absyn.Exp> bindingExp; | ||
| 144 | input Boolean eachPrefix; | ||
| 145 | input InstNode scope; | ||
| 146 | input Integer instanceLevel; | ||
| 147 | input SourceInfo info; | ||
| 148 | output Binding binding; | ||
| 149 | algorithm | ||
| 150 | binding := match bindingExp | ||
| 151 | local | ||
| 152 | Absyn.Exp exp; | ||
| 153 | EachType each_ty; | ||
| 154 | |||
| 155 | case SOME(exp) | ||
| 156 | algorithm | ||
| 157 |
2/2✓ Branch 0 taken 2056421 times.
✓ Branch 1 taken 16612 times.
|
2073033 | each_ty := if eachPrefix then EachType.EACH else EachType.NOT_EACH; |
| 158 | 2073033 | then | |
| 159 | RAW_BINDING(exp, InstNode.scopeRef(scope), {}, each_ty, Source.BINDING, instanceLevel, info); | ||
| 160 | |||
| 161 | else EMPTY_BINDING; | ||
| 162 | end match; | ||
| 163 | end fromAbsyn; | ||
| 164 | |||
| 165 | function isBound | ||
| 166 | input Binding binding; | ||
| 167 | output Boolean isBound; | ||
| 168 | algorithm | ||
| 169 | isBound := match binding | ||
| 170 | case UNBOUND() then false; | ||
| 171 | case INVALID_BINDING() then false; | ||
| 172 | else true; | ||
| 173 | end match; | ||
| 174 | end isBound; | ||
| 175 | |||
| 176 | function isExplicitlyBound | ||
| 177 | input Binding binding; | ||
| 178 | output Boolean isBound; | ||
| 179 | algorithm | ||
| 180 | isBound := match binding | ||
| 181 | case UNBOUND() then false; | ||
| 182 | case CEVAL_BINDING() then false; | ||
| 183 | case INVALID_BINDING() then false; | ||
| 184 | else true; | ||
| 185 | end match; | ||
| 186 | end isExplicitlyBound; | ||
| 187 | |||
| 188 | function isUnbound | ||
| 189 | input Binding binding; | ||
| 190 | output Boolean isUnbound; | ||
| 191 | algorithm | ||
| 192 | isUnbound := match binding | ||
| 193 | case UNBOUND() then true; | ||
| 194 | else false; | ||
| 195 | end match; | ||
| 196 | end isUnbound; | ||
| 197 | |||
| 198 | function isInvalid | ||
| 199 | input Binding binding; | ||
| 200 | output Boolean isInvalid; | ||
| 201 | algorithm | ||
| 202 | isInvalid := match binding | ||
| 203 | case INVALID_BINDING() then true; | ||
| 204 | else false; | ||
| 205 | end match; | ||
| 206 | end isInvalid; | ||
| 207 | |||
| 208 | function typedExp | ||
| 209 | input Binding binding; | ||
| 210 | output Option<Expression> exp; | ||
| 211 | algorithm | ||
| 212 | exp := match binding | ||
| 213 | 42626 | case TYPED_BINDING() then SOME(binding.bindingExp); | |
| 214 | 243 | case FLAT_BINDING() then SOME(binding.bindingExp); | |
| 215 | else NONE(); | ||
| 216 | end match; | ||
| 217 | end typedExp; | ||
| 218 | |||
| 219 | function getUntypedExp | ||
| 220 | input Binding binding; | ||
| 221 | output Expression exp; | ||
| 222 | algorithm | ||
| 223 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 120326 times.
|
120326 | UNTYPED_BINDING(bindingExp = exp) := binding; |
| 224 | end getUntypedExp; | ||
| 225 | |||
| 226 | function getTypedExp | ||
| 227 | input Binding binding; | ||
| 228 | output Expression exp; | ||
| 229 | algorithm | ||
| 230 | exp := match binding | ||
| 231 | 2741868 | case TYPED_BINDING() then binding.bindingExp; | |
| 232 | 833872 | case FLAT_BINDING() then binding.bindingExp; | |
| 233 | end match; | ||
| 234 | end getTypedExp; | ||
| 235 | |||
| 236 | function setTypedExp | ||
| 237 | input Expression exp; | ||
| 238 | input output Binding binding; | ||
| 239 | algorithm | ||
| 240 | () := match binding | ||
| 241 | case TYPED_BINDING() | ||
| 242 | algorithm | ||
| 243 | 254323 | binding.bindingExp := exp; | |
| 244 | then | ||
| 245 | (); | ||
| 246 | |||
| 247 | case FLAT_BINDING() | ||
| 248 | algorithm | ||
| 249 | 9623 | binding.bindingExp := exp; | |
| 250 | then | ||
| 251 | (); | ||
| 252 | end match; | ||
| 253 | end setTypedExp; | ||
| 254 | |||
| 255 | function hasExp | ||
| 256 | input Binding binding; | ||
| 257 | output Boolean hasExp; | ||
| 258 | algorithm | ||
| 259 | hasExp := match binding | ||
| 260 | case UNTYPED_BINDING() then true; | ||
| 261 | case TYPED_BINDING() then true; | ||
| 262 | case FLAT_BINDING() then true; | ||
| 263 | else false; | ||
| 264 | end match; | ||
| 265 | end hasExp; | ||
| 266 | |||
| 267 | function getExp | ||
| 268 | input Binding binding; | ||
| 269 | output Expression exp; | ||
| 270 | algorithm | ||
| 271 | exp := match binding | ||
| 272 | 35809 | case UNTYPED_BINDING() then binding.bindingExp; | |
| 273 | 149141 | case TYPED_BINDING() then binding.bindingExp; | |
| 274 | 17913 | case FLAT_BINDING() then binding.bindingExp; | |
| 275 | end match; | ||
| 276 | end getExp; | ||
| 277 | |||
| 278 | function getExpOpt | ||
| 279 | input Binding binding; | ||
| 280 | output Option<Expression> exp; | ||
| 281 | algorithm | ||
| 282 | exp := match binding | ||
| 283 | 41308 | case UNTYPED_BINDING() then SOME(binding.bindingExp); | |
| 284 | 6747 | case TYPED_BINDING() then SOME(binding.bindingExp); | |
| 285 | 152 | case FLAT_BINDING() then SOME(binding.bindingExp); | |
| 286 | else NONE(); | ||
| 287 | end match; | ||
| 288 | end getExpOpt; | ||
| 289 | |||
| 290 | function setExp | ||
| 291 | input Expression exp; | ||
| 292 | input output Binding binding; | ||
| 293 | algorithm | ||
| 294 | () := match binding | ||
| 295 | case UNTYPED_BINDING() | ||
| 296 | algorithm | ||
| 297 | ✗ | binding.bindingExp := exp; | |
| 298 | then | ||
| 299 | (); | ||
| 300 | |||
| 301 | case TYPED_BINDING() | ||
| 302 | algorithm | ||
| 303 | 22875 | binding.bindingExp := exp; | |
| 304 | then | ||
| 305 | (); | ||
| 306 | |||
| 307 | case FLAT_BINDING() | ||
| 308 | algorithm | ||
| 309 | 1870 | binding.bindingExp := exp; | |
| 310 | then | ||
| 311 | (); | ||
| 312 | |||
| 313 | end match; | ||
| 314 | end setExp; | ||
| 315 | |||
| 316 | function isRecordExp | ||
| 317 | input Binding binding; | ||
| 318 | output Boolean isRecordExp; | ||
| 319 | algorithm | ||
| 320 | isRecordExp := match binding | ||
| 321 | ✗ | case TYPED_BINDING() then Expression.isRecord(binding.bindingExp); | |
| 322 | else false; | ||
| 323 | end match; | ||
| 324 | end isRecordExp; | ||
| 325 | |||
| 326 | function isCrefExp | ||
| 327 | input Binding binding; | ||
| 328 | output Boolean isCref; | ||
| 329 | algorithm | ||
| 330 | isCref := match binding | ||
| 331 | ✗ | case TYPED_BINDING() then Expression.isCref(binding.bindingExp); | |
| 332 | else false; | ||
| 333 | end match; | ||
| 334 | end isCrefExp; | ||
| 335 | |||
| 336 | function recordFieldBinding | ||
| 337 | input InstNode fieldNode; | ||
| 338 | input Binding recordBinding; | ||
| 339 | output Binding fieldBinding = recordBinding; | ||
| 340 | protected | ||
| 341 | Expression exp; | ||
| 342 | Type ty; | ||
| 343 | Variability var; | ||
| 344 | Purity purity; | ||
| 345 | String field_name = InstNode.name(fieldNode); | ||
| 346 | algorithm | ||
| 347 | fieldBinding := match fieldBinding | ||
| 348 | case UNTYPED_BINDING() | ||
| 349 | algorithm | ||
| 350 | ✗ | fieldBinding.bindingExp := Expression.recordElement(field_name, fieldBinding.bindingExp); | |
| 351 | then | ||
| 352 | fieldBinding; | ||
| 353 | |||
| 354 | case TYPED_BINDING() | ||
| 355 | algorithm | ||
| 356 | 26 | exp := Expression.recordElement(field_name, fieldBinding.bindingExp); | |
| 357 | 26 | ty := Expression.typeOf(exp); | |
| 358 | 26 | purity := Expression.purity(exp); | |
| 359 | 26 | var := Expression.variability(exp); | |
| 360 | 26 | then | |
| 361 | TYPED_BINDING(exp, ty, var, purity, fieldBinding.eachType, fieldBinding.evalState, | ||
| 362 | fieldBinding.isFlattened, fieldBinding.source, fieldBinding.confidence, fieldBinding.info); | ||
| 363 | |||
| 364 | case FLAT_BINDING() | ||
| 365 | algorithm | ||
| 366 | ✗ | exp := Expression.recordElement(field_name, fieldBinding.bindingExp); | |
| 367 | ✗ | var := Expression.variability(exp); | |
| 368 | ✗ | then | |
| 369 | FLAT_BINDING(exp, var, fieldBinding.source, fieldBinding.confidence); | ||
| 370 | |||
| 371 | case CEVAL_BINDING() | ||
| 372 | algorithm | ||
| 373 | ✗ | fieldBinding.bindingExp := Expression.recordElement(field_name, fieldBinding.bindingExp); | |
| 374 | then | ||
| 375 | fieldBinding; | ||
| 376 | |||
| 377 | end match; | ||
| 378 | end recordFieldBinding; | ||
| 379 | |||
| 380 | function variability | ||
| 381 | input Binding binding; | ||
| 382 | output Variability var; | ||
| 383 | algorithm | ||
| 384 | var := match binding | ||
| 385 | 842559 | case TYPED_BINDING() then binding.variability; | |
| 386 | 977 | case FLAT_BINDING() then binding.variability; | |
| 387 | else | ||
| 388 | algorithm | ||
| 389 | ✗ | Error.terminate(getInstanceName() + " got unknown binding", sourceInfo()); | |
| 390 | ✗ | then | |
| 391 | fail(); | ||
| 392 | end match; | ||
| 393 | end variability; | ||
| 394 | |||
| 395 | function setVariability | ||
| 396 | input Variability var; | ||
| 397 | input output Binding binding; | ||
| 398 | algorithm | ||
| 399 | () := match binding | ||
| 400 | ✗ | case TYPED_BINDING() algorithm binding.variability := var; then (); | |
| 401 | ✗ | case FLAT_BINDING() algorithm binding.variability := var; then (); | |
| 402 | else (); | ||
| 403 | end match; | ||
| 404 | end setVariability; | ||
| 405 | |||
| 406 | function purity | ||
| 407 | input Binding binding; | ||
| 408 | output Purity purity; | ||
| 409 | algorithm | ||
| 410 | purity := match binding | ||
| 411 | 17 | case TYPED_BINDING() then binding.purity; | |
| 412 | else Purity.PURE; | ||
| 413 | end match; | ||
| 414 | end purity; | ||
| 415 | |||
| 416 | function getInfo | ||
| 417 | input Binding binding; | ||
| 418 | output SourceInfo info; | ||
| 419 | algorithm | ||
| 420 | info := match binding | ||
| 421 | ✗ | case RAW_BINDING() then binding.info; | |
| 422 | 827963 | case UNTYPED_BINDING() then binding.info; | |
| 423 | 1618012 | case TYPED_BINDING() then binding.info; | |
| 424 | else Absyn.dummyInfo; | ||
| 425 | end match; | ||
| 426 | end getInfo; | ||
| 427 | |||
| 428 | function getType | ||
| 429 | input Binding binding; | ||
| 430 | output Type ty; | ||
| 431 | algorithm | ||
| 432 | ty := match binding | ||
| 433 | case UNBOUND() then Type.UNKNOWN(); | ||
| 434 | case RAW_BINDING() then Type.UNKNOWN(); | ||
| 435 | case UNTYPED_BINDING() then Type.UNKNOWN(); | ||
| 436 | 13575 | case TYPED_BINDING() then binding.bindingType; | |
| 437 | 280 | case FLAT_BINDING() then Expression.typeOf(binding.bindingExp); | |
| 438 | ✗ | case CEVAL_BINDING() then Expression.typeOf(binding.bindingExp); | |
| 439 | ✗ | case INVALID_BINDING() then getType(binding.binding); | |
| 440 | end match; | ||
| 441 | end getType; | ||
| 442 | |||
| 443 | function isEach | ||
| 444 | input Binding binding; | ||
| 445 | output Boolean isEach; | ||
| 446 | algorithm | ||
| 447 | isEach := match binding | ||
| 448 | 25 | case RAW_BINDING() then binding.eachType == EachType.EACH; | |
| 449 | ✗ | case UNTYPED_BINDING() then binding.eachType == EachType.EACH; | |
| 450 | ✗ | case TYPED_BINDING() then binding.eachType == EachType.EACH; | |
| 451 | else false; | ||
| 452 | end match; | ||
| 453 | end isEach; | ||
| 454 | |||
| 455 | function isTyped | ||
| 456 | input Binding binding; | ||
| 457 | output Boolean isTyped; | ||
| 458 | algorithm | ||
| 459 | isTyped := match binding | ||
| 460 | case TYPED_BINDING() then true; | ||
| 461 | case FLAT_BINDING() then true; | ||
| 462 | else false; | ||
| 463 | end match; | ||
| 464 | end isTyped; | ||
| 465 | |||
| 466 | function toString | ||
| 467 | input Binding binding; | ||
| 468 | input String prefix = ""; | ||
| 469 | output String string; | ||
| 470 | algorithm | ||
| 471 | string := match binding | ||
| 472 | case UNBOUND() then ""; | ||
| 473 | 20 | case RAW_BINDING() then prefix + Dump.printExpStr(binding.bindingExp); | |
| 474 | 5 | case UNTYPED_BINDING() then prefix + Expression.toString(binding.bindingExp); | |
| 475 | 13 | case TYPED_BINDING() then prefix + Expression.toString(binding.bindingExp); | |
| 476 | 1 | case FLAT_BINDING() then prefix + Expression.toString(binding.bindingExp); | |
| 477 | ✗ | case CEVAL_BINDING() then prefix + Expression.toString(binding.bindingExp); | |
| 478 | ✗ | case INVALID_BINDING() then toString(binding.binding, prefix); | |
| 479 | else ""; | ||
| 480 | end match; | ||
| 481 | end toString; | ||
| 482 | |||
| 483 | function toFlatString | ||
| 484 | input Binding binding; | ||
| 485 | input BaseModelica.OutputFormat format; | ||
| 486 | input String prefix = ""; | ||
| 487 | output String string; | ||
| 488 | algorithm | ||
| 489 | string := match binding | ||
| 490 | case UNBOUND() then ""; | ||
| 491 | ✗ | case RAW_BINDING() then prefix + Dump.printExpStr(binding.bindingExp); | |
| 492 | ✗ | case UNTYPED_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format); | |
| 493 | 68 | case TYPED_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format); | |
| 494 | 145 | case FLAT_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format); | |
| 495 | ✗ | case CEVAL_BINDING() then prefix + Expression.toFlatString(binding.bindingExp, format); | |
| 496 | ✗ | case INVALID_BINDING() then toFlatString(binding.binding, format, prefix); | |
| 497 | else ""; | ||
| 498 | end match; | ||
| 499 | |||
| 500 |
2/2✓ Branch 0 taken 310 times.
✓ Branch 1 taken 3 times.
|
313 | if format.showConfidence then |
| 501 | 3 | string := string + " /* confidence = " + String(actualConfidence(binding)) + "*/"; | |
| 502 | end if; | ||
| 503 | end toFlatString; | ||
| 504 | |||
| 505 | function toDebugString | ||
| 506 | input Binding binding; | ||
| 507 | output String string; | ||
| 508 | algorithm | ||
| 509 | string := match binding | ||
| 510 | case WILD() then "WILD"; | ||
| 511 | case UNBOUND() then "UNBOUND"; | ||
| 512 | case RAW_BINDING() then "RAW_BINDING"; | ||
| 513 | case UNTYPED_BINDING() then "UNTYPED_BINDING"; | ||
| 514 | case TYPED_BINDING() then "TYPED_BINDING"; | ||
| 515 | case FLAT_BINDING() then "FLAT_BINDING"; | ||
| 516 | case CEVAL_BINDING() then "CEVAL_BINDING"; | ||
| 517 | case INVALID_BINDING() then "INVALID_BINDING"; | ||
| 518 | else "UNKNOWN"; | ||
| 519 | end match; | ||
| 520 | end toDebugString; | ||
| 521 | |||
| 522 | function isEqual | ||
| 523 | input Binding binding1; | ||
| 524 | input Binding binding2; | ||
| 525 | output Boolean equal; | ||
| 526 | algorithm | ||
| 527 | equal := match (binding1, binding2) | ||
| 528 | case (UNBOUND(), UNBOUND()) then true; | ||
| 529 | |||
| 530 | // TODO: Handle propagated dims. | ||
| 531 | case (RAW_BINDING(), RAW_BINDING()) | ||
| 532 | 32551 | then AbsynUtil.expEqual(binding1.bindingExp, binding2.bindingExp); | |
| 533 | |||
| 534 | case (UNTYPED_BINDING(), UNTYPED_BINDING()) | ||
| 535 | ✗ | then Expression.isEqual(binding1.bindingExp, binding2.bindingExp); | |
| 536 | |||
| 537 | case (TYPED_BINDING(), TYPED_BINDING()) | ||
| 538 | 1 | then Expression.isEqual(binding1.bindingExp, binding2.bindingExp); | |
| 539 | |||
| 540 | else false; | ||
| 541 | end match; | ||
| 542 | end isEqual; | ||
| 543 | |||
| 544 | function toDAE | ||
| 545 | input Binding binding; | ||
| 546 | output DAE.Binding outBinding; | ||
| 547 | algorithm | ||
| 548 | outBinding := match binding | ||
| 549 | case WILD() then DAE.UNBOUND(); | ||
| 550 | case UNBOUND() then DAE.UNBOUND(); | ||
| 551 | 24727 | case TYPED_BINDING() then makeDAEBinding(binding.bindingExp, binding.variability); | |
| 552 | ✗ | case FLAT_BINDING() then makeDAEBinding(binding.bindingExp, binding.variability); | |
| 553 | case CEVAL_BINDING() then DAE.UNBOUND(); | ||
| 554 | case INVALID_BINDING() | ||
| 555 | algorithm | ||
| 556 | ✗ | Error.addTotalMessages(binding.errors); | |
| 557 | ✗ | then | |
| 558 | fail(); | ||
| 559 | else | ||
| 560 | algorithm | ||
| 561 | ✗ | Error.terminate(getInstanceName() + " got untyped binding", sourceInfo()); | |
| 562 | ✗ | then | |
| 563 | fail(); | ||
| 564 | end match; | ||
| 565 | end toDAE; | ||
| 566 | |||
| 567 | function makeDAEBinding | ||
| 568 | input Expression exp; | ||
| 569 | input Variability var; | ||
| 570 | output DAE.Binding binding; | ||
| 571 | algorithm | ||
| 572 | 24727 | binding := DAE.EQBOUND( | |
| 573 | Expression.toDAE(exp), | ||
| 574 | NONE(), | ||
| 575 | Variability.variabilityToDAEConst(var), | ||
| 576 | DAE.BINDING_FROM_DEFAULT_VALUE() // TODO: revise this. | ||
| 577 | ); | ||
| 578 | end makeDAEBinding; | ||
| 579 | |||
| 580 | function toDAEExp | ||
| 581 | input Binding binding; | ||
| 582 | output Option<DAE.Exp> bindingExp; | ||
| 583 | algorithm | ||
| 584 | bindingExp := match binding | ||
| 585 | case UNBOUND() then NONE(); | ||
| 586 | 75030 | case TYPED_BINDING() then SOME(Expression.toDAE(binding.bindingExp)); | |
| 587 | 85346 | case FLAT_BINDING() then SOME(Expression.toDAE(binding.bindingExp)); | |
| 588 | case CEVAL_BINDING() then NONE(); | ||
| 589 | else | ||
| 590 | algorithm | ||
| 591 | ✗ | Error.terminate(getInstanceName() + " got untyped binding", sourceInfo()); | |
| 592 | ✗ | then | |
| 593 | fail(); | ||
| 594 | end match; | ||
| 595 | end toDAEExp; | ||
| 596 | |||
| 597 | function applyExp | ||
| 598 | input Binding binding; | ||
| 599 | input ApplyFn fn; | ||
| 600 | |||
| 601 | partial function ApplyFn | ||
| 602 | input Expression exp; | ||
| 603 | end ApplyFn; | ||
| 604 | algorithm | ||
| 605 | () := match binding | ||
| 606 | ✗ | case UNTYPED_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then (); | |
| 607 | ✗ | case TYPED_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then (); | |
| 608 | ✗ | case FLAT_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then (); | |
| 609 | ✗ | case CEVAL_BINDING() algorithm Expression.apply(binding.bindingExp, fn); then (); | |
| 610 | else (); | ||
| 611 | end match; | ||
| 612 | end applyExp; | ||
| 613 | |||
| 614 | function applyExpShallow | ||
| 615 | input Binding binding; | ||
| 616 | input ApplyFn fn; | ||
| 617 | |||
| 618 | partial function ApplyFn | ||
| 619 | input Expression exp; | ||
| 620 | end ApplyFn; | ||
| 621 | algorithm | ||
| 622 | () := match binding | ||
| 623 | ✗ | case UNTYPED_BINDING() algorithm fn(binding.bindingExp); then (); | |
| 624 |
1/2✓ Branch 0 taken 549476 times.
✗ Branch 1 not taken.
|
549476 | case TYPED_BINDING() algorithm fn(binding.bindingExp); then (); |
| 625 |
1/2✓ Branch 0 taken 53285 times.
✗ Branch 1 not taken.
|
53285 | case FLAT_BINDING() algorithm fn(binding.bindingExp); then (); |
| 626 | ✗ | case CEVAL_BINDING() algorithm fn(binding.bindingExp); then (); | |
| 627 | else (); | ||
| 628 | end match; | ||
| 629 | end applyExpShallow; | ||
| 630 | |||
| 631 | function mapExp | ||
| 632 | input output Binding binding; | ||
| 633 | input MapFunc mapFn; | ||
| 634 | |||
| 635 | partial function MapFunc | ||
| 636 | input output Expression exp; | ||
| 637 | end MapFunc; | ||
| 638 | protected | ||
| 639 | Expression e1, e2; | ||
| 640 | algorithm | ||
| 641 | () := match binding | ||
| 642 | case UNTYPED_BINDING(bindingExp = e1) | ||
| 643 | algorithm | ||
| 644 | 1 | e2 := Expression.map(e1, mapFn); | |
| 645 | |||
| 646 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1 | if not referenceEq(e1, e2) then |
| 647 | 1 | binding.bindingExp := e2; | |
| 648 | end if; | ||
| 649 | then | ||
| 650 | (); | ||
| 651 | |||
| 652 | case TYPED_BINDING(bindingExp = e1) | ||
| 653 | algorithm | ||
| 654 | 186893 | e2 := Expression.map(e1, mapFn); | |
| 655 | |||
| 656 |
2/2✓ Branch 0 taken 37355 times.
✓ Branch 1 taken 149538 times.
|
186893 | if not referenceEq(e1, e2) then |
| 657 | 37355 | binding.bindingExp := e2; | |
| 658 | end if; | ||
| 659 | then | ||
| 660 | (); | ||
| 661 | |||
| 662 | case FLAT_BINDING(bindingExp = e1) | ||
| 663 | algorithm | ||
| 664 | 59885 | e2 := Expression.map(e1, mapFn); | |
| 665 | |||
| 666 |
2/2✓ Branch 0 taken 6136 times.
✓ Branch 1 taken 53749 times.
|
59885 | if not referenceEq(e1, e2) then |
| 667 | 6136 | binding.bindingExp := e2; | |
| 668 | end if; | ||
| 669 | then | ||
| 670 | (); | ||
| 671 | |||
| 672 | case CEVAL_BINDING(bindingExp = e1) | ||
| 673 | algorithm | ||
| 674 | ✗ | e2 := Expression.map(e1, mapFn); | |
| 675 | |||
| 676 | ✗ | if not referenceEq(e1, e2) then | |
| 677 | ✗ | binding.bindingExp := e2; | |
| 678 | end if; | ||
| 679 | then | ||
| 680 | (); | ||
| 681 | |||
| 682 | else (); | ||
| 683 | end match; | ||
| 684 | end mapExp; | ||
| 685 | |||
| 686 | function mapExpShallow | ||
| 687 | input output Binding binding; | ||
| 688 | input MapFunc mapFn; | ||
| 689 | |||
| 690 | partial function MapFunc | ||
| 691 | input output Expression exp; | ||
| 692 | end MapFunc; | ||
| 693 | protected | ||
| 694 | Expression e1, e2; | ||
| 695 | algorithm | ||
| 696 | () := match binding | ||
| 697 | case UNTYPED_BINDING(bindingExp = e1) | ||
| 698 | algorithm | ||
| 699 | ✗ | e2 := mapFn(e1); | |
| 700 | |||
| 701 | ✗ | if not referenceEq(e1, e2) then | |
| 702 | ✗ | binding.bindingExp := e2; | |
| 703 | end if; | ||
| 704 | then | ||
| 705 | (); | ||
| 706 | |||
| 707 | case TYPED_BINDING(bindingExp = e1) | ||
| 708 | algorithm | ||
| 709 |
2/2✓ Branch 0 taken 867052 times.
✓ Branch 1 taken 1147382 times.
|
2014434 | e2 := mapFn(e1); |
| 710 | |||
| 711 |
2/2✓ Branch 0 taken 110482 times.
✓ Branch 1 taken 1903952 times.
|
2014434 | if not referenceEq(e1, e2) then |
| 712 | 110482 | binding.bindingExp := e2; | |
| 713 | end if; | ||
| 714 | then | ||
| 715 | (); | ||
| 716 | |||
| 717 | case FLAT_BINDING(bindingExp = e1) | ||
| 718 | algorithm | ||
| 719 |
2/2✓ Branch 0 taken 12378 times.
✓ Branch 1 taken 677803 times.
|
690181 | e2 := mapFn(e1); |
| 720 | |||
| 721 |
2/2✓ Branch 0 taken 16599 times.
✓ Branch 1 taken 673582 times.
|
690181 | if not referenceEq(e1, e2) then |
| 722 | 16599 | binding.bindingExp := e2; | |
| 723 | end if; | ||
| 724 | then | ||
| 725 | (); | ||
| 726 | |||
| 727 | case CEVAL_BINDING(bindingExp = e1) | ||
| 728 | algorithm | ||
| 729 | ✗ | e2 := mapFn(e1); | |
| 730 | |||
| 731 | ✗ | if not referenceEq(e1, e2) then | |
| 732 | ✗ | binding.bindingExp := e2; | |
| 733 | end if; | ||
| 734 | then | ||
| 735 | (); | ||
| 736 | |||
| 737 | else (); | ||
| 738 | end match; | ||
| 739 | end mapExpShallow; | ||
| 740 | |||
| 741 | function foldExp<ArgT> | ||
| 742 | input Binding binding; | ||
| 743 | input FoldFunc foldFn; | ||
| 744 | input output ArgT arg; | ||
| 745 | |||
| 746 | partial function FoldFunc | ||
| 747 | input Expression exp; | ||
| 748 | input output ArgT arg; | ||
| 749 | end FoldFunc; | ||
| 750 | algorithm | ||
| 751 | arg := match binding | ||
| 752 | ✗ | case UNTYPED_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg); | |
| 753 | 498392 | case TYPED_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg); | |
| 754 | ✗ | case FLAT_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg); | |
| 755 | ✗ | case CEVAL_BINDING() then Expression.fold(binding.bindingExp, foldFn, arg); | |
| 756 | else arg; | ||
| 757 | end match; | ||
| 758 | end foldExp; | ||
| 759 | |||
| 760 | function containsExp | ||
| 761 | input Binding binding; | ||
| 762 | input PredFunc predFn; | ||
| 763 | output Boolean res; | ||
| 764 | |||
| 765 | partial function PredFunc | ||
| 766 | input Expression exp; | ||
| 767 | output Boolean res; | ||
| 768 | end PredFunc; | ||
| 769 | algorithm | ||
| 770 | res := match binding | ||
| 771 | ✗ | case UNTYPED_BINDING() then Expression.contains(binding.bindingExp, predFn); | |
| 772 | ✗ | case TYPED_BINDING() then Expression.contains(binding.bindingExp, predFn); | |
| 773 | ✗ | case FLAT_BINDING() then Expression.contains(binding.bindingExp, predFn); | |
| 774 | ✗ | case CEVAL_BINDING() then Expression.contains(binding.bindingExp, predFn); | |
| 775 | else false; | ||
| 776 | end match; | ||
| 777 | end containsExp; | ||
| 778 | |||
| 779 | function update | ||
| 780 | input output Binding binding; | ||
| 781 | input Expression exp; | ||
| 782 | algorithm | ||
| 783 | binding := match binding | ||
| 784 | |||
| 785 | case WILD() | ||
| 786 | ✗ | then TYPED_BINDING( | |
| 787 | bindingExp = exp, | ||
| 788 | bindingType = Expression.typeOf(exp), | ||
| 789 | variability = Expression.variability(exp), | ||
| 790 | purity = Expression.purity(exp), | ||
| 791 | eachType = EachType.NOT_EACH, | ||
| 792 | evalState = if Expression.isConstNumber(exp) | ||
| 793 | then Mutable.create(EvalState.EVALUATED) | ||
| 794 | else Mutable.create(EvalState.NOT_EVALUATED), | ||
| 795 | isFlattened = true, | ||
| 796 | source = Source.BINDING, | ||
| 797 | confidence = NO_CONFIDENCE, | ||
| 798 | info = sourceInfo() | ||
| 799 | ); | ||
| 800 | |||
| 801 | case UNBOUND() | ||
| 802 |
2/2✓ Branch 1 taken 273 times.
✓ Branch 2 taken 1593 times.
|
1866 | then TYPED_BINDING( |
| 803 | bindingExp = exp, | ||
| 804 | bindingType = Expression.typeOf(exp), | ||
| 805 | variability = Expression.variability(exp), | ||
| 806 | purity = Expression.purity(exp), | ||
| 807 | eachType = EachType.NOT_EACH, | ||
| 808 | evalState = if Expression.isConstNumber(exp) | ||
| 809 | then Mutable.create(EvalState.EVALUATED) | ||
| 810 | else Mutable.create(EvalState.NOT_EVALUATED), | ||
| 811 | isFlattened = true, | ||
| 812 | source = Source.BINDING, | ||
| 813 | confidence = NO_CONFIDENCE, | ||
| 814 | info = sourceInfo() | ||
| 815 | ); | ||
| 816 | |||
| 817 | case UNTYPED_BINDING() algorithm | ||
| 818 | ✗ | binding.bindingExp := exp; | |
| 819 | then binding; | ||
| 820 | |||
| 821 | case TYPED_BINDING() algorithm | ||
| 822 | 155 | binding.bindingExp := exp; | |
| 823 | then binding; | ||
| 824 | |||
| 825 | case FLAT_BINDING() algorithm | ||
| 826 | 9 | binding.bindingExp := exp; | |
| 827 | then binding; | ||
| 828 | |||
| 829 | case CEVAL_BINDING() algorithm | ||
| 830 | ✗ | binding.bindingExp := exp; | |
| 831 | then binding; | ||
| 832 | |||
| 833 | case INVALID_BINDING() algorithm | ||
| 834 | ✗ | binding.binding := update(binding.binding, exp); | |
| 835 | then binding; | ||
| 836 | |||
| 837 | case RAW_BINDING() algorithm | ||
| 838 | ✗ | Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because a raw binding cannot be updated."}); | |
| 839 | ✗ | then fail(); | |
| 840 | |||
| 841 | else algorithm | ||
| 842 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, {getInstanceName() + " failed."}); | |
| 843 | ✗ | then fail(); | |
| 844 | |||
| 845 | end match; | ||
| 846 | end update; | ||
| 847 | |||
| 848 | function setAttr | ||
| 849 | "sets a specific attribute value and adds it if it does not exist" | ||
| 850 | input output list<tuple<String, Binding>> ty_attr; | ||
| 851 | input String attr_name; | ||
| 852 | input Binding attr_value; | ||
| 853 | algorithm | ||
| 854 | ty_attr := match ty_attr | ||
| 855 | local | ||
| 856 | tuple<String, Binding> at; | ||
| 857 | list<tuple<String, Binding>> rest; | ||
| 858 | String name; | ||
| 859 | ✗ | case (name, _ ) :: rest guard(name == attr_name) then (attr_name, attr_value) :: rest; | |
| 860 | 132 | case at :: rest then at :: setAttr(rest, attr_name, attr_value); | |
| 861 | 118 | case {} then {(attr_name, attr_value)}; | |
| 862 | end match; | ||
| 863 | end setAttr; | ||
| 864 | |||
| 865 | function propagate | ||
| 866 | "Propagates a modifier through an element, given as a list of split subscript." | ||
| 867 | input output Binding binding; | ||
| 868 | input list<Subscript> subs; | ||
| 869 | algorithm | ||
| 870 | () := match binding | ||
| 871 | case RAW_BINDING() | ||
| 872 | algorithm | ||
| 873 | 1827186 | binding.subs := listAppend(binding.subs, subs); | |
| 874 | |||
| 875 |
1/2✓ Branch 0 taken 1827186 times.
✗ Branch 1 not taken.
|
1827186 | if binding.source <> Source.TYPE then |
| 876 | 1827186 | binding.source := Source.MODIFIER; | |
| 877 | end if; | ||
| 878 | then | ||
| 879 | (); | ||
| 880 | |||
| 881 | else (); | ||
| 882 | end match; | ||
| 883 | end propagate; | ||
| 884 | |||
| 885 | function unpropagate | ||
| 886 | input output Binding binding; | ||
| 887 | input InstNode node; | ||
| 888 | algorithm | ||
| 889 | () := match binding | ||
| 890 | case RAW_BINDING() | ||
| 891 | algorithm | ||
| 892 |
4/6✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25 times.
|
75 | binding.subs := list(s for s guard not Subscript.isSplitFromOrigin(s, node) in binding.subs); |
| 893 | then | ||
| 894 | (); | ||
| 895 | |||
| 896 | else (); | ||
| 897 | end match; | ||
| 898 | end unpropagate; | ||
| 899 | |||
| 900 | function source | ||
| 901 | input Binding binding; | ||
| 902 | output Source source; | ||
| 903 | algorithm | ||
| 904 | source := match binding | ||
| 905 | ✗ | case RAW_BINDING() then binding.source; | |
| 906 | ✗ | case UNTYPED_BINDING() then binding.source; | |
| 907 | 215410 | case TYPED_BINDING() then binding.source; | |
| 908 | 34013 | case FLAT_BINDING() then binding.source; | |
| 909 | else Source.BINDING; | ||
| 910 | end match; | ||
| 911 | end source; | ||
| 912 | |||
| 913 | function setSource | ||
| 914 | input Source source; | ||
| 915 | input output Binding binding; | ||
| 916 | algorithm | ||
| 917 | () := match binding | ||
| 918 | 1293580 | case RAW_BINDING() algorithm binding.source := source; then (); | |
| 919 | ✗ | case UNTYPED_BINDING() algorithm binding.source := source; then (); | |
| 920 | ✗ | case TYPED_BINDING() algorithm binding.source := source; then (); | |
| 921 | ✗ | case FLAT_BINDING() algorithm binding.source := source; then (); | |
| 922 | else (); | ||
| 923 | end match; | ||
| 924 | end setSource; | ||
| 925 | |||
| 926 | function setConfidence | ||
| 927 | input Integer confidence; | ||
| 928 | input output Binding binding; | ||
| 929 | algorithm | ||
| 930 | () := match binding | ||
| 931 | 1293580 | case RAW_BINDING() algorithm binding.confidence := confidence; then (); | |
| 932 | ✗ | case UNTYPED_BINDING() algorithm binding.confidence := confidence; then (); | |
| 933 | ✗ | case TYPED_BINDING() algorithm binding.confidence := confidence; then (); | |
| 934 | ✗ | case FLAT_BINDING() algorithm binding.confidence := confidence; then (); | |
| 935 | else (); | ||
| 936 | end match; | ||
| 937 | end setConfidence; | ||
| 938 | |||
| 939 | function makeUntyped | ||
| 940 | input Expression exp; | ||
| 941 | input InstNode scope; | ||
| 942 | input EachType eachType; | ||
| 943 | input Source source; | ||
| 944 | input SourceInfo info; | ||
| 945 | input Integer confidence = NO_CONFIDENCE; | ||
| 946 | output Binding binding; | ||
| 947 | algorithm | ||
| 948 | 607 | binding := UNTYPED_BINDING(exp, false, InstNode.scopeRef(scope), eachType, source, confidence, info); | |
| 949 | end makeUntyped; | ||
| 950 | |||
| 951 | function makeTyped | ||
| 952 | input Expression exp; | ||
| 953 | input EachType eachType; | ||
| 954 | input Source source; | ||
| 955 | input SourceInfo info; | ||
| 956 | input EvalState state = EvalState.NOT_EVALUATED; | ||
| 957 | input Integer confidence = NO_CONFIDENCE; | ||
| 958 | output Binding binding; | ||
| 959 | algorithm | ||
| 960 | 66 | binding := TYPED_BINDING(exp, Expression.typeOf(exp), | |
| 961 | Expression.variability(exp), Expression.purity(exp), | ||
| 962 | eachType, Mutable.create(state), false, source, confidence, info); | ||
| 963 | end makeTyped; | ||
| 964 | |||
| 965 | function makeFlat | ||
| 966 | input Expression exp; | ||
| 967 | input Variability var; | ||
| 968 | input Source source; | ||
| 969 | input Integer confidence = NO_CONFIDENCE; | ||
| 970 | output Binding binding; | ||
| 971 | algorithm | ||
| 972 | 364751 | binding := FLAT_BINDING(exp, var, source, confidence); | |
| 973 | end makeFlat; | ||
| 974 | |||
| 975 | function isEvaluated | ||
| 976 | input Binding binding; | ||
| 977 | output Boolean evaluated; | ||
| 978 | algorithm | ||
| 979 | evaluated := match binding | ||
| 980 | case TYPED_BINDING() | ||
| 981 | 36 | then Mutable.access(binding.evalState) == EvalState.EVALUATED; | |
| 982 | case CEVAL_BINDING() then true; | ||
| 983 | else false; | ||
| 984 | end match; | ||
| 985 | end isEvaluated; | ||
| 986 | |||
| 987 | function hasTypeOrigin | ||
| 988 | input Binding binding; | ||
| 989 | output Boolean res; | ||
| 990 | algorithm | ||
| 991 | res := match binding | ||
| 992 | case RAW_BINDING() | ||
| 993 | guard not listEmpty(binding.subs) | ||
| 994 | 32 | then Subscript.isSplitClassProxy(listHead(binding.subs)); | |
| 995 | |||
| 996 | else false; | ||
| 997 | end match; | ||
| 998 | end hasTypeOrigin; | ||
| 999 | |||
| 1000 | function expandEach | ||
| 1001 | "Expands the raw binding with each for a component x into | ||
| 1002 | fill(binding, size(x, 1), size(x, 2), ...)" | ||
| 1003 | input output Binding binding; | ||
| 1004 | input InstNode node; | ||
| 1005 | protected | ||
| 1006 | list<Absyn.Exp> args; | ||
| 1007 | Absyn.Exp node_exp; | ||
| 1008 | constant Absyn.ComponentRef size_name = Absyn.ComponentRef.CREF_IDENT("size", {}); | ||
| 1009 | constant Absyn.ComponentRef fill_name = Absyn.ComponentRef.CREF_IDENT("fill", {}); | ||
| 1010 | algorithm | ||
| 1011 | () := match binding | ||
| 1012 | case RAW_BINDING(eachType = EachType.EACH) | ||
| 1013 | algorithm | ||
| 1014 | ✗ | node_exp := Absyn.Exp.CREF(Absyn.ComponentRef.CREF_IDENT(InstNode.name(node), {})); | |
| 1015 | args := {}; | ||
| 1016 | |||
| 1017 | ✗ | for i in InstNode.dimensionCount(node):-1:1 loop | |
| 1018 | ✗ | args := AbsynUtil.makeCall(size_name, {node_exp, Absyn.Exp.INTEGER(i)}) :: args; | |
| 1019 | end for; | ||
| 1020 | |||
| 1021 | ✗ | args := binding.bindingExp :: args; | |
| 1022 | ✗ | binding.bindingExp := AbsynUtil.makeCall(fill_name, args); | |
| 1023 | then | ||
| 1024 | (); | ||
| 1025 | |||
| 1026 | else (); | ||
| 1027 | end match; | ||
| 1028 | end expandEach; | ||
| 1029 | |||
| 1030 | function isClockOrSampleFunction | ||
| 1031 | input Binding binding; | ||
| 1032 | output Boolean b; | ||
| 1033 | algorithm | ||
| 1034 | b := match getExpOpt(binding) | ||
| 1035 | local | ||
| 1036 | Expression exp; | ||
| 1037 | 2993 | case SOME(exp) then Expression.isClockOrSampleFunction(exp); | |
| 1038 | else false; | ||
| 1039 | end match; | ||
| 1040 | end isClockOrSampleFunction; | ||
| 1041 | |||
| 1042 | function confidence | ||
| 1043 | "Returns the confidence of a binding, i.e. on what level of the instance | ||
| 1044 | tree it was set." | ||
| 1045 | input Binding binding; | ||
| 1046 | output Integer confidence; | ||
| 1047 | algorithm | ||
| 1048 | confidence := match binding | ||
| 1049 | ✗ | case RAW_BINDING() then binding.confidence; | |
| 1050 | ✗ | case UNTYPED_BINDING() then binding.confidence; | |
| 1051 | 199674 | case TYPED_BINDING() then binding.confidence; | |
| 1052 | 34017 | case FLAT_BINDING() then binding.confidence; | |
| 1053 | else NO_CONFIDENCE; | ||
| 1054 | end match; | ||
| 1055 | end confidence; | ||
| 1056 | |||
| 1057 | function isFromType | ||
| 1058 | "Returns true if the binding is an attribute modifier of a type rather than | ||
| 1059 | of a component." | ||
| 1060 | input Binding binding; | ||
| 1061 | output Boolean fromType = source(binding) == Source.TYPE; | ||
| 1062 | end isFromType; | ||
| 1063 | |||
| 1064 | function compareStartConfidence | ||
| 1065 | "Compares two start attributes by MLS 8.6.2 priority: a start set on a | ||
| 1066 | component beats one set by its type, then the lower actual confidence wins, | ||
| 1067 | then the lower raw confidence. Negative if b1 is stronger, 0 if tied." | ||
| 1068 | input Binding b1; | ||
| 1069 | input Binding b2; | ||
| 1070 | output Integer cmp; | ||
| 1071 | algorithm | ||
| 1072 |
2/2✓ Branch 2 taken 11 times.
✓ Branch 3 taken 28 times.
|
39 | if isFromType(b1) <> isFromType(b2) then |
| 1073 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 10 times.
|
11 | cmp := if isFromType(b1) then 1 else -1; |
| 1074 | else | ||
| 1075 | 28 | cmp := actualConfidence(b1) - actualConfidence(b2); | |
| 1076 | |||
| 1077 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 21 times.
|
28 | if cmp == 0 then |
| 1078 | 21 | cmp := confidence(b1) - confidence(b2); | |
| 1079 | end if; | ||
| 1080 | end if; | ||
| 1081 | end compareStartConfidence; | ||
| 1082 | |||
| 1083 | function actualConfidence | ||
| 1084 | "Returns the actual confidence for a binding, which if the binding consists | ||
| 1085 | of a single parameter is the highest confidence (lowest number) of the | ||
| 1086 | binding itself and the actual confidence of the parameter's binding, as | ||
| 1087 | per 8.6.2. For any other kind of binding, and for the attribute modifiers | ||
| 1088 | of a type, the actual confidence is just the confidence stored in the | ||
| 1089 | binding." | ||
| 1090 | input Binding binding; | ||
| 1091 | output Integer conf = NO_CONFIDENCE; | ||
| 1092 | protected | ||
| 1093 | Binding b = binding; | ||
| 1094 | Expression exp; | ||
| 1095 | ComponentRef cref; | ||
| 1096 | InstNode node; | ||
| 1097 | Component comp; | ||
| 1098 | Variable var; | ||
| 1099 | algorithm | ||
| 1100 |
2/2✓ Branch 1 taken 60514 times.
✓ Branch 2 taken 12 times.
|
60526 | if isFromType(binding) then |
| 1101 | 12 | conf := confidence(binding); | |
| 1102 | 12 | return; | |
| 1103 | end if; | ||
| 1104 | |||
| 1105 |
2/2✓ Branch 1 taken 64134 times.
✓ Branch 2 taken 60514 times.
|
124648 | while hasExp(b) loop |
| 1106 | 64134 | conf := min(conf, confidence(b)); | |
| 1107 | 64134 | exp := getExp(b); | |
| 1108 | b := NFBinding.EMPTY_BINDING; | ||
| 1109 | |||
| 1110 | () := match exp | ||
| 1111 | case Expression.CREF() | ||
| 1112 | guard ComponentRef.isCref(exp.cref) | ||
| 1113 | algorithm | ||
| 1114 | 4112 | node := InstNode.resolveInner(ComponentRef.node(exp.cref)); | |
| 1115 | |||
| 1116 | () := match node | ||
| 1117 | // crefs lowered by the new backend point to variables, not components | ||
| 1118 | case InstNode.VAR_NODE() | ||
| 1119 | algorithm | ||
| 1120 | 57 | var := Pointer.access(PointerWeak.upgrade(node.varPointer)); | |
| 1121 | |||
| 1122 |
2/2✓ Branch 1 taken 51 times.
✓ Branch 2 taken 6 times.
|
57 | if Variable.variability(var) < Variability.DISCRETE then |
| 1123 | 51 | b := var.binding; | |
| 1124 | end if; | ||
| 1125 | then | ||
| 1126 | (); | ||
| 1127 | |||
| 1128 | else | ||
| 1129 | algorithm | ||
| 1130 |
1/2✓ Branch 1 taken 4055 times.
✗ Branch 2 not taken.
|
4055 | if InstNode.isComponent(node) then |
| 1131 | 4055 | comp := InstNode.component(node); | |
| 1132 | |||
| 1133 |
1/2✓ Branch 1 taken 4055 times.
✗ Branch 2 not taken.
|
4055 | if Component.variability(comp) < Variability.DISCRETE then |
| 1134 | 4055 | b := Component.getBinding(comp); | |
| 1135 | end if; | ||
| 1136 | end if; | ||
| 1137 | then | ||
| 1138 | (); | ||
| 1139 | end match; | ||
| 1140 | then | ||
| 1141 | (); | ||
| 1142 | |||
| 1143 | else (); | ||
| 1144 | end match; | ||
| 1145 | end while; | ||
| 1146 | end actualConfidence; | ||
| 1147 | |||
| 1148 | annotation(__OpenModelica_Interface="nf_frontend"); | ||
| 1149 | end NFBinding; | ||
| 1150 |