OMCompiler/Compiler/FrontEnd/NFSCodeFlattenImports.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 NFSCodeFlattenImports | ||
| 37 | " file: NFSCodeFlattenImports.mo | ||
| 38 | package: NFSCodeFlattenImports | ||
| 39 | description: SCode flattening | ||
| 40 | |||
| 41 | |||
| 42 | This module flattens the SCode representation by removing all extends, imports | ||
| 43 | and redeclares, and fully qualifying class names. | ||
| 44 | " | ||
| 45 | |||
| 46 | public import Absyn; | ||
| 47 | public import AbsynUtil; | ||
| 48 | public import SCode; | ||
| 49 | public import NFSCodeEnv; | ||
| 50 | |||
| 51 | public type Env = NFSCodeEnv.Env; | ||
| 52 | |||
| 53 | protected import Debug; | ||
| 54 | protected import Error; | ||
| 55 | protected import Flags; | ||
| 56 | protected import List; | ||
| 57 | protected import NFSCodeLookup; | ||
| 58 | protected import System; | ||
| 59 | import SCodeUtil; | ||
| 60 | |||
| 61 | protected type Item = NFSCodeEnv.Item; | ||
| 62 | protected type Extends = NFSCodeEnv.Extends; | ||
| 63 | protected type FrameType = NFSCodeEnv.FrameType; | ||
| 64 | protected type Import = Absyn.Import; | ||
| 65 | |||
| 66 | public function flattenProgram | ||
| 67 | input SCode.Program inProgram; | ||
| 68 | input Env inEnv; | ||
| 69 | output SCode.Program outProgram; | ||
| 70 | output Env outEnv; | ||
| 71 | algorithm | ||
| 72 | 1087 | (outProgram, outEnv) := List.mapFold(inProgram, flattenClass, inEnv); | |
| 73 | end flattenProgram; | ||
| 74 | |||
| 75 | public function flattenClass | ||
| 76 | input SCode.Element inClass; | ||
| 77 | input Env inEnv; | ||
| 78 | output SCode.Element outClass; | ||
| 79 | output Env outEnv; | ||
| 80 | algorithm | ||
| 81 | (outClass, outEnv) := matchcontinue inClass | ||
| 82 | local | ||
| 83 | SCode.Ident name; | ||
| 84 | SCode.ClassDef cdef; | ||
| 85 | SourceInfo info; | ||
| 86 | Item item; | ||
| 87 | Env env; | ||
| 88 | NFSCodeEnv.Frame cls_env; | ||
| 89 | SCode.Element cls; | ||
| 90 | NFSCodeEnv.ClassType cls_ty; | ||
| 91 | |||
| 92 | case SCode.CLASS(name = name, classDef = cdef, info = info) | ||
| 93 | algorithm | ||
| 94 |
3/6✗ Branch 1 not taken.
✓ Branch 2 taken 17314 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17314 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17314 times.
|
17314 | (NFSCodeEnv.CLASS(env = {cls_env}, classType = cls_ty), _) := |
| 95 | NFSCodeLookup.lookupInClass(name, inEnv); | ||
| 96 | 17314 | env := NFSCodeEnv.enterFrame(cls_env, inEnv); | |
| 97 | |||
| 98 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17314 times.
|
17314 | (cdef, cls_env :: env) := flattenClassDef(cdef, env, info); |
| 99 | 17314 | cls := SCodeUtil.setClassDef(cdef, inClass); | |
| 100 | 17314 | item := NFSCodeEnv.newClassItem(cls, {cls_env}, cls_ty); | |
| 101 | 17314 | env := NFSCodeEnv.updateItemInEnv(item, env, name); | |
| 102 | then | ||
| 103 | (cls, env); | ||
| 104 | |||
| 105 | else | ||
| 106 | algorithm | ||
| 107 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 108 | ✗ | Debug.traceln("- NFSCodeFlattenImports.flattenClass failed on " + | |
| 109 | SCodeUtil.elementName(inClass) + " in " + NFSCodeEnv.getEnvName(inEnv)); | ||
| 110 | ✗ | then | |
| 111 | fail(); | ||
| 112 | end matchcontinue; | ||
| 113 | end flattenClass; | ||
| 114 | |||
| 115 | protected function flattenClassDef | ||
| 116 | input SCode.ClassDef inClassDef; | ||
| 117 | input Env inEnv; | ||
| 118 | input SourceInfo inInfo; | ||
| 119 | output SCode.ClassDef outClassDef; | ||
| 120 | output Env outEnv; | ||
| 121 | algorithm | ||
| 122 | (outClassDef, outEnv) := match(inClassDef, inEnv) | ||
| 123 | local | ||
| 124 | list<SCode.Element> el; | ||
| 125 | list<SCode.Equation> neql, ieql; | ||
| 126 | list<SCode.AlgorithmSection> nal, ial; | ||
| 127 | list<SCode.ConstraintSection> nco; | ||
| 128 | list<Absyn.NamedArg> clats; //class attributes | ||
| 129 | Option<SCode.ExternalDecl> extdecl; | ||
| 130 | Absyn.TypeSpec ty; | ||
| 131 | SCode.Mod mods; | ||
| 132 | SCode.Attributes attr; | ||
| 133 | Env env; | ||
| 134 | SCode.ClassDef cdef; | ||
| 135 | |||
| 136 | case (SCode.PARTS(el, neql, ieql, nal, ial, nco, clats, extdecl), _) | ||
| 137 | algorithm | ||
| 138 | // Lookup elements. | ||
| 139 | 14139 | el := List.filterOnTrue(el, isNotImport); | |
| 140 | 14139 | (el, env) := List.mapFold(el, flattenElement, inEnv); | |
| 141 | |||
| 142 | // Lookup equations and algorithm names. | ||
| 143 | 14139 | neql := List.map1(neql, flattenEquation, env); | |
| 144 | 14139 | ieql := List.map1(ieql, flattenEquation, env); | |
| 145 | 14139 | nal := List.map1(nal, flattenAlgorithm, env); | |
| 146 | 14139 | ial := List.map1(ial, flattenAlgorithm, env); | |
| 147 | 14139 | nco := List.map2(nco, flattenConstraints, env, inInfo); | |
| 148 | 14139 | then | |
| 149 | (SCode.PARTS(el, neql, ieql, nal, ial, nco, clats, extdecl), env); | ||
| 150 | |||
| 151 | case (SCode.CLASS_EXTENDS(mods, cdef), _) | ||
| 152 | algorithm | ||
| 153 | 563 | (cdef, env) := flattenClassDef(cdef, inEnv, inInfo); | |
| 154 | 563 | mods := flattenModifier(mods, env, inInfo); | |
| 155 | 563 | then | |
| 156 | (SCode.CLASS_EXTENDS(mods, cdef), env); | ||
| 157 | |||
| 158 | case (SCode.DERIVED(ty, mods, attr), env) | ||
| 159 | algorithm | ||
| 160 | 3051 | mods := flattenModifier(mods, env, inInfo); | |
| 161 | // Remove the extends from the local scope before flattening the derived | ||
| 162 | // type, because the type should not be looked up via itself. | ||
| 163 | 3051 | env := NFSCodeEnv.removeExtendsFromLocalScope(env); | |
| 164 | 3051 | ty := flattenTypeSpec(ty, env, inInfo); | |
| 165 | 3051 | then | |
| 166 | (SCode.DERIVED(ty, mods, attr), inEnv); | ||
| 167 | |||
| 168 | else (inClassDef, inEnv); | ||
| 169 | end match; | ||
| 170 | end flattenClassDef; | ||
| 171 | |||
| 172 | protected function flattenDerivedClassDef | ||
| 173 | input SCode.ClassDef inClassDef; | ||
| 174 | input Env inEnv; | ||
| 175 | input SourceInfo inInfo; | ||
| 176 | output SCode.ClassDef outClassDef; | ||
| 177 | protected | ||
| 178 | Absyn.TypeSpec ty; | ||
| 179 | SCode.Mod mods; | ||
| 180 | SCode.Attributes attr; | ||
| 181 | algorithm | ||
| 182 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 150 times.
|
150 | SCode.DERIVED(ty, mods, attr) := inClassDef; |
| 183 | 150 | ty := flattenTypeSpec(ty, inEnv, inInfo); | |
| 184 | 150 | mods := flattenModifier(mods, inEnv, inInfo); | |
| 185 | 150 | outClassDef := SCode.DERIVED(ty, mods, attr); | |
| 186 | end flattenDerivedClassDef; | ||
| 187 | |||
| 188 | protected function isNotImport | ||
| 189 | input SCode.Element inElement; | ||
| 190 | output Boolean outB; | ||
| 191 | algorithm | ||
| 192 | outB := match inElement | ||
| 193 | case SCode.IMPORT() then false; | ||
| 194 | else true; | ||
| 195 | end match; | ||
| 196 | end isNotImport; | ||
| 197 | |||
| 198 | protected function flattenElement | ||
| 199 | input SCode.Element inElement; | ||
| 200 | input Env inEnv; | ||
| 201 | output SCode.Element outElement; | ||
| 202 | output Env outEnv; | ||
| 203 | algorithm | ||
| 204 | (outElement, outEnv) := match inElement | ||
| 205 | local | ||
| 206 | Env env; | ||
| 207 | SCode.Element elem; | ||
| 208 | String name; | ||
| 209 | Item item; | ||
| 210 | |||
| 211 | // Lookup component types, modifications and conditions. | ||
| 212 | case SCode.COMPONENT(name = name) | ||
| 213 | algorithm | ||
| 214 | 50231 | elem := flattenComponent(inElement, inEnv); | |
| 215 | 50231 | item := NFSCodeEnv.newVarItem(elem, true); | |
| 216 | 50231 | env := NFSCodeEnv.updateItemInEnv(item, inEnv, name); | |
| 217 | 50231 | then | |
| 218 | (elem, env); | ||
| 219 | |||
| 220 | // Lookup class definitions. | ||
| 221 | case SCode.CLASS() | ||
| 222 | algorithm | ||
| 223 | 15570 | (elem, env) := flattenClass(inElement, inEnv); | |
| 224 | then | ||
| 225 | (elem, env); | ||
| 226 | |||
| 227 | // Lookup base class and modifications in extends clauses. | ||
| 228 | case SCode.EXTENDS() | ||
| 229 | 9228 | then (flattenExtends(inElement, inEnv), inEnv); | |
| 230 | |||
| 231 | ✗ | else (inElement, inEnv); | |
| 232 | end match; | ||
| 233 | end flattenElement; | ||
| 234 | |||
| 235 | protected function flattenComponent | ||
| 236 | input SCode.Element inComponent; | ||
| 237 | input Env inEnv; | ||
| 238 | output SCode.Element outComponent; | ||
| 239 | protected | ||
| 240 | SCode.Ident name; | ||
| 241 | SCode.Prefixes prefixes; | ||
| 242 | SCode.Attributes attr; | ||
| 243 | Absyn.TypeSpec type_spec; | ||
| 244 | SCode.Mod mod; | ||
| 245 | SCode.Comment cmt; | ||
| 246 | Option<Absyn.Exp> cond; | ||
| 247 | SourceInfo info; | ||
| 248 | algorithm | ||
| 249 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50274 times.
|
50274 | SCode.COMPONENT(name, prefixes, attr, type_spec, mod, cmt, cond, info) := inComponent; |
| 250 | 50274 | attr := flattenAttributes(attr, inEnv, info); | |
| 251 | 50274 | type_spec := flattenTypeSpec(type_spec, inEnv, info); | |
| 252 | 50274 | mod := flattenModifier(mod, inEnv, info); | |
| 253 | 50274 | cond := flattenOptExp(cond, inEnv, info); | |
| 254 | 50274 | outComponent := SCode.COMPONENT(name, prefixes, attr, type_spec, mod, cmt, cond, info); | |
| 255 | end flattenComponent; | ||
| 256 | |||
| 257 | protected function flattenAttributes | ||
| 258 | input SCode.Attributes inAttributes; | ||
| 259 | input Env inEnv; | ||
| 260 | input SourceInfo inInfo; | ||
| 261 | output SCode.Attributes outAttributes; | ||
| 262 | protected | ||
| 263 | Absyn.ArrayDim ad; | ||
| 264 | SCode.ConnectorType ct; | ||
| 265 | SCode.Parallelism prl; | ||
| 266 | SCode.Variability var; | ||
| 267 | Absyn.Direction dir; | ||
| 268 | Absyn.IsField isf; | ||
| 269 | algorithm | ||
| 270 | 50274 | SCode.ATTR(ad, ct, prl, var, dir, isf) := inAttributes; | |
| 271 | 50274 | ad := List.map2(ad, flattenSubscript, inEnv, inInfo); | |
| 272 | 50274 | outAttributes := SCode.ATTR(ad, ct, prl, var, dir, isf); | |
| 273 | end flattenAttributes; | ||
| 274 | |||
| 275 | protected function flattenTypeSpec | ||
| 276 | input Absyn.TypeSpec inTypeSpec; | ||
| 277 | input Env inEnv; | ||
| 278 | input SourceInfo inInfo; | ||
| 279 | output Absyn.TypeSpec outTypeSpec; | ||
| 280 | algorithm | ||
| 281 | outTypeSpec := match inTypeSpec | ||
| 282 | local | ||
| 283 | Absyn.Path path; | ||
| 284 | Option<Absyn.ArrayDim> ad; | ||
| 285 | list<Absyn.TypeSpec> tys; | ||
| 286 | |||
| 287 | // A normal type. | ||
| 288 | case Absyn.TPATH(path = path, arrayDim = ad) | ||
| 289 | algorithm | ||
| 290 | 53472 | (_, path, _) := NFSCodeLookup.lookupClassName(path, inEnv, inInfo); | |
| 291 | 53472 | then | |
| 292 | Absyn.TPATH(path, ad); | ||
| 293 | |||
| 294 | // A polymorphic type, i.e. replaceable type Type subtypeof Any. | ||
| 295 | case Absyn.TCOMPLEX(path = Absyn.IDENT("polymorphic")) | ||
| 296 | then inTypeSpec; | ||
| 297 | |||
| 298 | // A MetaModelica type such as list or tuple. | ||
| 299 | case Absyn.TCOMPLEX(path = path, typeSpecs = tys, arrayDim = ad) | ||
| 300 | algorithm | ||
| 301 | 7 | tys := List.map2(tys, flattenTypeSpec, inEnv, inInfo); | |
| 302 | 7 | then | |
| 303 | Absyn.TCOMPLEX(path, tys, ad); | ||
| 304 | |||
| 305 | end match; | ||
| 306 | end flattenTypeSpec; | ||
| 307 | |||
| 308 | protected function flattenExtends | ||
| 309 | input SCode.Element inExtends; | ||
| 310 | input Env inEnv; | ||
| 311 | output SCode.Element outExtends; | ||
| 312 | protected | ||
| 313 | Absyn.Path path; | ||
| 314 | SCode.Mod mod; | ||
| 315 | Option<SCode.Annotation> ann; | ||
| 316 | SourceInfo info; | ||
| 317 | Env env; | ||
| 318 | SCode.Visibility vis; | ||
| 319 | algorithm | ||
| 320 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9228 times.
|
9228 | SCode.EXTENDS(path, vis, mod, ann, info) := inExtends; |
| 321 | 9228 | env := NFSCodeEnv.removeExtendsFromLocalScope(inEnv); | |
| 322 | 9228 | (_, path, _) := NFSCodeLookup.lookupBaseClassName(path, env, info); | |
| 323 | 9228 | mod := flattenModifier(mod, inEnv, info); | |
| 324 | 9228 | outExtends := SCode.EXTENDS(path, vis, mod, ann, info); | |
| 325 | end flattenExtends; | ||
| 326 | |||
| 327 | protected function flattenEquation | ||
| 328 | input SCode.Equation inEquation; | ||
| 329 | input Env inEnv; | ||
| 330 | output SCode.Equation outEquation; | ||
| 331 | algorithm | ||
| 332 | 8312 | (outEquation, _) := SCodeUtil.mapFoldEquations(inEquation, flattenEquationTraverser, inEnv); | |
| 333 | end flattenEquation; | ||
| 334 | |||
| 335 | protected function flattenEquationTraverser | ||
| 336 | input output SCode.Equation eq; | ||
| 337 | input output Env env; | ||
| 338 | algorithm | ||
| 339 | (eq, env) := match eq | ||
| 340 | local | ||
| 341 | SCode.Ident iter_name; | ||
| 342 | SourceInfo info; | ||
| 343 | Absyn.ComponentRef cref; | ||
| 344 | SCode.Comment cmt; | ||
| 345 | Absyn.Exp crefExp, exp; | ||
| 346 | |||
| 347 | case SCode.EQ_FOR(index = iter_name, info = info) | ||
| 348 | algorithm | ||
| 349 | 370 | env := NFSCodeEnv.extendEnvWithIterators({Absyn.ITERATOR(iter_name, NONE(), NONE())}, System.tmpTickIndex(NFSCodeEnv.tmpTickIndex), env); | |
| 350 | 185 | (eq, _) := SCodeUtil.mapFoldEquationExps(eq, traverseExp, (env, info)); | |
| 351 | then | ||
| 352 | (eq, env); | ||
| 353 | |||
| 354 | case SCode.EQ_REINIT(cref = crefExp as Absyn.CREF(componentRef = cref), expReinit = exp, comment = cmt, info = info) | ||
| 355 | algorithm | ||
| 356 | 15 | cref := NFSCodeLookup.lookupComponentRef(cref, env, info); | |
| 357 | 15 | eq := SCode.EQ_REINIT(crefExp, exp, cmt, info); | |
| 358 | 15 | (eq, _) := SCodeUtil.mapFoldEquationExps(eq, traverseExp, (env, info)); | |
| 359 | then | ||
| 360 | (eq, env); | ||
| 361 | |||
| 362 | else | ||
| 363 | algorithm | ||
| 364 | 10446 | info := SCodeUtil.getEquationInfo(eq); | |
| 365 | 10446 | (eq, _) := SCodeUtil.mapFoldEquationExps(eq, traverseExp, (env, info)); | |
| 366 | then | ||
| 367 | (eq, env); | ||
| 368 | |||
| 369 | end match; | ||
| 370 | end flattenEquationTraverser; | ||
| 371 | |||
| 372 | protected function traverseExp | ||
| 373 | input Absyn.Exp inExp; | ||
| 374 | input tuple<Env, SourceInfo> inTuple; | ||
| 375 | output Absyn.Exp outExp; | ||
| 376 | output tuple<Env, SourceInfo> outTuple; | ||
| 377 | algorithm | ||
| 378 | 77441 | (outExp, outTuple) := AbsynUtil.traverseExpBidir(inExp, flattenExpTraverserEnter, flattenExpTraverserExit, inTuple); | |
| 379 | end traverseExp; | ||
| 380 | |||
| 381 | protected function flattenConstraints | ||
| 382 | input SCode.ConstraintSection inConstraints; | ||
| 383 | input Env inEnv; | ||
| 384 | input SourceInfo inInfo; | ||
| 385 | output SCode.ConstraintSection outConstraints; | ||
| 386 | protected | ||
| 387 | list<Absyn.Exp> exps; | ||
| 388 | algorithm | ||
| 389 | 3 | SCode.CONSTRAINTS(exps) := inConstraints; | |
| 390 | 3 | exps := List.map2(exps, flattenExp, inEnv, inInfo); | |
| 391 | 3 | outConstraints := SCode.CONSTRAINTS(exps); | |
| 392 | end flattenConstraints; | ||
| 393 | |||
| 394 | protected function flattenAlgorithm | ||
| 395 | input SCode.AlgorithmSection inAlgorithm; | ||
| 396 | input Env inEnv; | ||
| 397 | output SCode.AlgorithmSection outAlgorithm; | ||
| 398 | protected | ||
| 399 | list<SCode.Statement> statements; | ||
| 400 | algorithm | ||
| 401 | 4651 | SCode.ALGORITHM(statements) := inAlgorithm; | |
| 402 | 4651 | statements := List.map1(statements, flattenStatement, inEnv); | |
| 403 | 4651 | outAlgorithm := SCode.ALGORITHM(statements); | |
| 404 | end flattenAlgorithm; | ||
| 405 | |||
| 406 | protected function flattenStatement | ||
| 407 | input SCode.Statement inStatement; | ||
| 408 | input Env inEnv; | ||
| 409 | output SCode.Statement outStatement; | ||
| 410 | algorithm | ||
| 411 | 19265 | (outStatement, _) := SCodeUtil.mapFoldStatements(inStatement, flattenStatementTraverser, inEnv); | |
| 412 | end flattenStatement; | ||
| 413 | |||
| 414 | protected function flattenStatementTraverser | ||
| 415 | input output SCode.Statement stmt; | ||
| 416 | input output Env env; | ||
| 417 | algorithm | ||
| 418 | (stmt, env) := match stmt | ||
| 419 | local | ||
| 420 | String iter_name; | ||
| 421 | SourceInfo info; | ||
| 422 | |||
| 423 | case SCode.ALG_FOR(index = iter_name, info = info) | ||
| 424 | algorithm | ||
| 425 | 392 | env := NFSCodeEnv.extendEnvWithIterators({Absyn.ITERATOR(iter_name, NONE(), NONE())}, System.tmpTickIndex(NFSCodeEnv.tmpTickIndex), env); | |
| 426 | 196 | (stmt, _) := SCodeUtil.mapFoldStatementExps(stmt, traverseExp, (env, info)); | |
| 427 | then | ||
| 428 | (stmt, env); | ||
| 429 | |||
| 430 | case SCode.ALG_PARFOR(index = iter_name, info = info) | ||
| 431 | algorithm | ||
| 432 | ✗ | env := NFSCodeEnv.extendEnvWithIterators({Absyn.ITERATOR(iter_name, NONE(), NONE())}, System.tmpTickIndex(NFSCodeEnv.tmpTickIndex), env); | |
| 433 | ✗ | (stmt, _) := SCodeUtil.mapFoldStatementExps(stmt, traverseExp, (env, info)); | |
| 434 | then | ||
| 435 | (stmt, env); | ||
| 436 | |||
| 437 | else | ||
| 438 | algorithm | ||
| 439 | 30356 | info := SCodeUtil.getStatementInfo(stmt); | |
| 440 | 30356 | (stmt, _) := SCodeUtil.mapFoldStatementExps(stmt, traverseExp, (env, info)); | |
| 441 | then | ||
| 442 | (stmt, env); | ||
| 443 | |||
| 444 | end match; | ||
| 445 | end flattenStatementTraverser; | ||
| 446 | |||
| 447 | protected function flattenModifier | ||
| 448 | input SCode.Mod inMod; | ||
| 449 | input Env inEnv; | ||
| 450 | input SourceInfo inInfo; | ||
| 451 | output SCode.Mod outMod; | ||
| 452 | algorithm | ||
| 453 | outMod := match inMod | ||
| 454 | local | ||
| 455 | SCode.Final fp; | ||
| 456 | SCode.Each ep; | ||
| 457 | list<SCode.SubMod> sub_mods; | ||
| 458 | Option<Absyn.Exp> opt_exp; | ||
| 459 | SCode.Element el; | ||
| 460 | SourceInfo info; | ||
| 461 | Option<String> cmt; | ||
| 462 | |||
| 463 | case SCode.MOD(fp, ep, sub_mods, opt_exp, cmt, info) | ||
| 464 | algorithm | ||
| 465 | 69167 | opt_exp := flattenModOptExp(opt_exp, inEnv, inInfo); | |
| 466 | 69167 | sub_mods := List.map2(sub_mods, flattenSubMod, inEnv, inInfo); | |
| 467 | 69167 | then | |
| 468 | SCode.MOD(fp, ep, sub_mods, opt_exp, cmt, info); | ||
| 469 | |||
| 470 | case SCode.REDECL(fp, ep, el) | ||
| 471 | algorithm | ||
| 472 | 194 | el := flattenRedeclare(el, inEnv); | |
| 473 | 194 | then | |
| 474 | SCode.REDECL(fp, ep, el); | ||
| 475 | |||
| 476 | case SCode.NOMOD() then inMod; | ||
| 477 | end match; | ||
| 478 | end flattenModifier; | ||
| 479 | |||
| 480 | protected function flattenModOptExp | ||
| 481 | input Option<Absyn.Exp> inOptExp; | ||
| 482 | input Env inEnv; | ||
| 483 | input SourceInfo inInfo; | ||
| 484 | output Option<Absyn.Exp> outOptExp; | ||
| 485 | algorithm | ||
| 486 | outOptExp := match inOptExp | ||
| 487 | local | ||
| 488 | Absyn.Exp exp; | ||
| 489 | |||
| 490 | case SOME(exp) | ||
| 491 | algorithm | ||
| 492 | 58160 | exp := flattenExp(exp, inEnv, inInfo); | |
| 493 | then | ||
| 494 | SOME(exp); | ||
| 495 | |||
| 496 | else inOptExp; | ||
| 497 | end match; | ||
| 498 | end flattenModOptExp; | ||
| 499 | |||
| 500 | protected function flattenSubMod | ||
| 501 | input SCode.SubMod inSubMod; | ||
| 502 | input Env inEnv; | ||
| 503 | input SourceInfo inInfo; | ||
| 504 | output SCode.SubMod outSubMod; | ||
| 505 | algorithm | ||
| 506 | outSubMod := match inSubMod | ||
| 507 | local | ||
| 508 | SCode.Ident ident; | ||
| 509 | SCode.Mod mod; | ||
| 510 | |||
| 511 | case SCode.NAMEMOD(ident = ident, mod = mod) | ||
| 512 | algorithm | ||
| 513 | 45185 | mod := flattenModifier(mod, inEnv, inInfo); | |
| 514 | 45185 | then | |
| 515 | SCode.NAMEMOD(ident, mod); | ||
| 516 | |||
| 517 | end match; | ||
| 518 | end flattenSubMod; | ||
| 519 | |||
| 520 | protected function flattenRedeclare | ||
| 521 | input SCode.Element inElement; | ||
| 522 | input Env inEnv; | ||
| 523 | output SCode.Element outElement; | ||
| 524 | algorithm | ||
| 525 | outElement := match inElement | ||
| 526 | local | ||
| 527 | SCode.Ident name; | ||
| 528 | SCode.Prefixes prefixes; | ||
| 529 | SCode.Partial pp; | ||
| 530 | SCode.Encapsulated ep; | ||
| 531 | SCode.Restriction res; | ||
| 532 | SourceInfo info; | ||
| 533 | SCode.Element element; | ||
| 534 | SCode.ClassDef cdef,cdef2; | ||
| 535 | SCode.Comment cmt; | ||
| 536 | |||
| 537 | case SCode.CLASS(name, prefixes, ep, pp, res, | ||
| 538 | cdef as SCode.DERIVED(), cmt, info) | ||
| 539 | algorithm | ||
| 540 | 150 | cdef2 := flattenDerivedClassDef(cdef, inEnv, info); | |
| 541 | 150 | then | |
| 542 | SCode.CLASS(name, prefixes, ep, pp, res, cdef2, cmt, info); | ||
| 543 | |||
| 544 | case SCode.CLASS(classDef = SCode.ENUMERATION()) | ||
| 545 | then | ||
| 546 | inElement; | ||
| 547 | |||
| 548 | case SCode.COMPONENT() | ||
| 549 | algorithm | ||
| 550 | 43 | element := flattenComponent(inElement, inEnv); | |
| 551 | then | ||
| 552 | element; | ||
| 553 | |||
| 554 | else | ||
| 555 | algorithm | ||
| 556 | ✗ | Error.addMessage(Error.INTERNAL_ERROR, | |
| 557 | {"Unknown redeclare in NFSCodeFlattenImports.flattenRedeclare"}); | ||
| 558 | ✗ | then | |
| 559 | fail(); | ||
| 560 | |||
| 561 | end match; | ||
| 562 | end flattenRedeclare; | ||
| 563 | |||
| 564 | protected function flattenSubscript | ||
| 565 | input SCode.Subscript inSub; | ||
| 566 | input Env inEnv; | ||
| 567 | input SourceInfo inInfo; | ||
| 568 | output SCode.Subscript outSub; | ||
| 569 | algorithm | ||
| 570 | outSub := match inSub | ||
| 571 | local | ||
| 572 | Absyn.Exp exp; | ||
| 573 | |||
| 574 | case Absyn.SUBSCRIPT(subscript = exp) | ||
| 575 | algorithm | ||
| 576 | 56168 | exp := flattenExp(exp, inEnv, inInfo); | |
| 577 | 56168 | then | |
| 578 | Absyn.SUBSCRIPT(exp); | ||
| 579 | |||
| 580 | case Absyn.NOSUB() then inSub; | ||
| 581 | end match; | ||
| 582 | end flattenSubscript; | ||
| 583 | |||
| 584 | protected function flattenExp | ||
| 585 | input Absyn.Exp inExp; | ||
| 586 | input Env inEnv; | ||
| 587 | input SourceInfo inInfo; | ||
| 588 | output Absyn.Exp outExp; | ||
| 589 | algorithm | ||
| 590 | 115259 | (outExp, _) := AbsynUtil.traverseExpBidir(inExp, flattenExpTraverserEnter, flattenExpTraverserExit, (inEnv, inInfo)); | |
| 591 | end flattenExp; | ||
| 592 | |||
| 593 | protected function flattenOptExp | ||
| 594 | input Option<Absyn.Exp> inExp; | ||
| 595 | input Env inEnv; | ||
| 596 | input SourceInfo inInfo; | ||
| 597 | output Option<Absyn.Exp> outExp; | ||
| 598 | algorithm | ||
| 599 | outExp := match inExp | ||
| 600 | local | ||
| 601 | Absyn.Exp exp; | ||
| 602 | |||
| 603 | case SOME(exp) | ||
| 604 | algorithm | ||
| 605 | 552 | exp := flattenExp(exp, inEnv, inInfo); | |
| 606 | then | ||
| 607 | SOME(exp); | ||
| 608 | |||
| 609 | else inExp; | ||
| 610 | end match; | ||
| 611 | end flattenOptExp; | ||
| 612 | |||
| 613 | protected function flattenExpTraverserEnter | ||
| 614 | input Absyn.Exp inExp; | ||
| 615 | input tuple<Env, SourceInfo> inTuple; | ||
| 616 | output Absyn.Exp outExp; | ||
| 617 | output tuple<Env, SourceInfo> outTuple; | ||
| 618 | algorithm | ||
| 619 | (outExp,outTuple) := match(inExp,inTuple) | ||
| 620 | local | ||
| 621 | Env env; | ||
| 622 | Absyn.ComponentRef cref; | ||
| 623 | Absyn.FunctionArgs args; | ||
| 624 | Absyn.Exp exp; | ||
| 625 | Absyn.ForIterators iters; | ||
| 626 | SourceInfo info; | ||
| 627 | tuple<Env, SourceInfo> tup; | ||
| 628 | Absyn.ReductionIterType iterType; | ||
| 629 | |||
| 630 | case (Absyn.CREF(componentRef = cref), tup as (env, info)) | ||
| 631 | algorithm | ||
| 632 | 215456 | cref := NFSCodeLookup.lookupComponentRef(cref, env, info); | |
| 633 | 215456 | then | |
| 634 | (Absyn.CREF(cref), tup); | ||
| 635 | |||
| 636 | case (Absyn.CALL(function_ = cref, functionArgs = Absyn.FOR_ITER_FARG(exp = exp, iterType = iterType, iterators = iters)), (env, info)) | ||
| 637 | algorithm | ||
| 638 | 371 | cref := NFSCodeLookup.lookupComponentRef(cref, env, info); | |
| 639 | 371 | env := NFSCodeEnv.extendEnvWithIterators(iters, System.tmpTickIndex(NFSCodeEnv.tmpTickIndex), env); | |
| 640 | 371 | exp := flattenExp(exp, env, info); | |
| 641 | 371 | then | |
| 642 | (Absyn.CALL(cref, Absyn.FOR_ITER_FARG(exp, iterType, iters), inExp.typeVars), (env, info)); | ||
| 643 | |||
| 644 | case (Absyn.CALL(function_ = Absyn.CREF_IDENT(name = "SOME")), _) | ||
| 645 | then (inExp,inTuple); | ||
| 646 | |||
| 647 | case (Absyn.CALL(function_ = cref, functionArgs = args), tup as (env, info)) | ||
| 648 | algorithm | ||
| 649 | 18982 | cref := NFSCodeLookup.lookupComponentRef(cref, env, info); | |
| 650 | // TODO: handle function arguments | ||
| 651 | 18982 | then | |
| 652 | (Absyn.CALL(cref, args, inExp.typeVars), tup); | ||
| 653 | |||
| 654 | case (Absyn.PARTEVALFUNCTION(function_ = cref, functionArgs = args), tup as (env, info)) | ||
| 655 | algorithm | ||
| 656 | 13 | cref := NFSCodeLookup.lookupComponentRef(cref, env, info); | |
| 657 | // TODO: handle function arguments | ||
| 658 | 13 | then | |
| 659 | (Absyn.PARTEVALFUNCTION(cref, args), tup); | ||
| 660 | |||
| 661 | case (exp as Absyn.MATCHEXP(), (env, info)) | ||
| 662 | algorithm | ||
| 663 | 10 | env := NFSCodeEnv.extendEnvWithMatch(exp, System.tmpTickIndex(NFSCodeEnv.tmpTickIndex), env); | |
| 664 | 10 | then | |
| 665 | (exp, (env, info)); | ||
| 666 | else (inExp,inTuple); | ||
| 667 | end match; | ||
| 668 | end flattenExpTraverserEnter; | ||
| 669 | |||
| 670 | protected function flattenExpTraverserExit | ||
| 671 | input Absyn.Exp inExp; | ||
| 672 | input tuple<Env, SourceInfo> inTuple; | ||
| 673 | output Absyn.Exp outExp; | ||
| 674 | output tuple<Env, SourceInfo> outTuple; | ||
| 675 | algorithm | ||
| 676 | (outExp,outTuple) := match(inExp,inTuple) | ||
| 677 | local | ||
| 678 | Env env; | ||
| 679 | SourceInfo info; | ||
| 680 | |||
| 681 | case (Absyn.CALL(functionArgs = Absyn.FOR_ITER_FARG()), | ||
| 682 | (NFSCodeEnv.FRAME(frameType = NFSCodeEnv.IMPLICIT_SCOPE()) :: env, info)) | ||
| 683 | 371 | then | |
| 684 | (inExp, (env, info)); | ||
| 685 | |||
| 686 | case (Absyn.MATCHEXP(), | ||
| 687 | (NFSCodeEnv.FRAME(frameType = NFSCodeEnv.IMPLICIT_SCOPE()) :: env, info)) | ||
| 688 | 10 | then | |
| 689 | (inExp, (env, info)); | ||
| 690 | |||
| 691 | else (inExp,inTuple); | ||
| 692 | end match; | ||
| 693 | end flattenExpTraverserExit; | ||
| 694 | |||
| 695 | public function flattenComponentRefSubs | ||
| 696 | input Absyn.ComponentRef inCref; | ||
| 697 | input Env inEnv; | ||
| 698 | input SourceInfo inInfo; | ||
| 699 | output Absyn.ComponentRef outCref; | ||
| 700 | algorithm | ||
| 701 | outCref := match inCref | ||
| 702 | local | ||
| 703 | Absyn.Ident name; | ||
| 704 | Absyn.ComponentRef cref; | ||
| 705 | list<Absyn.Subscript> subs; | ||
| 706 | |||
| 707 | case Absyn.CREF_IDENT(name, subs) | ||
| 708 | algorithm | ||
| 709 | 234315 | subs := List.map2(subs, flattenSubscript, inEnv, inInfo); | |
| 710 | 234315 | then | |
| 711 | Absyn.CREF_IDENT(name, subs); | ||
| 712 | |||
| 713 | case Absyn.CREF_QUAL(name, subs, cref) | ||
| 714 | algorithm | ||
| 715 | 71844 | subs := List.map2(subs, flattenSubscript, inEnv, inInfo); | |
| 716 | 71844 | cref := flattenComponentRefSubs(cref, inEnv, inInfo); | |
| 717 | 71844 | then | |
| 718 | Absyn.CREF_QUAL(name, subs, cref); | ||
| 719 | |||
| 720 | case Absyn.CREF_FULLYQUALIFIED(componentRef = cref) | ||
| 721 | algorithm | ||
| 722 | 1587 | cref := flattenComponentRefSubs(cref, inEnv, inInfo); | |
| 723 | 1587 | then | |
| 724 | AbsynUtil.crefMakeFullyQualified(cref); | ||
| 725 | |||
| 726 | end match; | ||
| 727 | end flattenComponentRefSubs; | ||
| 728 | |||
| 729 | annotation(__OpenModelica_Interface="frontend"); | ||
| 730 | end NFSCodeFlattenImports; | ||
| 731 |