OMCompiler/Compiler/FrontEnd/ComponentReferenceBasics.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 ComponentReferenceBasics | ||
| 37 | " file: ComponentReferenceBasics.mo | ||
| 38 | package: ComponentReferenceBasics | ||
| 39 | description: Some stuff for ComponentRef datatypes | ||
| 40 | |||
| 41 | |||
| 42 | This file contains the module ComponentReferenceBasics, | ||
| 43 | which contains functions for ComponentRef." | ||
| 44 | |||
| 45 | // public imports | ||
| 46 | public import DAE; | ||
| 47 | |||
| 48 | // protected imports | ||
| 49 | protected import Config; | ||
| 50 | protected import ExpressionBasics; | ||
| 51 | protected import List; | ||
| 52 | protected import System; | ||
| 53 | protected import TypesDump; | ||
| 54 | |||
| 55 | public function crefDims " | ||
| 56 | function: crefDims | ||
| 57 | Return the all dimension (contained in the types) of a ComponentRef" | ||
| 58 | input DAE.ComponentRef inComponentRef; | ||
| 59 | output list<DAE.Dimension> outDimensionLst; | ||
| 60 | algorithm | ||
| 61 | outDimensionLst := match inComponentRef | ||
| 62 | local | ||
| 63 | list<DAE.Dimension> dims,res; | ||
| 64 | DAE.Type idType; | ||
| 65 | DAE.ComponentRef cr; | ||
| 66 | |||
| 67 | 2583843 | case DAE.CREF_IDENT(identType = idType) then TypesDump.getDimensions(idType); | |
| 68 | |||
| 69 | case DAE.CREF_QUAL(componentRef = cr, identType = idType) | ||
| 70 | algorithm | ||
| 71 | 5300809 | dims := TypesDump.getDimensions(idType); | |
| 72 | 5300809 | res := crefDims(cr); | |
| 73 | 5300809 | res := listAppend(dims,res); | |
| 74 | then | ||
| 75 | res; | ||
| 76 | end match; | ||
| 77 | end crefDims; | ||
| 78 | |||
| 79 | public function crefSubs " | ||
| 80 | function: crefSubs | ||
| 81 | Return all subscripts of a ComponentRef" | ||
| 82 | input DAE.ComponentRef inComponentRef; | ||
| 83 | output list<DAE.Subscript> outSubscriptLst; | ||
| 84 | algorithm | ||
| 85 | outSubscriptLst := match inComponentRef | ||
| 86 | local | ||
| 87 | list<DAE.Subscript> subs,res; | ||
| 88 | DAE.ComponentRef cr; | ||
| 89 | |||
| 90 | case DAE.CREF_IDENT(subscriptLst = subs) then subs; | ||
| 91 | |||
| 92 | case DAE.CREF_QUAL(componentRef = cr,subscriptLst=subs) | ||
| 93 | algorithm | ||
| 94 | 12745413 | res := crefSubs(cr); | |
| 95 | 12745413 | res := listAppend(subs,res); | |
| 96 | then | ||
| 97 | res; | ||
| 98 | end match; | ||
| 99 | end crefSubs; | ||
| 100 | |||
| 101 | /***************************************************/ | ||
| 102 | /* Compare */ | ||
| 103 | /***************************************************/ | ||
| 104 | |||
| 105 | public function crefLastIdentEqual | ||
| 106 | "author: Frenkel TUD | ||
| 107 | Returns true if the ComponentRefs has the same name (the last identifier)." | ||
| 108 | input DAE.ComponentRef cr1; | ||
| 109 | input DAE.ComponentRef cr2; | ||
| 110 | output Boolean equal; | ||
| 111 | protected | ||
| 112 | DAE.Ident id1,id2; | ||
| 113 | algorithm | ||
| 114 | 16215 | id1 := crefLastIdent(cr1); | |
| 115 | 16215 | id2 := crefLastIdent(cr2); | |
| 116 |
3/4✓ Branch 0 taken 15359 times.
✓ Branch 1 taken 856 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15359 times.
|
16215 | equal := stringEq(id1, id2); |
| 117 | end crefLastIdentEqual; | ||
| 118 | |||
| 119 | public function crefFirstCrefEqual | ||
| 120 | "author: Frenkel TUD | ||
| 121 | Returns true if the ComponentRefs have the same first Cref." | ||
| 122 | input DAE.ComponentRef cr1; | ||
| 123 | input DAE.ComponentRef cr2; | ||
| 124 | output Boolean equal; | ||
| 125 | protected | ||
| 126 | DAE.ComponentRef pcr1,pcr2; | ||
| 127 | algorithm | ||
| 128 | 47523 | pcr1 := crefFirstCref(cr1); | |
| 129 | 47523 | pcr2 := crefFirstCref(cr2); | |
| 130 | 47523 | equal := crefEqual(pcr1,pcr2); | |
| 131 | end crefFirstCrefEqual; | ||
| 132 | |||
| 133 | public function crefFirstCrefLastCrefEqual | ||
| 134 | "author: Frenkel TUD | ||
| 135 | Returns true if the ComponentRefs have the same first Cref." | ||
| 136 | input DAE.ComponentRef cr1 "First Cref"; | ||
| 137 | input DAE.ComponentRef cr2 "Last Cref"; | ||
| 138 | output Boolean equal; | ||
| 139 | protected | ||
| 140 | DAE.ComponentRef pcr1,pcr2; | ||
| 141 | algorithm | ||
| 142 | 10 | pcr1 := crefFirstCref(cr1); | |
| 143 | 10 | pcr2 := crefLastCref(cr2); | |
| 144 | 10 | equal := crefEqual(pcr1,pcr2); | |
| 145 | end crefFirstCrefLastCrefEqual; | ||
| 146 | |||
| 147 | public function crefFirstCref | ||
| 148 | "Returns the first part of a component reference, i.e the identifier" | ||
| 149 | input DAE.ComponentRef inCr; | ||
| 150 | output DAE.ComponentRef outCr; | ||
| 151 | algorithm | ||
| 152 | outCr := match inCr | ||
| 153 | local | ||
| 154 | DAE.Ident id; | ||
| 155 | list<DAE.Subscript> subs; | ||
| 156 | DAE.Type t2; | ||
| 157 | |||
| 158 | 247300 | case DAE.CREF_QUAL(id,t2,subs,_) then makeCrefIdent(id,t2,subs); | |
| 159 | case DAE.CREF_IDENT(_,_,_) then inCr; | ||
| 160 | end match; | ||
| 161 | end crefFirstCref; | ||
| 162 | |||
| 163 | public function crefLastIdent | ||
| 164 | "author: PA | ||
| 165 | Returns the last identfifier of a ComponentRef." | ||
| 166 | input DAE.ComponentRef inComponentRef; | ||
| 167 | output DAE.Ident outIdent; | ||
| 168 | algorithm | ||
| 169 | outIdent := match inComponentRef | ||
| 170 | local | ||
| 171 | DAE.Ident id,res; | ||
| 172 | DAE.ComponentRef cr; | ||
| 173 | |||
| 174 | case DAE.CREF_IDENT(ident = id) then id; | ||
| 175 | |||
| 176 | case DAE.CREF_QUAL(componentRef = cr) | ||
| 177 | algorithm | ||
| 178 | 9099435 | res := crefLastIdent(cr); | |
| 179 | then | ||
| 180 | res; | ||
| 181 | end match; | ||
| 182 | end crefLastIdent; | ||
| 183 | |||
| 184 | public function crefLastCref " | ||
| 185 | Return the last ComponentRef" | ||
| 186 | input DAE.ComponentRef inComponentRef; | ||
| 187 | output DAE.ComponentRef outComponentRef; | ||
| 188 | algorithm | ||
| 189 | outComponentRef := match inComponentRef | ||
| 190 | local | ||
| 191 | DAE.ComponentRef res,cr; | ||
| 192 | |||
| 193 | case DAE.CREF_IDENT() then inComponentRef; | ||
| 194 | |||
| 195 | case DAE.CREF_QUAL(componentRef = cr) | ||
| 196 | algorithm | ||
| 197 | 1291025 | res := crefLastCref(cr); | |
| 198 | then | ||
| 199 | res; | ||
| 200 | end match; | ||
| 201 | end crefLastCref; | ||
| 202 | |||
| 203 | public function crefFirstIdentEqual | ||
| 204 | "Returns true if the first identifier in both crefs are the same, otherwise false." | ||
| 205 | input DAE.ComponentRef inCref1; | ||
| 206 | input DAE.ComponentRef inCref2; | ||
| 207 | output Boolean outEqual; | ||
| 208 | protected | ||
| 209 | DAE.Ident id1, id2; | ||
| 210 | algorithm | ||
| 211 | 7478 | id1 := crefFirstIdent(inCref1); | |
| 212 | 7478 | id2 := crefFirstIdent(inCref2); | |
| 213 |
4/4✓ Branch 0 taken 5865 times.
✓ Branch 1 taken 1613 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 5853 times.
|
7478 | outEqual := stringEq(id1, id2); |
| 214 | end crefFirstIdentEqual; | ||
| 215 | |||
| 216 | public function crefFirstIdent | ||
| 217 | "Returns the first identifier of a component reference." | ||
| 218 | input DAE.ComponentRef inComponentRef; | ||
| 219 | output DAE.Ident outIdent; | ||
| 220 | algorithm | ||
| 221 | outIdent := match inComponentRef | ||
| 222 | local | ||
| 223 | DAE.Ident id; | ||
| 224 | |||
| 225 | case DAE.CREF_IDENT(ident = id) then id; | ||
| 226 | case DAE.CREF_QUAL(ident = id) then id; | ||
| 227 | end match; | ||
| 228 | end crefFirstIdent; | ||
| 229 | |||
| 230 | protected | ||
| 231 | |||
| 232 | type CompareWithSubsType = enumeration(WithoutSubscripts, WithGenericSubscript, WithGenericSubscriptNotAlphabetic, WithIntSubscript); | ||
| 233 | |||
| 234 | package CompareWithGenericSubscript "Package that can be modified to do different kinds of comparisons" | ||
| 235 | constant CompareWithSubsType compareSubscript=CompareWithSubsType.WithGenericSubscript; | ||
| 236 | function compare | ||
| 237 | input DAE.ComponentRef cr1, cr2; | ||
| 238 | output Integer res; | ||
| 239 | algorithm | ||
| 240 | res := match (cr1, cr2) | ||
| 241 | case (DAE.CREF_IDENT(),DAE.CREF_IDENT()) | ||
| 242 | algorithm | ||
| 243 | 12452128 | res := stringCompare(cr1.ident, cr2.ident); | |
| 244 |
6/6✓ Branch 0 taken 5898393 times.
✓ Branch 1 taken 5489722 times.
✓ Branch 2 taken 73449 times.
✓ Branch 3 taken 8532 times.
✓ Branch 4 taken 41003 times.
✓ Branch 5 taken 35918 times.
|
11547017 | if compareSubscript==CompareWithSubsType.WithoutSubscripts or res <> 0 then |
| 245 | 6917956 | return; | |
| 246 | end if; | ||
| 247 | 5534172 | then compareSubs(cr1.subscriptLst, cr2.subscriptLst); | |
| 248 | case (DAE.CREF_QUAL(),DAE.CREF_QUAL()) | ||
| 249 | algorithm | ||
| 250 | 25284019 | res := stringCompare(cr1.ident, cr2.ident); | |
| 251 |
8/8✓ Branch 0 taken 2933412 times.
✓ Branch 1 taken 14120789 times.
✓ Branch 2 taken 294605 times.
✓ Branch 3 taken 400461 times.
✓ Branch 4 taken 1542170 times.
✓ Branch 5 taken 5653403 times.
✓ Branch 6 taken 89891 times.
✓ Branch 7 taken 249288 times.
|
25284019 | if res <> 0 then |
| 252 | 4860078 | return; | |
| 253 | end if; | ||
| 254 | if compareSubscript<>CompareWithSubsType.WithoutSubscripts then | ||
| 255 | 14770538 | res := compareSubs(cr1.subscriptLst, cr2.subscriptLst); | |
| 256 |
6/6✓ Branch 0 taken 29044 times.
✓ Branch 1 taken 14091745 times.
✓ Branch 2 taken 27000 times.
✓ Branch 3 taken 373461 times.
✓ Branch 4 taken 1873 times.
✓ Branch 5 taken 247415 times.
|
14770538 | if res <> 0 then |
| 257 | 57917 | return; | |
| 258 | end if; | ||
| 259 | end if; | ||
| 260 | 20366024 | then compare(cr1.componentRef, cr2.componentRef); | |
| 261 | case (DAE.CREF_QUAL(),DAE.CREF_IDENT()) | ||
| 262 | algorithm | ||
| 263 | 1095937 | res := stringCompare(cr1.ident, cr2.ident); | |
| 264 |
6/8✓ Branch 0 taken 869092 times.
✓ Branch 1 taken 26409 times.
✓ Branch 2 taken 18291 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 164281 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17840 times.
✗ Branch 7 not taken.
|
1095937 | if res <> 0 then |
| 265 | 1069504 | return; | |
| 266 | end if; | ||
| 267 | if compareSubscript<>CompareWithSubsType.WithoutSubscripts then | ||
| 268 | 26433 | res := compareSubs(cr1.subscriptLst, cr2.subscriptLst); | |
| 269 | end if; | ||
| 270 |
3/6✓ Branch 0 taken 15000 times.
✓ Branch 1 taken 11409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
26433 | if res <> 0 then |
| 271 | 15000 | return; | |
| 272 | end if; | ||
| 273 | then 1; | ||
| 274 | case (DAE.CREF_IDENT(),DAE.CREF_QUAL()) | ||
| 275 | algorithm | ||
| 276 | 1735704 | res := stringCompare(cr1.ident, cr2.ident); | |
| 277 |
5/8✓ Branch 0 taken 1495770 times.
✓ Branch 1 taken 25591 times.
✓ Branch 2 taken 53614 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 137977 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22752 times.
✗ Branch 7 not taken.
|
1735704 | if res <> 0 then |
| 278 | 1710113 | return; | |
| 279 | end if; | ||
| 280 | if compareSubscript<>CompareWithSubsType.WithoutSubscripts then | ||
| 281 | 25591 | res := compareSubs(cr1.subscriptLst, cr2.subscriptLst); | |
| 282 | end if; | ||
| 283 |
2/6✓ Branch 0 taken 10122 times.
✓ Branch 1 taken 15469 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
25591 | if res <> 0 then |
| 284 | 10122 | return; | |
| 285 | end if; | ||
| 286 | then -1; | ||
| 287 | end match; | ||
| 288 | end compare; | ||
| 289 | function compareSubs | ||
| 290 | input list<DAE.Subscript> ss1, ss2; | ||
| 291 | output Integer res=0; | ||
| 292 | protected | ||
| 293 | list<DAE.Subscript> ss=ss2; | ||
| 294 | DAE.Subscript s2; | ||
| 295 | Integer i1, i2; | ||
| 296 | algorithm | ||
| 297 |
6/8✓ Branch 0 taken 6301552 times.
✓ Branch 1 taken 15141953 times.
✓ Branch 2 taken 48664 times.
✓ Branch 3 taken 381370 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 47750 times.
✓ Branch 7 taken 259401 times.
|
22180690 | for s1 in ss1 loop |
| 298 |
5/8✓ Branch 0 taken 13499 times.
✓ Branch 1 taken 6288053 times.
✓ Branch 2 taken 647 times.
✓ Branch 3 taken 48017 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 47750 times.
|
6397966 | if listEmpty(ss) then |
| 299 | res := -1; | ||
| 300 | 14146 | return; | |
| 301 | end if; | ||
| 302 | 6383820 | s2::ss := ss; | |
| 303 | if compareSubscript == CompareWithSubsType.WithGenericSubscript then | ||
| 304 | 6288053 | res := compareSubscriptStr(s1, s2); | |
| 305 | elseif compareSubscript == CompareWithSubsType.WithGenericSubscriptNotAlphabetic then | ||
| 306 | 48017 | res := ExpressionBasics.compareSubscripts(s1, s2); | |
| 307 | else | ||
| 308 | 47750 | i1 := ExpressionBasics.subscriptInt(s1); | |
| 309 | 47750 | i2 := ExpressionBasics.subscriptInt(s2); | |
| 310 |
4/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 41541 times.
✓ Branch 5 taken 6209 times.
✓ Branch 6 taken 21945 times.
✓ Branch 7 taken 19596 times.
|
47750 | res := if i1 < i2 then -1 elseif i1 > i2 then 1 else 0; |
| 311 | end if; | ||
| 312 |
4/4✓ Branch 0 taken 4507059 times.
✓ Branch 1 taken 1780994 times.
✓ Branch 2 taken 27000 times.
✓ Branch 3 taken 21017 times.
|
6336070 | if res <> 0 then |
| 313 | 4559864 | return; | |
| 314 | end if; | ||
| 315 | end for; | ||
| 316 |
4/8✓ Branch 0 taken 15125167 times.
✓ Branch 1 taken 16786 times.
✓ Branch 2 taken 381370 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 259401 times.
✗ Branch 7 not taken.
|
15782724 | if not listEmpty(ss) then |
| 317 | res := 1; | ||
| 318 | end if; | ||
| 319 | end compareSubs; | ||
| 320 | |||
| 321 | function compareSubscriptStr | ||
| 322 | "stringCompare of the printed subscripts, without printing an integer index." | ||
| 323 | input DAE.Subscript s1, s2; | ||
| 324 | output Integer res; | ||
| 325 | algorithm | ||
| 326 | res := match (s1, s2) | ||
| 327 | local | ||
| 328 | Integer i1, i2; | ||
| 329 | case (DAE.INDEX(exp = DAE.ICONST(integer = i1)), DAE.INDEX(exp = DAE.ICONST(integer = i2))) | ||
| 330 |
2/8✓ Branch 0 taken 4505325 times.
✓ Branch 1 taken 1779202 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
6284527 | then if i1 == i2 then 0 else stringCompare(intString(i1), intString(i2)); |
| 331 |
2/8✓ Branch 0 taken 3419 times.
✓ Branch 1 taken 107 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
3526 | else |
| 332 | if referenceEq(s1, s2) then 0 | ||
| 333 | else stringCompare(ExpressionBasics.printSubscriptStr(s1), ExpressionBasics.printSubscriptStr(s2)); | ||
| 334 | end match; | ||
| 335 | end compareSubscriptStr; | ||
| 336 | end CompareWithGenericSubscript; | ||
| 337 | |||
| 338 | package CompareWithGenericSubscriptNotAlphabetic | ||
| 339 | extends CompareWithGenericSubscript(compareSubscript=CompareWithSubsType.WithGenericSubscriptNotAlphabetic); | ||
| 340 | end CompareWithGenericSubscriptNotAlphabetic; | ||
| 341 | package CompareWithoutSubscripts | ||
| 342 | extends CompareWithGenericSubscript(compareSubscript=CompareWithSubsType.WithoutSubscripts); | ||
| 343 | end CompareWithoutSubscripts; | ||
| 344 | package CompareWithIntSubscript "More efficient than CompareWithGenericSubscript, assuming all subscripts are integers" | ||
| 345 | extends CompareWithGenericSubscript(compareSubscript=CompareWithSubsType.WithIntSubscript); | ||
| 346 | end CompareWithIntSubscript; | ||
| 347 | |||
| 348 | public function crefSortFunc "A sorting function (greatherThan) for crefs" | ||
| 349 | input DAE.ComponentRef cr1; | ||
| 350 | input DAE.ComponentRef cr2; | ||
| 351 | output Boolean greaterThan; | ||
| 352 | algorithm | ||
| 353 | 24755 | greaterThan := CompareWithGenericSubscript.compare(cr1,cr2) > 0; | |
| 354 | end crefSortFunc; | ||
| 355 | |||
| 356 | public function crefCompareGeneric "A sorting function for crefs" | ||
| 357 | input DAE.ComponentRef cr1; | ||
| 358 | input DAE.ComponentRef cr2; | ||
| 359 | output Integer comp; | ||
| 360 | algorithm | ||
| 361 | 16742678 | comp := CompareWithGenericSubscript.compare(cr1,cr2); | |
| 362 | end crefCompareGeneric; | ||
| 363 | |||
| 364 | public function crefCompareIntSubscript "A sorting function for crefs" | ||
| 365 | input DAE.ComponentRef cr1; | ||
| 366 | input DAE.ComponentRef cr2; | ||
| 367 | output Integer comp; | ||
| 368 | algorithm | ||
| 369 | 209277 | comp := CompareWithIntSubscript.compare(cr1,cr2); | |
| 370 | end crefCompareIntSubscript; | ||
| 371 | |||
| 372 | public function crefCompareGenericNotAlphabetic "A sorting function for crefs" | ||
| 373 | input DAE.ComponentRef cr1; | ||
| 374 | input DAE.ComponentRef cr2; | ||
| 375 | output Integer comp; | ||
| 376 | algorithm | ||
| 377 | 475515 | comp := CompareWithGenericSubscriptNotAlphabetic.compare(cr1,cr2); | |
| 378 | end crefCompareGenericNotAlphabetic; | ||
| 379 | |||
| 380 | public function crefLexicalGreaterSubsAtEnd | ||
| 381 | "mahge: | ||
| 382 | Compares two crefs lexically. Subscripts are treated as if they are | ||
| 383 | they are at the end of the whole component reference. | ||
| 384 | e.g. r[1].i is greater than r[2].a. | ||
| 385 | returns true if the first cref is greater than the second" | ||
| 386 | input DAE.ComponentRef cr1; | ||
| 387 | input DAE.ComponentRef cr2; | ||
| 388 | output Boolean isGreater; | ||
| 389 | algorithm | ||
| 390 | 2749539 | isGreater := crefLexicalCompareSubsAtEnd(cr1,cr2) > 0; | |
| 391 | end crefLexicalGreaterSubsAtEnd; | ||
| 392 | |||
| 393 | public function crefLexicalCompareSubsAtEnd | ||
| 394 | "mahge: | ||
| 395 | Compares two crefs lexically. Subscripts are treated as if they are | ||
| 396 | they are at the end of the whole component reference. | ||
| 397 | e.g. r[1].i is greater than r[2].a. | ||
| 398 | returns value is same as C strcmp. 0 if equal, 1 if first is greater, -1 otherwise" | ||
| 399 | input DAE.ComponentRef cr1; | ||
| 400 | input DAE.ComponentRef cr2; | ||
| 401 | output Integer res; | ||
| 402 | protected | ||
| 403 | list<Integer> subs1; | ||
| 404 | list<Integer> subs2; | ||
| 405 | algorithm | ||
| 406 | 2749539 | res := CompareWithoutSubscripts.compare(cr1, cr2); | |
| 407 |
2/2✓ Branch 0 taken 2440511 times.
✓ Branch 1 taken 309028 times.
|
2749539 | if res <> 0 then |
| 408 | 2440511 | return; | |
| 409 | end if; | ||
| 410 | 309028 | subs1 := ExpressionBasics.subscriptsInt(crefSubs(cr1)); | |
| 411 | 309028 | subs2 := ExpressionBasics.subscriptsInt(crefSubs(cr2)); | |
| 412 | 309028 | res := crefLexicalCompareSubsAtEnd2(subs1, subs2); | |
| 413 | end crefLexicalCompareSubsAtEnd; | ||
| 414 | |||
| 415 | protected function crefLexicalCompareSubsAtEnd2 | ||
| 416 | "mahge: | ||
| 417 | Helper function for crefLexicalCompareubsAtEnd | ||
| 418 | compares subs. However only if the crefs with out subs are equal. | ||
| 419 | (i.e. identsCompared is 0) | ||
| 420 | otherwise just returns" | ||
| 421 | input list<Integer> inSubs1; | ||
| 422 | input list<Integer> inSubs2; | ||
| 423 | output Integer res = 0; | ||
| 424 | protected | ||
| 425 | list<Integer> rest=inSubs2; | ||
| 426 | algorithm | ||
| 427 |
1/2✓ Branch 0 taken 373694 times.
✗ Branch 1 not taken.
|
373694 | for i in inSubs1 loop |
| 428 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 373694 times.
|
373694 | res::rest := rest; |
| 429 |
4/4✓ Branch 0 taken 149099 times.
✓ Branch 1 taken 224595 times.
✓ Branch 2 taken 64666 times.
✓ Branch 3 taken 84433 times.
|
373694 | res := if i>res then 1 elseif i < res then -1 else 0; |
| 430 | if res <> 0 then | ||
| 431 | 309028 | return; | |
| 432 | end if; | ||
| 433 | end for; | ||
| 434 | end crefLexicalCompareSubsAtEnd2; | ||
| 435 | |||
| 436 | public function crefContainedIn | ||
| 437 | "author: PA | ||
| 438 | Returns true if second arg is a sub component ref of first arg. | ||
| 439 | For instance, b.c. is a sub_component of a.b.c." | ||
| 440 | input DAE.ComponentRef containerCref "the cref that might contain"; | ||
| 441 | input DAE.ComponentRef containedCref "cref that might be contained"; | ||
| 442 | output Boolean outBoolean; | ||
| 443 | algorithm | ||
| 444 | outBoolean := matchcontinue (containerCref, containedCref) | ||
| 445 | local | ||
| 446 | DAE.ComponentRef full,partOf,cr2; | ||
| 447 | Boolean res; | ||
| 448 | |||
| 449 | // a qualified cref cannot be contained in an ident cref. | ||
| 450 | case (DAE.CREF_IDENT(), DAE.CREF_QUAL()) then false; | ||
| 451 | |||
| 452 | // see if they are equal | ||
| 453 | case (full, partOf) | ||
| 454 | algorithm | ||
| 455 | ✗ | true := crefEqualNoStringCompare(full, partOf); | |
| 456 | then | ||
| 457 | true; | ||
| 458 | |||
| 459 | // dive into | ||
| 460 | case (full as DAE.CREF_QUAL(componentRef = cr2), partOf) | ||
| 461 | algorithm | ||
| 462 | ✗ | false := crefEqualNoStringCompare(full, partOf); | |
| 463 | ✗ | res := crefContainedIn(cr2,partOf); | |
| 464 | then | ||
| 465 | res; | ||
| 466 | |||
| 467 | // anything else is false | ||
| 468 | else false; | ||
| 469 | end matchcontinue; | ||
| 470 | end crefContainedIn; | ||
| 471 | |||
| 472 | public function crefPrefixOf | ||
| 473 | "author: PA | ||
| 474 | Returns true if prefixCref is a prefix of fullCref | ||
| 475 | For example, a.b is a prefix of a.b.c. | ||
| 476 | adrpo 2010-10-07, | ||
| 477 | added also that a.b.c is a prefix of a.b.c[1].*!" | ||
| 478 | input DAE.ComponentRef prefixCref; | ||
| 479 | input DAE.ComponentRef fullCref; | ||
| 480 | output Boolean outPrefixOf; | ||
| 481 | algorithm | ||
| 482 | outPrefixOf := match (prefixCref,fullCref) | ||
| 483 | // both are qualified, dive into | ||
| 484 | case (DAE.CREF_QUAL(), DAE.CREF_QUAL()) | ||
| 485 |
8/8✓ Branch 0 taken 117982 times.
✓ Branch 1 taken 28592 times.
✓ Branch 3 taken 105921 times.
✓ Branch 4 taken 12061 times.
✓ Branch 6 taken 104441 times.
✓ Branch 7 taken 1480 times.
✓ Branch 9 taken 96071 times.
✓ Branch 10 taken 8370 times.
|
146574 | then prefixCref.ident == fullCref.ident and |
| 486 | ExpressionBasics.subscriptEqual(prefixCref.subscriptLst, fullCref.subscriptLst) and | ||
| 487 | crefPrefixOf(prefixCref.componentRef, fullCref.componentRef); | ||
| 488 | |||
| 489 | // adrpo: 2010-10-07: first is an ID, second is qualified, see if one is prefix of the other | ||
| 490 | // even if the first one DOESN'T HAVE SUBSCRIPTS! | ||
| 491 | case (DAE.CREF_IDENT(subscriptLst = {}), DAE.CREF_QUAL()) | ||
| 492 |
4/4✓ Branch 0 taken 12040 times.
✓ Branch 1 taken 927 times.
✓ Branch 3 taken 418 times.
✓ Branch 4 taken 11622 times.
|
12967 | then prefixCref.ident == fullCref.ident; |
| 493 | |||
| 494 | // first is an ID, second is qualified, see if one is prefix of the other | ||
| 495 | case (DAE.CREF_IDENT(), DAE.CREF_QUAL()) | ||
| 496 |
5/6✓ Branch 0 taken 720 times.
✓ Branch 1 taken 5768 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 672 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
|
6488 | then prefixCref.ident == fullCref.ident and |
| 497 | ExpressionBasics.subscriptEqual(prefixCref.subscriptLst, fullCref.subscriptLst); | ||
| 498 | |||
| 499 | // adrpo: 2010-10-07: first is an ID, second is an ID, see if one is prefix of the other | ||
| 500 | // even if the first one DOESN'T HAVE SUBSCRIPTS! | ||
| 501 | case (DAE.CREF_IDENT(subscriptLst = {}), DAE.CREF_IDENT()) | ||
| 502 |
4/4✓ Branch 0 taken 5792 times.
✓ Branch 1 taken 9137 times.
✓ Branch 3 taken 5362 times.
✓ Branch 4 taken 430 times.
|
14929 | then stringEq(prefixCref.ident, fullCref.ident); |
| 503 | |||
| 504 | case (DAE.CREF_IDENT(), DAE.CREF_IDENT()) | ||
| 505 |
6/6✓ Branch 0 taken 3987 times.
✓ Branch 1 taken 8264 times.
✓ Branch 3 taken 123 times.
✓ Branch 4 taken 3864 times.
✓ Branch 6 taken 104 times.
✓ Branch 7 taken 19 times.
|
12251 | then prefixCref.ident == fullCref.ident and |
| 506 | ExpressionBasics.subscriptEqual(prefixCref.subscriptLst, fullCref.subscriptLst); | ||
| 507 | |||
| 508 | // they are not a prefix of one-another | ||
| 509 | else false; | ||
| 510 | end match; | ||
| 511 | end crefPrefixOf; | ||
| 512 | |||
| 513 | public function crefPrefixOfIgnoreSubscripts | ||
| 514 | "author: PA | ||
| 515 | Returns true if prefixCref is a prefix of fullCref | ||
| 516 | For example, a.b is a prefix of a.b.c. | ||
| 517 | This function ignores the subscripts" | ||
| 518 | input DAE.ComponentRef prefixCref; | ||
| 519 | input DAE.ComponentRef fullCref; | ||
| 520 | output Boolean outPrefixOf; | ||
| 521 | algorithm | ||
| 522 | outPrefixOf := match (prefixCref,fullCref) | ||
| 523 | // both are qualified, dive into | ||
| 524 | case (DAE.CREF_QUAL(), DAE.CREF_QUAL()) | ||
| 525 |
6/6✓ Branch 0 taken 3475626 times.
✓ Branch 1 taken 1705696 times.
✓ Branch 3 taken 798789 times.
✓ Branch 4 taken 2676837 times.
✓ Branch 6 taken 795727 times.
✓ Branch 7 taken 3062 times.
|
5181322 | then prefixCref.ident == fullCref.ident and |
| 526 | crefPrefixOfIgnoreSubscripts(prefixCref.componentRef, fullCref.componentRef); | ||
| 527 | |||
| 528 | // first is an ID, second is qualified, see if one is prefix of the other | ||
| 529 | case (DAE.CREF_IDENT(), DAE.CREF_QUAL()) | ||
| 530 |
4/4✓ Branch 0 taken 13524 times.
✓ Branch 1 taken 79576 times.
✓ Branch 3 taken 11758 times.
✓ Branch 4 taken 1766 times.
|
93100 | then prefixCref.ident == fullCref.ident; |
| 531 | |||
| 532 | case (DAE.CREF_IDENT(), DAE.CREF_IDENT()) | ||
| 533 |
4/4✓ Branch 0 taken 15606 times.
✓ Branch 1 taken 82033 times.
✓ Branch 3 taken 15581 times.
✓ Branch 4 taken 25 times.
|
97639 | then prefixCref.ident == fullCref.ident; |
| 534 | |||
| 535 | // they are not a prefix of one-another | ||
| 536 | else false; | ||
| 537 | end match; | ||
| 538 | end crefPrefixOfIgnoreSubscripts; | ||
| 539 | |||
| 540 | public function crefNotPrefixOf "negation of crefPrefixOf" | ||
| 541 | input DAE.ComponentRef cr1; | ||
| 542 | input DAE.ComponentRef cr2; | ||
| 543 | output Boolean outBoolean; | ||
| 544 | algorithm | ||
| 545 | outBoolean := match(cr1, cr2) | ||
| 546 | // first is qualified, second is an unqualified ident, return false! | ||
| 547 | case (DAE.CREF_QUAL(), DAE.CREF_IDENT()) then true; | ||
| 548 | ✗ | else not crefPrefixOf(cr1, cr2); | |
| 549 | end match; | ||
| 550 | end crefNotPrefixOf; | ||
| 551 | |||
| 552 | public function crefEqual | ||
| 553 | "Returns true if two component references are equal. | ||
| 554 | No string comparison of unparsed crefs is performed!" | ||
| 555 | input DAE.ComponentRef inComponentRef1; | ||
| 556 | input DAE.ComponentRef inComponentRef2; | ||
| 557 | output Boolean outBoolean; | ||
| 558 | algorithm | ||
| 559 | 34663005 | outBoolean := crefEqualNoStringCompare(inComponentRef1,inComponentRef2); | |
| 560 | end crefEqual; | ||
| 561 | |||
| 562 | public function crefInLst "returns true if the cref is in the list of crefs" | ||
| 563 | input DAE.ComponentRef cref; | ||
| 564 | input list<DAE.ComponentRef> lst; | ||
| 565 | output Boolean b; | ||
| 566 | algorithm | ||
| 567 | 88322 | b := List.isMemberOnTrue(cref,lst,crefEqual); | |
| 568 | end crefInLst; | ||
| 569 | |||
| 570 | public function crefNotInLst "returns true if the cref is not in the list of crefs" | ||
| 571 | input DAE.ComponentRef cref; | ||
| 572 | input list<DAE.ComponentRef> lst; | ||
| 573 | output Boolean b; | ||
| 574 | algorithm | ||
| 575 | ✗ | b := not List.isMemberOnTrue(cref,lst,crefEqual); | |
| 576 | end crefNotInLst; | ||
| 577 | |||
| 578 | public function crefEqualVerySlowStringCompareDoNotUse | ||
| 579 | "Returns true if two component references are equal, | ||
| 580 | comparing strings if no other solution is found" | ||
| 581 | input DAE.ComponentRef inComponentRef1; | ||
| 582 | input DAE.ComponentRef inComponentRef2; | ||
| 583 | output Boolean outBoolean; | ||
| 584 | algorithm | ||
| 585 | outBoolean := matchcontinue (inComponentRef1,inComponentRef2) | ||
| 586 | local | ||
| 587 | DAE.Ident n1,n2,s1,s2; | ||
| 588 | list<DAE.Subscript> idx1,idx2; | ||
| 589 | DAE.ComponentRef cr1,cr2; | ||
| 590 | |||
| 591 | // check for pointer equality first, if they point to the same thing, they are equal | ||
| 592 | case (_,_) | ||
| 593 | algorithm | ||
| 594 | ✗ | true := referenceEq(inComponentRef1,inComponentRef2); | |
| 595 | then | ||
| 596 | true; | ||
| 597 | |||
| 598 | // simple identifiers | ||
| 599 | case (DAE.CREF_IDENT(ident = n1,subscriptLst = {}),DAE.CREF_IDENT(ident = n2,subscriptLst = {})) | ||
| 600 | algorithm | ||
| 601 | ✗ | true := stringEq(n1, n2); | |
| 602 | then | ||
| 603 | true; | ||
| 604 | case (DAE.CREF_IDENT(ident = n1,subscriptLst = (idx1 as _::_)),DAE.CREF_IDENT(ident = n2,subscriptLst = (idx2 as _::_))) | ||
| 605 | algorithm | ||
| 606 | ✗ | true := stringEq(n1, n2); | |
| 607 | ✗ | true := ExpressionBasics.subscriptEqual(idx1, idx2); | |
| 608 | then | ||
| 609 | true; | ||
| 610 | // BZ 2009-12 | ||
| 611 | // For some reason in some examples we get crefs on different forms. | ||
| 612 | // the compare can be crefEqual(CREF_IDENT("mycref",_,{1,2,3}),CREF_IDENT("mycref[1,2,3]",_,{})) | ||
| 613 | // I do belive this has something to do with variable replacement and BackendDAE. | ||
| 614 | // TODO: investigate reason, until then keep as is. | ||
| 615 | // I do believe that this is the same bug as adrians qual-ident bug below. | ||
| 616 | case (DAE.CREF_IDENT(ident = n1,subscriptLst = {}),DAE.CREF_IDENT(ident = n2,subscriptLst = (idx2 as _::_))) | ||
| 617 | algorithm | ||
| 618 | ✗ | 0 := System.stringFind(n1, n2); // n2 should be first in n1! | |
| 619 | ✗ | s1 := n2 + "[" + ExpressionBasics.printListStr(idx2, ExpressionBasics.printSubscriptStr, ",") + "]"; | |
| 620 | ✗ | true := stringEq(s1,n1); | |
| 621 | then | ||
| 622 | true; | ||
| 623 | case (DAE.CREF_IDENT(ident = n1,subscriptLst = (idx2 as _::_)),DAE.CREF_IDENT(ident = n2,subscriptLst = {})) | ||
| 624 | algorithm | ||
| 625 | ✗ | 0 := System.stringFind(n2, n1); // n1 should be first in n2! | |
| 626 | ✗ | s1 := n1 + "[" + ExpressionBasics.printListStr(idx2, ExpressionBasics.printSubscriptStr, ",") + "]"; | |
| 627 | ✗ | true := stringEq(s1,n2); | |
| 628 | then | ||
| 629 | true; | ||
| 630 | // qualified crefs | ||
| 631 | case (DAE.CREF_QUAL(ident = n1,subscriptLst = idx1,componentRef = cr1),DAE.CREF_QUAL(ident = n2,subscriptLst = idx2,componentRef = cr2)) | ||
| 632 | algorithm | ||
| 633 | ✗ | true := stringEq(n1, n2); | |
| 634 | ✗ | true := crefEqualVerySlowStringCompareDoNotUse(cr1, cr2); | |
| 635 | ✗ | true := ExpressionBasics.subscriptEqual(idx1, idx2); | |
| 636 | then | ||
| 637 | true; | ||
| 638 | // this is a VERY expensive case! Do we NEED IT??!! | ||
| 639 | // There is a bug here somewhere or in MetaModelica Compiler (MMC). | ||
| 640 | // Therefore as a last resort, print the strings and compare. | ||
| 641 | // adrpo: this is really not needed BUT unfortunately IT IS as | ||
| 642 | // QUAL(x, IDENT(y)) == IDENT(x.y) | ||
| 643 | // somewhere in the compiler the lhs is replaced by the rhs | ||
| 644 | // and makes this case needed! THIS SHOULD BE FIXED!! TODO! FIXME! | ||
| 645 | // NOTE: THIS IS NOT A BUG IN MMC! | ||
| 646 | /* adrpo: comment this and try to make it work faster with the two cases below! | ||
| 647 | case (cr1 as DAE.CREF_QUAL(ident = n1),cr2 as DAE.CREF_IDENT) | ||
| 648 | algorithm | ||
| 649 | s1 = printComponentRefStr(cr1); | ||
| 650 | s2 = printComponentRefStr(cr2); | ||
| 651 | true = stringEq(s1, s2); | ||
| 652 | // debug_print("cr1", cr1); | ||
| 653 | // debug_print("cr2", cr2); | ||
| 654 | // enableTrace(); | ||
| 655 | then | ||
| 656 | true; | ||
| 657 | */ | ||
| 658 | // the following two cases replaces the one below | ||
| 659 | // right cref is stringified! | ||
| 660 | case (cr1 as DAE.CREF_QUAL(ident = n1),cr2 as DAE.CREF_IDENT(ident = n2)) | ||
| 661 | algorithm | ||
| 662 | ✗ | 0 := System.stringFind(n2, n1); // n1 should be first in n2! | |
| 663 | ✗ | s1 := printComponentRefStr(cr1); | |
| 664 | ✗ | s2 := printComponentRefStr(cr2); | |
| 665 | ✗ | true := stringEq(s1, s2); | |
| 666 | then | ||
| 667 | true; | ||
| 668 | // left cref is stringified! | ||
| 669 | case (cr1 as DAE.CREF_IDENT(ident = n1),cr2 as DAE.CREF_QUAL(ident = n2)) | ||
| 670 | algorithm | ||
| 671 | ✗ | 0 := System.stringFind(n1, n2); // n2 should be first in n1! | |
| 672 | ✗ | s1 := printComponentRefStr(cr1); | |
| 673 | ✗ | s2 := printComponentRefStr(cr2); | |
| 674 | ✗ | true := stringEq(s1, s2); | |
| 675 | then | ||
| 676 | true; | ||
| 677 | // the crefs are not equal! | ||
| 678 | else false; | ||
| 679 | end matchcontinue; | ||
| 680 | end crefEqualVerySlowStringCompareDoNotUse; | ||
| 681 | |||
| 682 | public function crefEqualNoStringCompare | ||
| 683 | "Returns true if two component references are equal! | ||
| 684 | IMPORTANT! do not use this function if you have | ||
| 685 | stringified components, meaning this function will | ||
| 686 | return false for: cref1: QUAL(x, IDENT(y)) != cref2: IDENT(x.y)" | ||
| 687 | input DAE.ComponentRef inCref1; | ||
| 688 | input DAE.ComponentRef inCref2; | ||
| 689 | output Boolean outEqual; | ||
| 690 | algorithm | ||
| 691 |
2/2✓ Branch 0 taken 16662124 times.
✓ Branch 1 taken 122075312 times.
|
138737436 | if referenceEq(inCref1, inCref2) then |
| 692 | outEqual := true; | ||
| 693 | 16662124 | return; | |
| 694 | end if; | ||
| 695 | |||
| 696 | outEqual := match(inCref1, inCref2) | ||
| 697 | case (DAE.CREF_IDENT(), DAE.CREF_IDENT()) | ||
| 698 |
6/6✓ Branch 0 taken 25119331 times.
✓ Branch 1 taken 3072090 times.
✓ Branch 3 taken 24152324 times.
✓ Branch 4 taken 967007 times.
✓ Branch 6 taken 3154214 times.
✓ Branch 7 taken 20998110 times.
|
28191421 | then inCref1.ident == inCref2.ident and |
| 699 | ExpressionBasics.subscriptEqual(inCref1.subscriptLst, inCref2.subscriptLst); | ||
| 700 | |||
| 701 | case (DAE.CREF_QUAL(), DAE.CREF_QUAL()) | ||
| 702 |
8/8✓ Branch 0 taken 71376348 times.
✓ Branch 1 taken 16282380 times.
✓ Branch 3 taken 65050893 times.
✓ Branch 4 taken 6325455 times.
✓ Branch 6 taken 43055866 times.
✓ Branch 7 taken 21995027 times.
✓ Branch 9 taken 19944 times.
✓ Branch 10 taken 43035922 times.
|
87658728 | then inCref1.ident == inCref2.ident and |
| 703 | crefEqualNoStringCompare(inCref1.componentRef, inCref2.componentRef) and | ||
| 704 | ExpressionBasics.subscriptEqual(inCref1.subscriptLst, inCref2.subscriptLst); | ||
| 705 | |||
| 706 | else false; | ||
| 707 | end match; | ||
| 708 | end crefEqualNoStringCompare; | ||
| 709 | |||
| 710 | public function crefEqualReturn | ||
| 711 | "author: PA | ||
| 712 | Checks if two crefs are equal and if | ||
| 713 | so returns the cref, otherwise fail." | ||
| 714 | input DAE.ComponentRef cr; | ||
| 715 | input DAE.ComponentRef cr2; | ||
| 716 | output DAE.ComponentRef ocr; | ||
| 717 | algorithm | ||
| 718 | ✗ | true := crefEqualNoStringCompare(cr, cr2); | |
| 719 | ocr := cr; | ||
| 720 | end crefEqualReturn; | ||
| 721 | |||
| 722 | public function crefEqualWithoutLastSubs | ||
| 723 | "Checks if two crefs are equal, without considering their last subscripts." | ||
| 724 | input DAE.ComponentRef cr1; | ||
| 725 | input DAE.ComponentRef cr2; | ||
| 726 | output Boolean res; | ||
| 727 | algorithm | ||
| 728 | ✗ | res := crefEqualNoStringCompare(crefStripLastSubs(cr1),crefStripLastSubs(cr2)); | |
| 729 | end crefEqualWithoutLastSubs; | ||
| 730 | |||
| 731 | public function crefEqualWithoutSubs | ||
| 732 | "Checks if two crefs are equal, without considering their subscripts." | ||
| 733 | input DAE.ComponentRef cr1; | ||
| 734 | input DAE.ComponentRef cr2; | ||
| 735 | output Boolean res; | ||
| 736 | algorithm | ||
| 737 | 863673 | res := crefEqualWithoutSubs2(referenceEq(cr1, cr2), cr1, cr2); | |
| 738 | end crefEqualWithoutSubs; | ||
| 739 | |||
| 740 | protected function crefEqualWithoutSubs2 | ||
| 741 | input Boolean refEq; | ||
| 742 | input DAE.ComponentRef icr1; | ||
| 743 | input DAE.ComponentRef icr2; | ||
| 744 | output Boolean res; | ||
| 745 | algorithm | ||
| 746 | res := match(refEq, icr1, icr2) | ||
| 747 | local | ||
| 748 | DAE.Ident n1, n2; | ||
| 749 | Boolean r; | ||
| 750 | DAE.ComponentRef cr1,cr2; | ||
| 751 | |||
| 752 | case (true, _, _) then true; | ||
| 753 | |||
| 754 | case (_, DAE.CREF_IDENT(ident = n1), DAE.CREF_IDENT(ident = n2)) | ||
| 755 |
4/4✓ Branch 0 taken 59829 times.
✓ Branch 1 taken 68237 times.
✓ Branch 3 taken 33642 times.
✓ Branch 4 taken 26187 times.
|
128066 | then stringEq(n1, n2); |
| 756 | |||
| 757 | case (_, DAE.CREF_QUAL(ident = n1, componentRef = cr1), | ||
| 758 | DAE.CREF_QUAL(ident = n2, componentRef = cr2)) | ||
| 759 | algorithm | ||
| 760 |
4/4✓ Branch 0 taken 661846 times.
✓ Branch 1 taken 572402 times.
✓ Branch 3 taken 537094 times.
✓ Branch 4 taken 124752 times.
|
1234248 | r := stringEq(n1, n2); |
| 761 | 537094 | r := if r then crefEqualWithoutSubs2(referenceEq(cr1, cr2), cr1, cr2) else false; | |
| 762 | then | ||
| 763 | r; | ||
| 764 | |||
| 765 | else false; | ||
| 766 | end match; | ||
| 767 | end crefEqualWithoutSubs2; | ||
| 768 | |||
| 769 | public function crefStripLastSubs | ||
| 770 | "Strips the last subscripts of a ComponentRef" | ||
| 771 | input DAE.ComponentRef inComponentRef; | ||
| 772 | output DAE.ComponentRef outComponentRef; | ||
| 773 | algorithm | ||
| 774 | outComponentRef := match inComponentRef | ||
| 775 | local | ||
| 776 | DAE.Ident id; | ||
| 777 | list<DAE.Subscript> s; | ||
| 778 | DAE.ComponentRef cr_1,cr; | ||
| 779 | DAE.Type t2; | ||
| 780 | |||
| 781 | case DAE.CREF_IDENT(subscriptLst = {}) then inComponentRef; | ||
| 782 | |||
| 783 | case DAE.CREF_IDENT(ident = id,identType = t2) | ||
| 784 | 3255743 | then | |
| 785 | makeCrefIdent(id,t2,{}); | ||
| 786 | |||
| 787 | case DAE.CREF_QUAL(ident = id,identType = t2,subscriptLst = s,componentRef = cr) | ||
| 788 | algorithm | ||
| 789 | 10384703 | cr_1 := crefStripLastSubs(cr); | |
| 790 |
2/2✓ Branch 0 taken 5085290 times.
✓ Branch 1 taken 5299413 times.
|
10384703 | then |
| 791 | if referenceEq(cr, cr_1) then inComponentRef else makeCrefQual(id,t2,s,cr_1); | ||
| 792 | end match; | ||
| 793 | end crefStripLastSubs; | ||
| 794 | |||
| 795 | public function makeCrefIdent | ||
| 796 | "@author: adrpo | ||
| 797 | This function creates a DAE.CREF_IDENT(ident, identType, subscriptLst)" | ||
| 798 | input DAE.Ident ident; | ||
| 799 | input DAE.Type identType "type of the identifier, without considering the subscripts"; | ||
| 800 | input list<DAE.Subscript> subscriptLst; | ||
| 801 | output DAE.ComponentRef outCrefIdent; | ||
| 802 | annotation(__OpenModelica_EarlyInline = true); | ||
| 803 | algorithm | ||
| 804 | 20182808 | outCrefIdent := DAE.CREF_IDENT(ident, identType, subscriptLst); | |
| 805 | end makeCrefIdent; | ||
| 806 | |||
| 807 | public function makeCrefQual | ||
| 808 | "@author: adrpo | ||
| 809 | This function creates a DAE.CREF_QUAL(ident, identType, subscriptLst, componentRef)" | ||
| 810 | input DAE.Ident ident; | ||
| 811 | input DAE.Type identType "type of the identifier, without considering the subscripts"; | ||
| 812 | input list<DAE.Subscript> subscriptLst; | ||
| 813 | input DAE.ComponentRef componentRef; | ||
| 814 | output DAE.ComponentRef outCrefQual; | ||
| 815 | annotation(__OpenModelica_EarlyInline = true); | ||
| 816 | algorithm | ||
| 817 | // subCref := shareCref(componentRef); | ||
| 818 | // outCrefQual := shareCref(DAE.CREF_QUAL(ident, identType, subscriptLst, subCref)); | ||
| 819 | 20921659 | outCrefQual := DAE.CREF_QUAL(ident, identType, subscriptLst, componentRef); | |
| 820 | end makeCrefQual; | ||
| 821 | |||
| 822 | public function printComponentRefStr | ||
| 823 | "Print a ComponentRef. | ||
| 824 | LS: print functions that return a string instead of printing | ||
| 825 | Had to duplicate the huge printExp2 and modify. | ||
| 826 | An alternative would be to implement sprint somehow | ||
| 827 | which would need internal state, with reset and | ||
| 828 | getString methods. | ||
| 829 | Once these are tested and ok, the printExp above can | ||
| 830 | be replaced by a call to these _str functions and | ||
| 831 | printing the result." | ||
| 832 | input DAE.ComponentRef inComponentRef; | ||
| 833 | output String outString; | ||
| 834 | algorithm | ||
| 835 | outString := match inComponentRef | ||
| 836 | local | ||
| 837 | DAE.Ident s,str,strrest,strseb; | ||
| 838 | list<DAE.Subscript> subs; | ||
| 839 | DAE.ComponentRef cr; | ||
| 840 | Boolean b; | ||
| 841 | |||
| 842 | // Optimize -- a function call less | ||
| 843 | case DAE.CREF_IDENT(ident = s,subscriptLst = {}) | ||
| 844 | then s; | ||
| 845 | |||
| 846 | // idents with subscripts | ||
| 847 | case DAE.CREF_IDENT(ident = s,subscriptLst = subs) | ||
| 848 | algorithm | ||
| 849 | 427786 | str := printComponentRef2Str(s, subs); | |
| 850 | then | ||
| 851 | str; | ||
| 852 | |||
| 853 | // Qualified - Modelica output - does not handle names with underscores | ||
| 854 | // Qualified - non Modelica output | ||
| 855 | case DAE.CREF_QUAL(ident = s,subscriptLst = subs,componentRef = cr) | ||
| 856 | algorithm | ||
| 857 | 798597 | b := Config.modelicaOutput(); | |
| 858 | 798597 | str := printComponentRef2Str(s, subs); | |
| 859 | 798597 | strrest := printComponentRefStr(cr); | |
| 860 |
1/2✓ Branch 0 taken 798597 times.
✗ Branch 1 not taken.
|
798597 | strseb := if b then "__" else "."; |
| 861 | 798597 | str := stringAppendList({str, strseb, strrest}); | |
| 862 | then | ||
| 863 | str; | ||
| 864 | |||
| 865 | // Wild | ||
| 866 | case DAE.WILD() then "_"; | ||
| 867 | end match; | ||
| 868 | end printComponentRefStr; | ||
| 869 | |||
| 870 | public function printComponentRef2Str | ||
| 871 | "Helper function to printComponentRefStr." | ||
| 872 | input DAE.Ident inIdent; | ||
| 873 | input list<DAE.Subscript> inSubscriptLst; | ||
| 874 | output String outString; | ||
| 875 | algorithm | ||
| 876 | outString := match (inIdent,inSubscriptLst) | ||
| 877 | local | ||
| 878 | DAE.Ident s,str,strseba,strsebb; | ||
| 879 | list<DAE.Subscript> l; | ||
| 880 | Boolean b; | ||
| 881 | |||
| 882 | // no subscripts | ||
| 883 | case (s,{}) then s; | ||
| 884 | |||
| 885 | // some subscripts, Modelica output | ||
| 886 | // some subscripts, non Modelica output | ||
| 887 | case (s,l) | ||
| 888 | algorithm | ||
| 889 | 482450 | b := Config.modelicaOutput(); | |
| 890 | 482450 | str := ExpressionBasics.printListStr(l, ExpressionBasics.printSubscriptStr, ","); | |
| 891 |
1/2✓ Branch 0 taken 482450 times.
✗ Branch 1 not taken.
|
964900 | (strseba,strsebb) := if b then ("_L","_R") else ("[","]"); |
| 892 | 482450 | str := stringAppendList({s, strseba, str, strsebb}); | |
| 893 | then | ||
| 894 | str; | ||
| 895 | |||
| 896 | end match; | ||
| 897 | end printComponentRef2Str; | ||
| 898 | |||
| 899 | public function printComponentRefListStr | ||
| 900 | input list<DAE.ComponentRef> crs; | ||
| 901 | output String res; | ||
| 902 | algorithm | ||
| 903 | ✗ | res := "{" + stringDelimitList(List.map(crs, printComponentRefStr), ",") + "}"; | |
| 904 | end printComponentRefListStr; | ||
| 905 | |||
| 906 | public constant Integer crefHashSeed = 5381; | ||
| 907 | |||
| 908 | public function crefHasNoSubscripts | ||
| 909 | "A chain of qualifiers and an identifier none of which has subscripts, so a | ||
| 910 | traversal of the expressions in it has nothing to visit." | ||
| 911 | input DAE.ComponentRef cr; | ||
| 912 | output Boolean b; | ||
| 913 | algorithm | ||
| 914 | b := match cr | ||
| 915 | 166382281 | case DAE.CREF_QUAL(subscriptLst = {}) then crefHasNoSubscripts(cr.componentRef); | |
| 916 | case DAE.CREF_IDENT(subscriptLst = {}) then true; | ||
| 917 | else false; | ||
| 918 | end match; | ||
| 919 | end crefHasNoSubscripts; | ||
| 920 | |||
| 921 | public function hashComponentRef | ||
| 922 | "djb2 continued over the qualifiers and subscripts in order." | ||
| 923 | input DAE.ComponentRef cr; | ||
| 924 | output Integer hash = hashComponentRefFrom(cr, crefHashSeed); | ||
| 925 | end hashComponentRef; | ||
| 926 | |||
| 927 | protected function hashComponentRefFrom | ||
| 928 | input DAE.ComponentRef cr; | ||
| 929 | input Integer hash; | ||
| 930 | output Integer outHash; | ||
| 931 | algorithm | ||
| 932 | outHash := match cr | ||
| 933 | 61391839 | case DAE.CREF_IDENT() then crefHashSubscripts(cr.subscriptLst, crefHashIdent(cr.ident, hash)); | |
| 934 | 123830435 | case DAE.CREF_QUAL() then hashComponentRefFrom(cr.componentRef, crefHashSubscripts(cr.subscriptLst, crefHashIdent(cr.ident, hash))); | |
| 935 | else hash; | ||
| 936 | end match; | ||
| 937 | end hashComponentRefFrom; | ||
| 938 | |||
| 939 | public function crefHashIdent | ||
| 940 | input String ident; | ||
| 941 | input Integer hash; | ||
| 942 | output Integer outHash = stringHashDjb2Continue(ident, stringHashDjb2Continue(".", hash)); | ||
| 943 | end crefHashIdent; | ||
| 944 | |||
| 945 | protected function crefHashSubscripts | ||
| 946 | input list<DAE.Subscript> subs; | ||
| 947 | input output Integer hash; | ||
| 948 | algorithm | ||
| 949 |
2/2✓ Branch 0 taken 38662580 times.
✓ Branch 1 taken 185222274 times.
|
223884854 | for sub in subs loop |
| 950 | 38662580 | hash := crefHashSubscript(sub, hash); | |
| 951 | end for; | ||
| 952 | end crefHashSubscripts; | ||
| 953 | |||
| 954 | public function crefHashSubscript | ||
| 955 | input DAE.Subscript sub; | ||
| 956 | input Integer hash; | ||
| 957 | output Integer outHash = intHashDjb2Continue(hashSubscript(sub), stringHashDjb2Continue("[", hash)); | ||
| 958 | end crefHashSubscript; | ||
| 959 | |||
| 960 | public function hashSubscript "help function" | ||
| 961 | input DAE.Subscript sub; | ||
| 962 | output Integer hash; | ||
| 963 | algorithm | ||
| 964 | hash := match sub | ||
| 965 | local | ||
| 966 | DAE.Exp exp; | ||
| 967 | Integer i; | ||
| 968 | |||
| 969 | case DAE.WHOLEDIM() then 0; | ||
| 970 | case DAE.INDEX(DAE.ICONST(i)) then i; | ||
| 971 | 538 | case DAE.SLICE(exp) then ExpressionBasics.hashExp(exp); | |
| 972 | 114950 | case DAE.INDEX(exp) then ExpressionBasics.hashExp(exp); | |
| 973 | ✗ | case DAE.WHOLE_NONEXP(exp) then ExpressionBasics.hashExp(exp); | |
| 974 | end match; | ||
| 975 | end hashSubscript; | ||
| 976 | |||
| 977 | annotation(__OpenModelica_Interface="frontend_dump"); | ||
| 978 | end ComponentReferenceBasics; | ||
| 979 |