OMCompiler/Compiler/NFFrontEnd/NFConvertDAE.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 NFConvertDAE | ||
| 37 | |||
| 38 | import Binding = NFBinding; | ||
| 39 | import DAE; | ||
| 40 | import Equation = NFEquation; | ||
| 41 | import FlatModel = NFFlatModel; | ||
| 42 | import NFFlatten.FunctionTree; | ||
| 43 | import NFInstNode.InstNode; | ||
| 44 | import Statement = NFStatement; | ||
| 45 | import Restriction = NFRestriction; | ||
| 46 | |||
| 47 | protected | ||
| 48 | |||
| 49 | import Algorithm = NFAlgorithm; | ||
| 50 | import Attributes = NFAttributes; | ||
| 51 | import AbsynUtil; | ||
| 52 | import AvlTreePathFunction; | ||
| 53 | import Call = NFCall; | ||
| 54 | import ComponentReferenceBasics; | ||
| 55 | import ComponentRef = NFComponentRef; | ||
| 56 | import Dimension = NFDimension; | ||
| 57 | import ElementSource; | ||
| 58 | import ExecStat.execStat; | ||
| 59 | import Expression = NFExpression; | ||
| 60 | import Flags; | ||
| 61 | import Flatten = NFFlatten; | ||
| 62 | import Function = NFFunction.Function; | ||
| 63 | import MetaModelica.Dangerous.listReverseInPlace; | ||
| 64 | import Class = NFClass; | ||
| 65 | import NFClassTree.ClassTree; | ||
| 66 | import Component = NFComponent; | ||
| 67 | import NFModifier.Modifier; | ||
| 68 | import NFPrefixes.ConnectorType; | ||
| 69 | import NFPrefixes.Direction; | ||
| 70 | import NFPrefixes.Variability; | ||
| 71 | import NFPrefixes.Visibility; | ||
| 72 | import Prefixes = NFPrefixes; | ||
| 73 | import Sections = NFSections; | ||
| 74 | import SCode; | ||
| 75 | import Type = NFType; | ||
| 76 | import Util; | ||
| 77 | import Variable = NFVariable; | ||
| 78 | |||
| 79 | public | ||
| 80 | function convert | ||
| 81 | input FlatModel flatModel; | ||
| 82 | input FunctionTree functions; | ||
| 83 | output DAE.DAElist dae; | ||
| 84 | output AvlTreePathFunction.Tree daeFunctions; | ||
| 85 | protected | ||
| 86 | algorithm | ||
| 87 | 1366 | daeFunctions := convertFunctionTree(functions); | |
| 88 | 1366 | dae := convertModel(flatModel); | |
| 89 | 1366 | execStat(getInstanceName()); | |
| 90 | end convert; | ||
| 91 | |||
| 92 | function convertModel | ||
| 93 | input FlatModel flatModel; | ||
| 94 | output DAE.DAElist dae; | ||
| 95 | protected | ||
| 96 | list<DAE.Element> elems; | ||
| 97 | DAE.Element class_elem; | ||
| 98 | algorithm | ||
| 99 | 1374 | elems := convertVariables(flatModel.variables, {}); | |
| 100 | 1374 | elems := convertEquations(flatModel.equations, elems); | |
| 101 | 1374 | elems := convertInitialEquations(flatModel.initialEquations, elems); | |
| 102 | 1374 | elems := convertAlgorithms(flatModel.algorithms, elems); | |
| 103 | 1374 | elems := convertInitialAlgorithms(flatModel.initialAlgorithms, elems); | |
| 104 | |||
| 105 | 1374 | class_elem := DAE.COMP(FlatModel.fullName(flatModel), elems, flatModel.source, ElementSource.getOptComment(flatModel.source)); | |
| 106 | 1374 | dae := DAE.DAE({class_elem}); | |
| 107 | end convertModel; | ||
| 108 | |||
| 109 | function convertStatements | ||
| 110 | input list<Statement> statements; | ||
| 111 | output list<DAE.Statement> elements; | ||
| 112 | algorithm | ||
| 113 |
4/4✓ Branch 0 taken 95217 times.
✓ Branch 1 taken 21156 times.
✓ Branch 2 taken 95217 times.
✓ Branch 3 taken 21156 times.
|
116373 | elements := list(convertStatement(s) for s in statements); |
| 114 | end convertStatements; | ||
| 115 | |||
| 116 | protected | ||
| 117 | uniontype VariableConversionSettings | ||
| 118 | record VARIABLE_CONVERSION_SETTINGS | ||
| 119 | Boolean isFunctionParameter; | ||
| 120 | Boolean addTypeToSource; | ||
| 121 | end VARIABLE_CONVERSION_SETTINGS; | ||
| 122 | end VariableConversionSettings; | ||
| 123 | |||
| 124 | constant VariableConversionSettings FUNCTION_VARIABLE_CONVERSION_SETTINGS = | ||
| 125 | VARIABLE_CONVERSION_SETTINGS(true, false); | ||
| 126 | |||
| 127 | function convertVariables | ||
| 128 | input list<Variable> variables; | ||
| 129 | input output list<DAE.Element> elements; | ||
| 130 | protected | ||
| 131 | VariableConversionSettings settings; | ||
| 132 | ComponentRef rest, last_rest = ComponentRef.EMPTY(); | ||
| 133 | Boolean encrypted, rest_encrypted = false; | ||
| 134 | algorithm | ||
| 135 |
4/4✓ Branch 1 taken 1371 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1368 times.
|
1377 | settings := VariableConversionSettings.VARIABLE_CONVERSION_SETTINGS( |
| 136 | isFunctionParameter = false, | ||
| 137 | addTypeToSource = Flags.isSet(Flags.INFO_XML_OPERATIONS) or Flags.isSet(Flags.VISUAL_XML) | ||
| 138 | ); | ||
| 139 | |||
| 140 |
2/2✓ Branch 1 taken 373309 times.
✓ Branch 2 taken 1374 times.
|
374683 | for var in listReverse(variables) loop |
| 141 | // The variables of an instance share its name as their prefix. | ||
| 142 |
1/2✓ Branch 1 taken 373309 times.
✗ Branch 2 not taken.
|
373309 | if ComponentRef.isCref(var.name) then |
| 143 | 373309 | rest := ComponentRef.rest(var.name); | |
| 144 |
2/2✓ Branch 0 taken 52144 times.
✓ Branch 1 taken 321165 times.
|
373309 | if not referenceEq(rest, last_rest) then |
| 145 | last_rest := rest; | ||
| 146 | 52144 | rest_encrypted := Variable.isEncryptedName(rest); | |
| 147 | end if; | ||
| 148 |
2/4✓ Branch 0 taken 373309 times.
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 373309 times.
|
373309 | encrypted := rest_encrypted or Variable.isEncryptedNode(ComponentRef.node(var.name)); |
| 149 | else | ||
| 150 | encrypted := false; | ||
| 151 | end if; | ||
| 152 | |||
| 153 | 373309 | elements := convertVariable(var, settings, encrypted) :: elements; | |
| 154 | end for; | ||
| 155 | end convertVariables; | ||
| 156 | |||
| 157 | function convertVariable | ||
| 158 | input Variable var; | ||
| 159 | input VariableConversionSettings settings; | ||
| 160 | input Boolean encrypted; | ||
| 161 | output DAE.Element daeVar; | ||
| 162 | protected | ||
| 163 | Option<DAE.VariableAttributes> var_attr; | ||
| 164 | Option<DAE.Exp> binding_exp; | ||
| 165 | algorithm | ||
| 166 | 373309 | binding_exp := Binding.toDAEExp(var.binding); | |
| 167 | 373309 | var_attr := convertVarAttributes(var.typeAttributes, var.ty, var.attributes); | |
| 168 | 373309 | daeVar := makeDAEVar(var.name, var.ty, binding_exp, var.attributes, | |
| 169 | var.visibility, var_attr, var.comment, settings, var.info, encrypted); | ||
| 170 | end convertVariable; | ||
| 171 | |||
| 172 | function makeDAEVar | ||
| 173 | input ComponentRef cref; | ||
| 174 | input Type ty; | ||
| 175 | input Option<DAE.Exp> binding; | ||
| 176 | input Attributes attr; | ||
| 177 | input Visibility vis; | ||
| 178 | input Option<DAE.VariableAttributes> vattr; | ||
| 179 | input SCode.Comment comment; | ||
| 180 | input VariableConversionSettings settings; | ||
| 181 | input SourceInfo info; | ||
| 182 | input Boolean encrypted; | ||
| 183 | output DAE.Element var; | ||
| 184 | protected | ||
| 185 | DAE.ComponentRef dcref; | ||
| 186 | DAE.Type dty; | ||
| 187 | DAE.ElementSource source; | ||
| 188 | algorithm | ||
| 189 | 430565 | dcref := ComponentRef.toDAE(cref); | |
| 190 |
2/2✓ Branch 0 taken 57256 times.
✓ Branch 1 taken 373309 times.
|
430565 | dty := Type.toDAE(if settings.isFunctionParameter then Type.arrayElementType(ty) else ty); |
| 191 | 430565 | source := ElementSource.createElementSource(info); | |
| 192 | |||
| 193 |
2/2✓ Branch 0 taken 3370 times.
✓ Branch 1 taken 427195 times.
|
430565 | if settings.addTypeToSource then |
| 194 | 3370 | source := addComponentTypeToSource(cref, source); | |
| 195 | end if; | ||
| 196 | |||
| 197 | var := match attr | ||
| 198 | case Attributes.ATTRIBUTES() | ||
| 199 |
1/2✓ Branch 0 taken 430565 times.
✗ Branch 1 not taken.
|
861130 | then |
| 200 | DAE.VAR( | ||
| 201 | dcref, | ||
| 202 | Prefixes.variabilityToDAE(attr.variability), | ||
| 203 | Prefixes.directionToDAE(attr.direction), | ||
| 204 | Prefixes.parallelismToDAE(attr.parallelism), | ||
| 205 | Prefixes.visibilityToDAE(vis), | ||
| 206 | dty, | ||
| 207 | binding, | ||
| 208 | ComponentReferenceBasics.crefDims(dcref), | ||
| 209 | ConnectorType.toDAE(attr.connectorType), | ||
| 210 | source, | ||
| 211 | vattr, | ||
| 212 | SOME(comment), | ||
| 213 | Absyn.NOT_INNER_OUTER(), | ||
| 214 | encrypted | ||
| 215 | ); | ||
| 216 | |||
| 217 | ✗ | else | |
| 218 | DAE.VAR(dcref, DAE.VarKind.VARIABLE(), DAE.VarDirection.BIDIR(), | ||
| 219 | DAE.VarParallelism.NON_PARALLEL(), Prefixes.visibilityToDAE(vis), dty, | ||
| 220 | binding, {}, DAE.ConnectorType.NON_CONNECTOR(), source, vattr, SOME(comment), | ||
| 221 | Absyn.NOT_INNER_OUTER(),encrypted); | ||
| 222 | |||
| 223 | end match; | ||
| 224 | end makeDAEVar; | ||
| 225 | |||
| 226 | function addComponentTypeToSource | ||
| 227 | input ComponentRef cref; | ||
| 228 | input output DAE.ElementSource source; | ||
| 229 | algorithm | ||
| 230 | source := match cref | ||
| 231 | case ComponentRef.CREF() | ||
| 232 | algorithm | ||
| 233 | 11241 | source := addComponentLevelTypeToSource(InstNode.parent(ComponentRef.node(cref)), source); | |
| 234 | 11241 | then | |
| 235 | addComponentTypeToSource(cref.restCref, source); | ||
| 236 | |||
| 237 | else source; | ||
| 238 | end match; | ||
| 239 | end addComponentTypeToSource; | ||
| 240 | |||
| 241 | function addComponentLevelTypeToSource | ||
| 242 | "Records the type(s) of the class that owns the component referenced at one | ||
| 243 | level of a cref into the element source. For a regular component this is a | ||
| 244 | single class (the class in which the component is declared). When a component | ||
| 245 | is inherited through one or more `extends` of a visualization type, e.g. | ||
| 246 | |||
| 247 | model MyShape | ||
| 248 | extends ModelicaServices.Animation.Shape; | ||
| 249 | end MyShape; | ||
| 250 | |||
| 251 | getDerivedNode collapses the whole extends chain down to the most derived | ||
| 252 | class (MyShape), so the visualization base class (Shape) would be lost and | ||
| 253 | the backend (VisualXML) could no longer recognize it. In that case we record | ||
| 254 | the full extends chain, with the visualization base class kept in the primary | ||
| 255 | slot of this level so that the identifier prefix computed from the type index | ||
| 256 | in VisualXML.isVisualizationVarFold still points at the right component. | ||
| 257 | |||
| 258 | This is only reached when the element source types are recorded at all, i.e. | ||
| 259 | under -d=visxml (animation) or infoXmlOperations; otherwise the original | ||
| 260 | single most derived class entry is kept." | ||
| 261 | input InstNode parentNode; | ||
| 262 | input output DAE.ElementSource source; | ||
| 263 | protected | ||
| 264 | InstNode concrete, n; | ||
| 265 | Absyn.Path concretePath, p; | ||
| 266 | list<Absyn.Path> chain = {}; | ||
| 267 | Option<Absyn.Path> visPath = NONE(); | ||
| 268 | algorithm | ||
| 269 | // the collapsed, most derived class (default behaviour) | ||
| 270 | 11241 | concrete := InstNode.classScope(InstNode.getDerivedNode(parentNode)); | |
| 271 | 11241 | concretePath := InstNode.scopePath(concrete); | |
| 272 | |||
| 273 | // Skip the chain walk when the most derived class is itself a visualization | ||
| 274 | // type (direct ModelicaServices/MultiBody shapes already match as a single | ||
| 275 | // entry); only an inherited shape needs the base classes recorded. | ||
| 276 |
2/2✓ Branch 1 taken 9471 times.
✓ Branch 2 taken 1770 times.
|
11241 | if not isVisualizerLeafName(concretePath) then |
| 277 | // walk the extends chain from where the component is actually declared up | ||
| 278 | // to the most derived class, collecting the intermediate base classes | ||
| 279 | 9471 | n := InstNode.classScope(parentNode); | |
| 280 |
2/2✓ Branch 1 taken 505 times.
✓ Branch 2 taken 9471 times.
|
9976 | while InstNode.isBaseClass(n) loop |
| 281 | 505 | p := InstNode.scopePath(n, ignoreBaseClass = true); | |
| 282 | chain := p :: chain; | ||
| 283 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 505 times.
✓ Branch 2 taken 505 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 505 times.
|
505 | if isNone(visPath) and isVisualizerLeafName(p) then |
| 284 | visPath := SOME(p); | ||
| 285 | end if; | ||
| 286 | 505 | n := InstNode.classScope(InstNode.getDerivedNode(n, recursive = false)); | |
| 287 | end while; | ||
| 288 | end if; | ||
| 289 | |||
| 290 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 11241 times.
✓ Branch 2 taken 11241 times.
✗ Branch 3 not taken.
|
11241 | if isSome(visPath) then |
| 291 | // a visualization type appears as a base class -> record the whole chain | ||
| 292 | // with the visualization base class in the primary slot of this level | ||
| 293 | ✗ | SOME(p) := visPath; | |
| 294 | ✗ | chain := listAppend(list(c for c guard not AbsynUtil.pathEqual(c, p) in chain), | |
| 295 | {concretePath}); | ||
| 296 | ✗ | for c in listReverse(chain) loop | |
| 297 | ✗ | source := ElementSource.addElementSourceType(source, c); | |
| 298 | end for; | ||
| 299 | ✗ | source := ElementSource.addElementSourceType(source, p); | |
| 300 | else | ||
| 301 | // default (unchanged): single most derived class entry | ||
| 302 | 11241 | source := ElementSource.addElementSourceType(source, concretePath); | |
| 303 | end if; | ||
| 304 | end addComponentLevelTypeToSource; | ||
| 305 | |||
| 306 | function isVisualizerLeafName | ||
| 307 | "Returns true if the last identifier of the path is one of the visualization | ||
| 308 | type names (Shape, Vector, Surface). This is only used to position the type | ||
| 309 | in the element source; VisualXML.hasVisPath remains the authority on whether | ||
| 310 | a fully qualified path is actually a visualization type." | ||
| 311 | input Absyn.Path path; | ||
| 312 | output Boolean isVisualizer; | ||
| 313 | algorithm | ||
| 314 | isVisualizer := match AbsynUtil.pathLastIdent(path) | ||
| 315 | case "Shape" then true; | ||
| 316 | case "Vector" then true; | ||
| 317 | case "Surface" then true; | ||
| 318 | else false; | ||
| 319 | end match; | ||
| 320 | end isVisualizerLeafName; | ||
| 321 | |||
| 322 | function convertVarAttributes | ||
| 323 | input list<tuple<String, Binding>> attrs; | ||
| 324 | input Type ty; | ||
| 325 | input Attributes compAttrs; | ||
| 326 | output Option<DAE.VariableAttributes> attributes; | ||
| 327 | protected | ||
| 328 | Boolean is_final; | ||
| 329 | Option<Boolean> is_final_opt; | ||
| 330 | algorithm | ||
| 331 |
4/4✓ Branch 0 taken 345452 times.
✓ Branch 1 taken 85113 times.
✓ Branch 2 taken 341127 times.
✓ Branch 3 taken 4325 times.
|
430565 | is_final := compAttrs.isFinal or |
| 332 | compAttrs.variability == Variability.STRUCTURAL_PARAMETER; | ||
| 333 | |||
| 334 |
4/4✓ Branch 0 taken 158245 times.
✓ Branch 1 taken 272320 times.
✓ Branch 2 taken 132266 times.
✓ Branch 3 taken 25979 times.
|
430565 | if listEmpty(attrs) and not is_final then |
| 335 | attributes := NONE(); | ||
| 336 | 132266 | return; | |
| 337 | end if; | ||
| 338 | |||
| 339 |
2/2✓ Branch 0 taken 208861 times.
✓ Branch 1 taken 89438 times.
|
298299 | is_final_opt := SOME(is_final); |
| 340 | |||
| 341 | attributes := match Type.arrayElementType(ty) | ||
| 342 | 270078 | case Type.REAL() then convertRealVarAttributes(attrs, is_final_opt); | |
| 343 | 13133 | case Type.INTEGER() then convertIntVarAttributes(attrs, is_final_opt); | |
| 344 | 11662 | case Type.BOOLEAN() then convertBoolVarAttributes(attrs, is_final_opt); | |
| 345 | 1426 | case Type.STRING() then convertStringVarAttributes(attrs, is_final_opt); | |
| 346 | 1981 | case Type.ENUMERATION() then convertEnumVarAttributes(attrs, is_final_opt); | |
| 347 | else NONE(); | ||
| 348 | end match; | ||
| 349 | end convertVarAttributes; | ||
| 350 | |||
| 351 | function convertRealVarAttributes | ||
| 352 | input list<tuple<String, Binding>> attrs; | ||
| 353 | input Option<Boolean> isFinal; | ||
| 354 | output Option<DAE.VariableAttributes> attributes; | ||
| 355 | protected | ||
| 356 | String name; | ||
| 357 | Binding b; | ||
| 358 | Option<DAE.Exp> quantity = NONE(), unit = NONE(), displayUnit = NONE(); | ||
| 359 | Option<DAE.Exp> min = NONE(), max = NONE(), start = NONE(), fixed = NONE(), nominal = NONE(); | ||
| 360 | Option<DAE.StateSelect> state_select = NONE(); | ||
| 361 | Option<DAE.Uncertainty> uncertain = NONE(); | ||
| 362 | Option<DAE.StartOrigin> start_origin = NONE(); | ||
| 363 | algorithm | ||
| 364 |
2/2✓ Branch 0 taken 679110 times.
✓ Branch 1 taken 270078 times.
|
949188 | for attr in attrs loop |
| 365 | 679110 | (name, b) := attr; | |
| 366 | |||
| 367 | () := match name | ||
| 368 | 37989 | case "displayUnit" algorithm displayUnit := convertVarAttribute(b); then (); | |
| 369 | 7466 | case "fixed" algorithm fixed := convertVarAttribute(b); then (); | |
| 370 | 15077 | case "max" algorithm max := convertVarAttribute(b); then (); | |
| 371 | 47826 | case "min" algorithm min := convertVarAttribute(b); then (); | |
| 372 | 29214 | case "nominal" algorithm nominal := convertVarAttribute(b); then (); | |
| 373 | 222383 | case "quantity" algorithm quantity := convertVarAttribute(b); then (); | |
| 374 | 74138 | case "start" algorithm start := convertVarAttribute(b); | |
| 375 | 74138 | start_origin := convertStartOrigin(b); then (); | |
| 376 | 7060 | case "stateSelect" algorithm state_select := convertStateSelectAttribute(b); then (); | |
| 377 | // TODO: VAR_ATTR_REAL has no field for unbounded. | ||
| 378 | case "unbounded" then (); | ||
| 379 | 169 | case "uncertain" algorithm uncertain := convertUncertaintyAttribute(b); then (); | |
| 380 | 237787 | case "unit" algorithm unit := convertVarAttribute(b); then (); | |
| 381 | |||
| 382 | // The attributes should already be type checked, so we shouldn't get any | ||
| 383 | // unknown attributes here. | ||
| 384 | else | ||
| 385 | algorithm | ||
| 386 | ✗ | Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo()); | |
| 387 | ✗ | then | |
| 388 | fail(); | ||
| 389 | end match; | ||
| 390 | end for; | ||
| 391 | |||
| 392 | 270078 | attributes := SOME(DAE.VariableAttributes.VAR_ATTR_REAL( | |
| 393 | quantity, unit, displayUnit, min, max, start, fixed, nominal, | ||
| 394 | state_select, uncertain, NONE(), NONE(), NONE(), isFinal, start_origin)); | ||
| 395 | end convertRealVarAttributes; | ||
| 396 | |||
| 397 | function convertIntVarAttributes | ||
| 398 | input list<tuple<String, Binding>> attrs; | ||
| 399 | input Option<Boolean> isFinal; | ||
| 400 | output Option<DAE.VariableAttributes> attributes; | ||
| 401 | protected | ||
| 402 | String name; | ||
| 403 | Binding b; | ||
| 404 | Option<DAE.Exp> quantity = NONE(), min = NONE(), max = NONE(); | ||
| 405 | Option<DAE.Exp> start = NONE(), fixed = NONE(); | ||
| 406 | Option<DAE.StartOrigin> start_origin = NONE(); | ||
| 407 | algorithm | ||
| 408 |
2/2✓ Branch 0 taken 21359 times.
✓ Branch 1 taken 13133 times.
|
34492 | for attr in attrs loop |
| 409 | 21359 | (name, b) := attr; | |
| 410 | |||
| 411 | () := match name | ||
| 412 | 1 | case "quantity" algorithm quantity := convertVarAttribute(b); then (); | |
| 413 | 11295 | case "min" algorithm min := convertVarAttribute(b); then (); | |
| 414 | 9615 | case "max" algorithm max := convertVarAttribute(b); then (); | |
| 415 | 285 | case "start" algorithm start := convertVarAttribute(b); | |
| 416 | 285 | start_origin := convertStartOrigin(b); then (); | |
| 417 | 163 | case "fixed" algorithm fixed := convertVarAttribute(b); then (); | |
| 418 | |||
| 419 | // The attributes should already be type checked, so we shouldn't get any | ||
| 420 | // unknown attributes here. | ||
| 421 | else | ||
| 422 | algorithm | ||
| 423 | ✗ | Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo()); | |
| 424 | ✗ | then | |
| 425 | fail(); | ||
| 426 | end match; | ||
| 427 | end for; | ||
| 428 | |||
| 429 | 13133 | attributes := SOME(DAE.VariableAttributes.VAR_ATTR_INT( | |
| 430 | quantity, min, max, start, fixed, | ||
| 431 | NONE(), NONE(), NONE(), NONE(), isFinal, start_origin)); | ||
| 432 | end convertIntVarAttributes; | ||
| 433 | |||
| 434 | function convertBoolVarAttributes | ||
| 435 | input list<tuple<String, Binding>> attrs; | ||
| 436 | input Option<Boolean> isFinal; | ||
| 437 | output Option<DAE.VariableAttributes> attributes; | ||
| 438 | protected | ||
| 439 | String name; | ||
| 440 | Binding b; | ||
| 441 | Option<DAE.Exp> quantity = NONE(), start = NONE(), fixed = NONE(); | ||
| 442 | Option<DAE.StartOrigin> start_origin = NONE(); | ||
| 443 | algorithm | ||
| 444 |
2/2✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 11662 times.
|
13142 | for attr in attrs loop |
| 445 | 1480 | (name, b) := attr; | |
| 446 | |||
| 447 | () := match name | ||
| 448 | 1 | case "quantity" algorithm quantity := convertVarAttribute(b); then (); | |
| 449 | 1333 | case "start" algorithm start := convertVarAttribute(b); | |
| 450 | 1333 | start_origin := convertStartOrigin(b); then (); | |
| 451 | 146 | case "fixed" algorithm fixed := convertVarAttribute(b); then (); | |
| 452 | |||
| 453 | // The attributes should already be type checked, so we shouldn't get any | ||
| 454 | // unknown attributes here. | ||
| 455 | else | ||
| 456 | algorithm | ||
| 457 | ✗ | Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo()); | |
| 458 | ✗ | then | |
| 459 | fail(); | ||
| 460 | end match; | ||
| 461 | end for; | ||
| 462 | |||
| 463 | 11662 | attributes := SOME(DAE.VariableAttributes.VAR_ATTR_BOOL( | |
| 464 | quantity, start, fixed, NONE(), NONE(), isFinal, start_origin)); | ||
| 465 | end convertBoolVarAttributes; | ||
| 466 | |||
| 467 | function convertStringVarAttributes | ||
| 468 | input list<tuple<String, Binding>> attrs; | ||
| 469 | input Option<Boolean> isFinal; | ||
| 470 | output Option<DAE.VariableAttributes> attributes; | ||
| 471 | protected | ||
| 472 | String name; | ||
| 473 | Binding b; | ||
| 474 | Option<DAE.Exp> quantity = NONE(), start = NONE(), fixed = NONE(); | ||
| 475 | Option<DAE.StartOrigin> start_origin = NONE(); | ||
| 476 | algorithm | ||
| 477 |
2/2✓ Branch 0 taken 35 times.
✓ Branch 1 taken 1426 times.
|
1461 | for attr in attrs loop |
| 478 | 35 | (name, b) := attr; | |
| 479 | |||
| 480 | () := match name | ||
| 481 | 1 | case "quantity" algorithm quantity := convertVarAttribute(b); then (); | |
| 482 | 31 | case "start" algorithm start := convertVarAttribute(b); | |
| 483 | 31 | start_origin := convertStartOrigin(b); then (); | |
| 484 | 3 | case "fixed" algorithm fixed := convertVarAttribute(b); then (); | |
| 485 | |||
| 486 | // The attributes should already be type checked, so we shouldn't get any | ||
| 487 | // unknown attributes here. | ||
| 488 | else | ||
| 489 | algorithm | ||
| 490 | ✗ | Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo()); | |
| 491 | ✗ | then | |
| 492 | fail(); | ||
| 493 | end match; | ||
| 494 | end for; | ||
| 495 | |||
| 496 | 1426 | attributes := SOME(DAE.VariableAttributes.VAR_ATTR_STRING( | |
| 497 | quantity, start, fixed, NONE(), NONE(), isFinal, start_origin)); | ||
| 498 | end convertStringVarAttributes; | ||
| 499 | |||
| 500 | function convertEnumVarAttributes | ||
| 501 | input list<tuple<String, Binding>> attrs; | ||
| 502 | input Option<Boolean> isFinal; | ||
| 503 | output Option<DAE.VariableAttributes> attributes; | ||
| 504 | protected | ||
| 505 | String name; | ||
| 506 | Binding b; | ||
| 507 | Option<DAE.Exp> quantity = NONE(), min = NONE(), max = NONE(); | ||
| 508 | Option<DAE.Exp> start = NONE(), fixed = NONE(); | ||
| 509 | Option<DAE.StartOrigin> start_origin = NONE(); | ||
| 510 | algorithm | ||
| 511 |
2/2✓ Branch 0 taken 587 times.
✓ Branch 1 taken 1981 times.
|
2568 | for attr in attrs loop |
| 512 | 587 | (name, b) := attr; | |
| 513 | |||
| 514 | () := match name | ||
| 515 | 173 | case "fixed" algorithm fixed := convertVarAttribute(b); then (); | |
| 516 | 1 | case "max" algorithm max := convertVarAttribute(b); then (); | |
| 517 | 2 | case "min" algorithm min := convertVarAttribute(b); then (); | |
| 518 | 1 | case "quantity" algorithm quantity := convertVarAttribute(b); then (); | |
| 519 | 410 | case "start" algorithm start := convertVarAttribute(b); | |
| 520 | 410 | start_origin := convertStartOrigin(b); then (); | |
| 521 | |||
| 522 | // The attributes should already be type checked, so we shouldn't get any | ||
| 523 | // unknown attributes here. | ||
| 524 | else | ||
| 525 | algorithm | ||
| 526 | ✗ | Error.terminate(getInstanceName() + " got unknown type attribute " + name, sourceInfo()); | |
| 527 | ✗ | then | |
| 528 | fail(); | ||
| 529 | end match; | ||
| 530 | end for; | ||
| 531 | |||
| 532 | 1981 | attributes := SOME(DAE.VariableAttributes.VAR_ATTR_ENUMERATION( | |
| 533 | quantity, min, max, start, fixed, NONE(), NONE(), isFinal, start_origin)); | ||
| 534 | end convertEnumVarAttributes; | ||
| 535 | |||
| 536 | function convertVarAttribute | ||
| 537 | input Binding binding; | ||
| 538 | output Option<DAE.Exp> attribute = SOME(Expression.toDAE(Binding.getTypedExp(binding))); | ||
| 539 | end convertVarAttribute; | ||
| 540 | |||
| 541 | function convertStateSelectAttribute | ||
| 542 | input Binding binding; | ||
| 543 | output Option<DAE.StateSelect> stateSelect; | ||
| 544 | protected | ||
| 545 | String name; | ||
| 546 | algorithm | ||
| 547 | 7060 | name := getStateSelectName(Expression.arrayFirstScalar(Binding.getTypedExp(binding))); | |
| 548 | 7060 | stateSelect := SOME(lookupStateSelectMember(name)); | |
| 549 | end convertStateSelectAttribute; | ||
| 550 | |||
| 551 | function getStateSelectName | ||
| 552 | input Expression exp; | ||
| 553 | output String name; | ||
| 554 | protected | ||
| 555 | Expression e; | ||
| 556 | algorithm | ||
| 557 | name := match exp | ||
| 558 | 7060 | case Expression.ENUM_LITERAL() then exp.name; | |
| 559 | ✗ | case Expression.CREF() then ComponentRef.nodeName(exp.cref); | |
| 560 | ✗ | case Expression.CALL(call = Call.TYPED_ARRAY_CONSTRUCTOR(exp = e)) then getStateSelectName(e); | |
| 561 | else | ||
| 562 | algorithm | ||
| 563 | ✗ | Error.terminate(getInstanceName() + | |
| 564 | " got invalid StateSelect expression " + Expression.toString(exp), sourceInfo()); | ||
| 565 | ✗ | then | |
| 566 | fail(); | ||
| 567 | end match; | ||
| 568 | end getStateSelectName; | ||
| 569 | |||
| 570 | function lookupStateSelectMember | ||
| 571 | input String name; | ||
| 572 | output DAE.StateSelect stateSelect; | ||
| 573 | algorithm | ||
| 574 | stateSelect := match name | ||
| 575 | case "never" then DAE.StateSelect.NEVER(); | ||
| 576 | case "avoid" then DAE.StateSelect.AVOID(); | ||
| 577 | case "default" then DAE.StateSelect.DEFAULT(); | ||
| 578 | case "prefer" then DAE.StateSelect.PREFER(); | ||
| 579 | case "always" then DAE.StateSelect.ALWAYS(); | ||
| 580 | else | ||
| 581 | algorithm | ||
| 582 | ✗ | Error.terminate(getInstanceName() + " got unknown StateSelect literal " + name, sourceInfo()); | |
| 583 | ✗ | then | |
| 584 | fail(); | ||
| 585 | end match; | ||
| 586 | end lookupStateSelectMember; | ||
| 587 | |||
| 588 | function convertUncertaintyAttribute | ||
| 589 | input Binding binding; | ||
| 590 | output Option<DAE.Uncertainty> stateSelect; | ||
| 591 | protected | ||
| 592 | InstNode node; | ||
| 593 | String name; | ||
| 594 | Expression exp = Expression.arrayFirstScalar(Binding.getTypedExp(binding)); | ||
| 595 | algorithm | ||
| 596 | name := match exp | ||
| 597 | 169 | case Expression.ENUM_LITERAL() then exp.name; | |
| 598 | ✗ | case Expression.CREF(cref = ComponentRef.CREF()) then ComponentRef.nodeName(exp.cref); | |
| 599 | else | ||
| 600 | algorithm | ||
| 601 | ✗ | Error.terminate(getInstanceName() + | |
| 602 | " got invalid Uncertainty expression " + Expression.toString(exp), sourceInfo()); | ||
| 603 | ✗ | then | |
| 604 | fail(); | ||
| 605 | end match; | ||
| 606 | |||
| 607 | 169 | stateSelect := SOME(lookupUncertaintyMember(name)); | |
| 608 | end convertUncertaintyAttribute; | ||
| 609 | |||
| 610 | function lookupUncertaintyMember | ||
| 611 | input String name; | ||
| 612 | output DAE.Uncertainty stateSelect; | ||
| 613 | algorithm | ||
| 614 | stateSelect := match name | ||
| 615 | case "given" then DAE.Uncertainty.GIVEN(); | ||
| 616 | case "sought" then DAE.Uncertainty.SOUGHT(); | ||
| 617 | case "refine" then DAE.Uncertainty.REFINE(); | ||
| 618 | case "propagate" then DAE.Uncertainty.PROPAGATE(); | ||
| 619 | else | ||
| 620 | algorithm | ||
| 621 | ✗ | Error.terminate(getInstanceName() + " got unknown Uncertainty literal " + name, sourceInfo()); | |
| 622 | ✗ | then | |
| 623 | fail(); | ||
| 624 | end match; | ||
| 625 | end lookupUncertaintyMember; | ||
| 626 | |||
| 627 | function convertStartOrigin | ||
| 628 | input Binding binding; | ||
| 629 | output Option<DAE.StartOrigin> startOrigin; | ||
| 630 | algorithm | ||
| 631 |
2/2✓ Branch 1 taken 15736 times.
✓ Branch 2 taken 60461 times.
|
76197 | startOrigin := SOME( |
| 632 | if Binding.isFromType(binding) then | ||
| 633 | DAE.StartOrigin.TYPE_CONFIDENCE(Binding.confidence(binding)) | ||
| 634 | else | ||
| 635 | DAE.StartOrigin.CONFIDENCE(Binding.actualConfidence(binding), Binding.confidence(binding))); | ||
| 636 | end convertStartOrigin; | ||
| 637 | |||
| 638 | function convertEquations | ||
| 639 | input list<Equation> equations; | ||
| 640 | input output list<DAE.Element> elements = {}; | ||
| 641 | algorithm | ||
| 642 |
2/2✓ Branch 1 taken 146602 times.
✓ Branch 2 taken 2265 times.
|
148867 | for eq in listReverse(equations) loop |
| 643 | 146602 | elements := convertEquation(eq, elements); | |
| 644 | end for; | ||
| 645 | end convertEquations; | ||
| 646 | |||
| 647 | function convertEquation | ||
| 648 | input Equation eq; | ||
| 649 | input output list<DAE.Element> elements; | ||
| 650 | algorithm | ||
| 651 | elements := match eq | ||
| 652 | local | ||
| 653 | Expression lhs, rhs; | ||
| 654 | DAE.Exp e1, e2, e3; | ||
| 655 | DAE.ComponentRef cr1, cr2; | ||
| 656 | |||
| 657 | case Equation.EQUALITY(lhs = lhs as Expression.CREF(), rhs = rhs as Expression.CREF()) | ||
| 658 | guard Type.isScalarBuiltin(eq.ty) | ||
| 659 | algorithm | ||
| 660 | 57400 | cr1 := ComponentRef.toDAE(lhs.cref); | |
| 661 | 57400 | cr2 := ComponentRef.toDAE(rhs.cref); | |
| 662 | 57400 | then | |
| 663 | DAE.Element.EQUEQUATION(cr1, cr2, eq.source) :: elements; | ||
| 664 | |||
| 665 | case Equation.EQUALITY() | ||
| 666 | algorithm | ||
| 667 | 86958 | e1 := Expression.toDAE(eq.lhs); | |
| 668 | 86958 | e2 := Expression.toDAE(eq.rhs); | |
| 669 |
8/8✓ Branch 1 taken 3487 times.
✓ Branch 2 taken 83471 times.
✓ Branch 5 taken 19820 times.
✓ Branch 6 taken 63651 times.
✓ Branch 8 taken 22540 times.
✓ Branch 9 taken 19820 times.
✓ Branch 10 taken 22540 times.
✓ Branch 11 taken 19820 times.
|
109498 | then |
| 670 | (if Type.isComplex(eq.ty) then | ||
| 671 | DAE.Element.COMPLEX_EQUATION(e1, e2, eq.source) | ||
| 672 | elseif Type.isArray(eq.ty) then | ||
| 673 | DAE.Element.ARRAY_EQUATION(list(Dimension.toDAE(d) for d in Type.arrayDims(eq.ty)), e1, e2, eq.source) | ||
| 674 | else | ||
| 675 | DAE.Element.EQUATION(e1, e2, eq.source)) :: elements; | ||
| 676 | |||
| 677 | case Equation.FOR() | ||
| 678 | 29 | then convertForEquation(eq, isInitial = false) :: elements; | |
| 679 | |||
| 680 | case Equation.IF() | ||
| 681 | 161 | then convertIfEquation(eq.branches, eq.source, isInitial = false) :: elements; | |
| 682 | |||
| 683 | case Equation.WHEN() | ||
| 684 | 263 | then convertWhenEquation(eq.branches, eq.source) :: elements; | |
| 685 | |||
| 686 | case Equation.ASSERT() | ||
| 687 | algorithm | ||
| 688 | 1707 | e1 := Expression.toDAE(eq.condition); | |
| 689 | 1707 | e2 := Expression.toDAE(eq.message); | |
| 690 | 1707 | e3 := Expression.toDAE(eq.level); | |
| 691 | 1707 | then | |
| 692 | DAE.Element.ASSERT(e1, e2, e3, eq.source) :: elements; | ||
| 693 | |||
| 694 | case Equation.TERMINATE() | ||
| 695 | 5 | then DAE.Element.TERMINATE(Expression.toDAE(eq.message), eq.source) :: elements; | |
| 696 | |||
| 697 | case Equation.REINIT() | ||
| 698 | algorithm | ||
| 699 | 27 | cr1 := ComponentRef.toDAE(Expression.toCref(eq.cref)); | |
| 700 | 27 | e1 := Expression.toDAE(eq.reinitExp); | |
| 701 | 27 | then | |
| 702 | DAE.Element.REINIT(cr1, e1, eq.source) :: elements; | ||
| 703 | |||
| 704 | case Equation.NORETCALL() | ||
| 705 | 52 | then DAE.Element.NORETCALL(Expression.toDAE(eq.exp), eq.source) :: elements; | |
| 706 | |||
| 707 | else | ||
| 708 | algorithm | ||
| 709 | ✗ | Error.terminate(getInstanceName() + " got unknown equation " + Equation.toString(eq), sourceInfo()); | |
| 710 | ✗ | then | |
| 711 | fail(); | ||
| 712 | end match; | ||
| 713 | end convertEquation; | ||
| 714 | |||
| 715 | function convertForEquation | ||
| 716 | input Equation forEquation; | ||
| 717 | input Boolean isInitial; | ||
| 718 | output DAE.Element forDAE; | ||
| 719 | protected | ||
| 720 | InstNode iterator; | ||
| 721 | Type ty; | ||
| 722 | Expression range; | ||
| 723 | list<Equation> body; | ||
| 724 | list<DAE.Element> dbody; | ||
| 725 | DAE.ElementSource source; | ||
| 726 | algorithm | ||
| 727 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 31 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 31 times.
|
31 | Equation.FOR(iterator = iterator, range = SOME(range), body = body, source = source) := forEquation; |
| 728 | |||
| 729 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
|
31 | if isInitial then |
| 730 | 2 | dbody := convertInitialEquations(body); | |
| 731 | else | ||
| 732 | 29 | dbody := convertEquations(body); | |
| 733 | end if; | ||
| 734 | |||
| 735 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
|
31 | Component.ITERATOR(ty = ty) := InstNode.component(iterator); |
| 736 | |||
| 737 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
|
31 | if isInitial then |
| 738 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | forDAE := DAE.Element.INITIAL_FOR_EQUATION(Type.toDAE(ty), Type.isArray(ty), |
| 739 | InstNode.name(iterator), 0, Expression.toDAE(range), dbody, source); | ||
| 740 | else | ||
| 741 |
1/2✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
|
58 | forDAE := DAE.Element.FOR_EQUATION(Type.toDAE(ty), Type.isArray(ty), |
| 742 | InstNode.name(iterator), 0, Expression.toDAE(range), dbody, source); | ||
| 743 | end if; | ||
| 744 | end convertForEquation; | ||
| 745 | |||
| 746 | function convertIfEquation | ||
| 747 | input list<Equation.Branch> ifBranches; | ||
| 748 | input DAE.ElementSource source; | ||
| 749 | input Boolean isInitial; | ||
| 750 | output DAE.Element ifEquation; | ||
| 751 | protected | ||
| 752 | list<Expression> conds = {}; | ||
| 753 | list<list<Equation>> branches = {}; | ||
| 754 | list<DAE.Exp> dconds; | ||
| 755 | list<list<DAE.Element>> dbranches; | ||
| 756 | list<DAE.Element> else_branch; | ||
| 757 | algorithm | ||
| 758 |
2/2✓ Branch 0 taken 592 times.
✓ Branch 1 taken 161 times.
|
753 | for branch in ifBranches loop |
| 759 | (conds, branches) := match branch | ||
| 760 | case Equation.Branch.BRANCH() | ||
| 761 | 592 | then (branch.condition :: conds, branch.body :: branches); | |
| 762 | |||
| 763 | case Equation.Branch.INVALID_BRANCH() | ||
| 764 | algorithm | ||
| 765 | ✗ | Equation.Branch.triggerErrors(branch); | |
| 766 | ✗ | then | |
| 767 | fail(); | ||
| 768 | end match; | ||
| 769 | end for; | ||
| 770 | |||
| 771 |
5/10✗ Branch 0 not taken.
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 592 times.
✓ Branch 8 taken 161 times.
✓ Branch 9 taken 592 times.
✓ Branch 10 taken 161 times.
|
753 | dbranches := if isInitial then |
| 772 | list(convertInitialEquations(b) for b in branches) else | ||
| 773 | list(convertEquations(b) for b in branches); | ||
| 774 | |||
| 775 | // Transform the last branch to an else-branch if its condition is true. | ||
| 776 |
2/2✓ Branch 2 taken 158 times.
✓ Branch 3 taken 3 times.
|
161 | if Expression.isTrue(listHead(conds)) then |
| 777 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
|
158 | else_branch :: dbranches := dbranches; |
| 778 | 158 | conds := listRest(conds); | |
| 779 | else | ||
| 780 | else_branch := {}; | ||
| 781 | end if; | ||
| 782 | |||
| 783 |
4/4✓ Branch 0 taken 434 times.
✓ Branch 1 taken 161 times.
✓ Branch 2 taken 434 times.
✓ Branch 3 taken 161 times.
|
595 | dconds := listReverse(Expression.toDAE(c) for c in conds); |
| 784 | 161 | dbranches := listReverseInPlace(dbranches); | |
| 785 | |||
| 786 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 161 times.
|
161 | ifEquation := if isInitial then |
| 787 | DAE.Element.INITIAL_IF_EQUATION(dconds, dbranches, else_branch, source) else | ||
| 788 | DAE.Element.IF_EQUATION(dconds, dbranches, else_branch, source); | ||
| 789 | end convertIfEquation; | ||
| 790 | |||
| 791 | function convertWhenEquation | ||
| 792 | input list<Equation.Branch> whenBranches; | ||
| 793 | input DAE.ElementSource source; | ||
| 794 | output DAE.Element whenEquation; | ||
| 795 | protected | ||
| 796 | DAE.Exp cond; | ||
| 797 | list<DAE.Element> els; | ||
| 798 | Option<DAE.Element> when_eq = NONE(); | ||
| 799 | algorithm | ||
| 800 |
2/2✓ Branch 1 taken 270 times.
✓ Branch 2 taken 263 times.
|
533 | for b in listReverse(whenBranches) loop |
| 801 | when_eq := match b | ||
| 802 | case Equation.Branch.BRANCH() | ||
| 803 | algorithm | ||
| 804 | 270 | cond := Expression.toDAE(b.condition); | |
| 805 | 270 | els := convertEquations(b.body); | |
| 806 | 270 | then | |
| 807 | SOME(DAE.Element.WHEN_EQUATION(cond, els, when_eq, source)); | ||
| 808 | end match; | ||
| 809 | end for; | ||
| 810 | |||
| 811 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 263 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 263 times.
|
263 | SOME(whenEquation) := when_eq; |
| 812 | end convertWhenEquation; | ||
| 813 | |||
| 814 | function convertInitialEquations | ||
| 815 | input list<Equation> equations; | ||
| 816 | input output list<DAE.Element> elements = {}; | ||
| 817 | algorithm | ||
| 818 |
2/2✓ Branch 1 taken 1818 times.
✓ Branch 2 taken 1376 times.
|
3194 | for eq in listReverse(equations) loop |
| 819 | 1818 | elements := convertInitialEquation(eq, elements); | |
| 820 | end for; | ||
| 821 | end convertInitialEquations; | ||
| 822 | |||
| 823 | function convertInitialEquation | ||
| 824 | input Equation eq; | ||
| 825 | input output list<DAE.Element> elements; | ||
| 826 | algorithm | ||
| 827 | elements := match eq | ||
| 828 | local | ||
| 829 | DAE.Exp e1, e2, e3; | ||
| 830 | |||
| 831 | case Equation.EQUALITY() | ||
| 832 | algorithm | ||
| 833 | 1786 | e1 := Expression.toDAE(eq.lhs); | |
| 834 | 1786 | e2 := Expression.toDAE(eq.rhs); | |
| 835 |
8/8✓ Branch 1 taken 59 times.
✓ Branch 2 taken 1727 times.
✓ Branch 5 taken 47 times.
✓ Branch 6 taken 1680 times.
✓ Branch 8 taken 47 times.
✓ Branch 9 taken 47 times.
✓ Branch 10 taken 47 times.
✓ Branch 11 taken 47 times.
|
1833 | then |
| 836 | (if Type.isComplex(eq.ty) then | ||
| 837 | DAE.Element.INITIAL_COMPLEX_EQUATION(e1, e2, eq.source) | ||
| 838 | elseif Type.isArray(eq.ty) then | ||
| 839 | DAE.Element.INITIAL_ARRAY_EQUATION(list(Dimension.toDAE(d) for d in Type.arrayDims(eq.ty)), e1, e2, eq.source) | ||
| 840 | else | ||
| 841 | DAE.Element.INITIALEQUATION(e1, e2, eq.source)) :: elements; | ||
| 842 | |||
| 843 | case Equation.FOR() | ||
| 844 | 2 | then convertForEquation(eq, isInitial = true) :: elements; | |
| 845 | |||
| 846 | case Equation.IF() | ||
| 847 | ✗ | then convertIfEquation(eq.branches, eq.source, isInitial = true) :: elements; | |
| 848 | |||
| 849 | case Equation.ASSERT() | ||
| 850 | algorithm | ||
| 851 | 29 | e1 := Expression.toDAE(eq.condition); | |
| 852 | 29 | e2 := Expression.toDAE(eq.message); | |
| 853 | 29 | e3 := Expression.toDAE(eq.level); | |
| 854 | 29 | then | |
| 855 | DAE.Element.INITIAL_ASSERT(e1, e2, e3, eq.source) :: elements; | ||
| 856 | |||
| 857 | case Equation.TERMINATE() | ||
| 858 | ✗ | then DAE.Element.INITIAL_TERMINATE(Expression.toDAE(eq.message), eq.source) :: elements; | |
| 859 | |||
| 860 | case Equation.NORETCALL() | ||
| 861 | 1 | then DAE.Element.INITIAL_NORETCALL(Expression.toDAE(eq.exp), eq.source) :: elements; | |
| 862 | |||
| 863 | else | ||
| 864 | algorithm | ||
| 865 | ✗ | Error.terminate(getInstanceName() + " got unknown equation " + Equation.toString(eq), sourceInfo()); | |
| 866 | ✗ | then | |
| 867 | fail(); | ||
| 868 | end match; | ||
| 869 | end convertInitialEquation; | ||
| 870 | |||
| 871 | function convertAlgorithms | ||
| 872 | input list<Algorithm> algorithms; | ||
| 873 | input output list<DAE.Element> elements; | ||
| 874 | algorithm | ||
| 875 |
2/2✓ Branch 1 taken 9633 times.
✓ Branch 2 taken 10874 times.
|
20507 | for alg in listReverse(algorithms) loop |
| 876 | 9633 | elements := convertAlgorithm(alg, elements); | |
| 877 | end for; | ||
| 878 | end convertAlgorithms; | ||
| 879 | |||
| 880 | function convertAlgorithm | ||
| 881 | input Algorithm alg; | ||
| 882 | input output list<DAE.Element> elements; | ||
| 883 | protected | ||
| 884 | list<DAE.Statement> stmts; | ||
| 885 | DAE.Algorithm dalg; | ||
| 886 | algorithm | ||
| 887 | 9633 | stmts := convertStatements(alg.statements); | |
| 888 | 9633 | dalg := DAE.ALGORITHM_STMTS(stmts); | |
| 889 | 9633 | elements := DAE.ALGORITHM(dalg, alg.source) :: elements; | |
| 890 | end convertAlgorithm; | ||
| 891 | |||
| 892 | function convertStatement | ||
| 893 | input Statement stmt; | ||
| 894 | output DAE.Statement elem; | ||
| 895 | algorithm | ||
| 896 | elem := match stmt | ||
| 897 | local | ||
| 898 | DAE.Exp e1, e2, e3; | ||
| 899 | DAE.Type ty; | ||
| 900 | list<DAE.Statement> body; | ||
| 901 | |||
| 902 | 86802 | case Statement.ASSIGNMENT() then convertAssignment(stmt); | |
| 903 | |||
| 904 | case Statement.FUNCTION_ARRAY_INIT() | ||
| 905 | algorithm | ||
| 906 | ✗ | ty := Type.toDAE(stmt.ty); | |
| 907 | ✗ | then | |
| 908 | DAE.Statement.STMT_ARRAY_INIT(stmt.name, ty, stmt.source); | ||
| 909 | |||
| 910 | 571 | case Statement.FOR() then convertForStatement(stmt); | |
| 911 | 4554 | case Statement.IF() then convertIfStatement(stmt.branches, stmt.source); | |
| 912 | 81 | case Statement.WHEN() then convertWhenStatement(stmt.branches, stmt.source); | |
| 913 | |||
| 914 | case Statement.ASSERT() | ||
| 915 | algorithm | ||
| 916 | 2883 | e1 := Expression.toDAE(stmt.condition); | |
| 917 | 2883 | e2 := Expression.toDAE(stmt.message); | |
| 918 | 2883 | e3 := Expression.toDAE(stmt.level); | |
| 919 | 2883 | then | |
| 920 | DAE.Statement.STMT_ASSERT(e1, e2, e3, stmt.source); | ||
| 921 | |||
| 922 | case Statement.TERMINATE() | ||
| 923 | 1 | then DAE.Statement.STMT_TERMINATE(Expression.toDAE(stmt.message), stmt.source); | |
| 924 | |||
| 925 | case Statement.REINIT() | ||
| 926 | algorithm | ||
| 927 | 4 | e1 := Expression.toDAE(stmt.cref); | |
| 928 | 4 | e2 := Expression.toDAE(stmt.reinitExp); | |
| 929 | 4 | then | |
| 930 | DAE.Statement.STMT_REINIT(e1, e2, stmt.source); | ||
| 931 | |||
| 932 | case Statement.NORETCALL() | ||
| 933 | 106 | then DAE.Statement.STMT_NORETCALL(Expression.toDAE(stmt.exp), stmt.source); | |
| 934 | |||
| 935 | case Statement.WHILE() | ||
| 936 | algorithm | ||
| 937 | 206 | e1 := Expression.toDAE(stmt.condition); | |
| 938 | 206 | body := convertStatements(stmt.body); | |
| 939 | 206 | then | |
| 940 | DAE.Statement.STMT_WHILE(e1, body, stmt.source); | ||
| 941 | |||
| 942 | case Statement.RETURN() | ||
| 943 | 7 | then DAE.Statement.STMT_RETURN(stmt.source); | |
| 944 | |||
| 945 | case Statement.BREAK() | ||
| 946 | 2 | then DAE.Statement.STMT_BREAK(stmt.source); | |
| 947 | |||
| 948 | case Statement.FAILURE() | ||
| 949 | ✗ | then DAE.Statement.STMT_FAILURE(convertStatements(stmt.body), stmt.source); | |
| 950 | |||
| 951 | else | ||
| 952 | algorithm | ||
| 953 | ✗ | Error.terminate(getInstanceName() + " got unknown statement " + Statement.toString(stmt), sourceInfo()); | |
| 954 | ✗ | then | |
| 955 | fail(); | ||
| 956 | end match; | ||
| 957 | end convertStatement; | ||
| 958 | |||
| 959 | function convertAssignment | ||
| 960 | input Statement stmt; | ||
| 961 | output DAE.Statement daeStmt; | ||
| 962 | protected | ||
| 963 | Expression lhs, rhs; | ||
| 964 | DAE.ElementSource src; | ||
| 965 | Type ty; | ||
| 966 | DAE.Type dty; | ||
| 967 | DAE.Exp dlhs, drhs; | ||
| 968 | list<Expression> expl; | ||
| 969 | algorithm | ||
| 970 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 86802 times.
|
86802 | Statement.ASSIGNMENT(lhs, rhs, ty, src) := stmt; |
| 971 | |||
| 972 |
2/2✓ Branch 1 taken 544 times.
✓ Branch 2 taken 86258 times.
|
86802 | if Type.isTuple(ty) then |
| 973 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 544 times.
|
544 | Expression.TUPLE(elements = expl) := lhs; |
| 974 | |||
| 975 | daeStmt := match expl | ||
| 976 | // () := call(...) => call(...) | ||
| 977 | ✗ | case {} then DAE.Statement.STMT_NORETCALL(Expression.toDAE(rhs), src); | |
| 978 | |||
| 979 | // (lhs) := call(...) => lhs := TSUB[call(...), 1] | ||
| 980 | case {lhs} | ||
| 981 | algorithm | ||
| 982 | ✗ | dty := Type.toDAE(ty); | |
| 983 | ✗ | dlhs := Expression.toDAE(lhs); | |
| 984 | ✗ | drhs := DAE.Exp.TSUB(Expression.toDAE(rhs), 1, dty); | |
| 985 | |||
| 986 | ✗ | if Type.isArray(ty) then | |
| 987 | ✗ | daeStmt := DAE.Statement.STMT_ASSIGN_ARR(dty, dlhs, drhs, src); | |
| 988 | else | ||
| 989 | ✗ | daeStmt := DAE.Statement.STMT_ASSIGN(dty, dlhs, drhs, src); | |
| 990 | end if; | ||
| 991 | then | ||
| 992 | daeStmt; | ||
| 993 | |||
| 994 | else | ||
| 995 | algorithm | ||
| 996 | 544 | dty := Type.toDAE(ty); | |
| 997 | 544 | drhs := Expression.toDAE(rhs); | |
| 998 |
4/4✓ Branch 0 taken 1217 times.
✓ Branch 1 taken 544 times.
✓ Branch 2 taken 1217 times.
✓ Branch 3 taken 544 times.
|
1761 | then |
| 999 | DAE.Statement.STMT_TUPLE_ASSIGN(dty, list(Expression.toDAE(e) for e in expl), drhs, src); | ||
| 1000 | end match; | ||
| 1001 | else | ||
| 1002 | 86258 | dty := Type.toDAE(ty); | |
| 1003 | 86258 | dlhs := Expression.toDAE(lhs); | |
| 1004 | 86258 | drhs := Expression.toDAE(rhs); | |
| 1005 | |||
| 1006 |
2/2✓ Branch 1 taken 1536 times.
✓ Branch 2 taken 84722 times.
|
86258 | if Type.isArray(ty) then |
| 1007 | 1536 | daeStmt := DAE.Statement.STMT_ASSIGN_ARR(dty, dlhs, drhs, src); | |
| 1008 | else | ||
| 1009 | 84722 | daeStmt := DAE.Statement.STMT_ASSIGN(dty, dlhs, drhs, src); | |
| 1010 | end if; | ||
| 1011 | end if; | ||
| 1012 | end convertAssignment; | ||
| 1013 | |||
| 1014 | function convertForStatement | ||
| 1015 | input Statement forStmt; | ||
| 1016 | output DAE.Statement forDAE; | ||
| 1017 | protected | ||
| 1018 | InstNode iterator; | ||
| 1019 | Type ty; | ||
| 1020 | Expression range; | ||
| 1021 | list<Statement> body; | ||
| 1022 | list<DAE.Statement> dbody; | ||
| 1023 | DAE.ElementSource source; | ||
| 1024 | Statement.ForType for_type; | ||
| 1025 | list<tuple<DAE.ComponentRef, SourceInfo>> loop_vars; | ||
| 1026 | list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters_dae; | ||
| 1027 | list<tuple<ComponentRef, array<Expression>>> sub_iters; | ||
| 1028 | algorithm | ||
| 1029 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 571 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 571 times.
|
571 | Statement.FOR(iterator = iterator, range = SOME(range), body = body, forType = for_type, source = source, sub_iters = sub_iters) := forStmt; |
| 1030 | 571 | dbody := convertStatements(body); | |
| 1031 | 571 | ty := InstNode.getType(iterator); | |
| 1032 |
2/8✗ Branch 0 not taken.
✓ Branch 1 taken 571 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 571 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
571 | sub_iters_dae := list( |
| 1033 | (ComponentRef.toDAE(Util.tuple21(si)), | ||
| 1034 | listArray(list(Expression.toDAE(e) for e in arrayList(Util.tuple22(si))))) | ||
| 1035 | for si in sub_iters); | ||
| 1036 | |||
| 1037 | forDAE := match for_type | ||
| 1038 | case Statement.ForType.NORMAL() | ||
| 1039 |
1/2✓ Branch 3 taken 571 times.
✗ Branch 4 not taken.
|
1142 | then DAE.Statement.STMT_FOR(Type.toDAE(ty), Type.isArray(ty), |
| 1040 | InstNode.name(iterator), Expression.toDAE(range), dbody, source, sub_iters_dae); | ||
| 1041 | |||
| 1042 | case Statement.ForType.PARALLEL() | ||
| 1043 | algorithm | ||
| 1044 | ✗ | loop_vars := list(convertForStatementParallelVar(v) for v in for_type.vars); | |
| 1045 | ✗ | then | |
| 1046 | DAE.Statement.STMT_PARFOR(Type.toDAE(ty), Type.isArray(ty), | ||
| 1047 | InstNode.name(iterator), Expression.toDAE(range), dbody, loop_vars, source); | ||
| 1048 | end match; | ||
| 1049 | end convertForStatement; | ||
| 1050 | |||
| 1051 | function convertForStatementParallelVar | ||
| 1052 | input tuple<ComponentRef, SourceInfo> var; | ||
| 1053 | output tuple<DAE.ComponentRef, SourceInfo> outVar; | ||
| 1054 | protected | ||
| 1055 | ComponentRef cref; | ||
| 1056 | DAE.ComponentRef dcref; | ||
| 1057 | SourceInfo info; | ||
| 1058 | algorithm | ||
| 1059 | ✗ | (cref, info) := var; | |
| 1060 | ✗ | dcref := ComponentRef.toDAE(cref); | |
| 1061 | ✗ | outVar := (dcref, info); | |
| 1062 | end convertForStatementParallelVar; | ||
| 1063 | |||
| 1064 | function convertIfStatement | ||
| 1065 | input list<tuple<Expression, list<Statement>>> ifBranches; | ||
| 1066 | input DAE.ElementSource source; | ||
| 1067 | output DAE.Statement ifStatement; | ||
| 1068 | protected | ||
| 1069 | Expression cond; | ||
| 1070 | DAE.Exp dcond; | ||
| 1071 | list<Statement> stmts; | ||
| 1072 | list<DAE.Statement> dstmts; | ||
| 1073 | Boolean first = true; | ||
| 1074 | Boolean single = listLength(ifBranches) == 1; | ||
| 1075 | DAE.Else else_stmt = DAE.Else.NOELSE(); | ||
| 1076 | algorithm | ||
| 1077 |
2/2✓ Branch 1 taken 9610 times.
✓ Branch 2 taken 4554 times.
|
14164 | for b in listReverse(ifBranches) loop |
| 1078 | 9610 | (cond, stmts) := b; | |
| 1079 | 9610 | dcond := Expression.toDAE(cond); | |
| 1080 | 9610 | dstmts := convertStatements(stmts); | |
| 1081 | |||
| 1082 |
4/4✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 6148 times.
✓ Branch 3 taken 3409 times.
✓ Branch 4 taken 53 times.
|
9610 | if first and not single and Expression.isTrue(cond) then |
| 1083 | 3409 | else_stmt := DAE.Else.ELSE(dstmts); | |
| 1084 | else | ||
| 1085 | 6201 | else_stmt := DAE.Else.ELSEIF(dcond, dstmts, else_stmt); | |
| 1086 | end if; | ||
| 1087 | |||
| 1088 | first := false; | ||
| 1089 | end for; | ||
| 1090 | |||
| 1091 | // This should always be an ELSEIF due to branch selection in earlier phases. | ||
| 1092 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4554 times.
|
4554 | DAE.Else.ELSEIF(dcond, dstmts, else_stmt) := else_stmt; |
| 1093 | 4554 | ifStatement := DAE.Statement.STMT_IF(dcond, dstmts, else_stmt, source); | |
| 1094 | end convertIfStatement; | ||
| 1095 | |||
| 1096 | function convertWhenStatement | ||
| 1097 | input list<tuple<Expression, list<Statement>>> whenBranches; | ||
| 1098 | input DAE.ElementSource source; | ||
| 1099 | output DAE.Statement whenStatement; | ||
| 1100 | protected | ||
| 1101 | Expression co; | ||
| 1102 | list<ComponentRef> conditions; | ||
| 1103 | DAE.Exp cond; | ||
| 1104 | list<DAE.Statement> stmts; | ||
| 1105 | Option<DAE.Statement> when_stmt = NONE(); | ||
| 1106 | algorithm | ||
| 1107 |
2/2✓ Branch 1 taken 117 times.
✓ Branch 2 taken 81 times.
|
198 | for b in listReverse(whenBranches) loop |
| 1108 | 117 | co := Util.tuple21(b); | |
| 1109 |
6/6✓ Branch 4 taken 168 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 221 times.
✓ Branch 7 taken 117 times.
✓ Branch 8 taken 53 times.
✓ Branch 9 taken 117 times.
|
338 | conditions := list(c for c guard(Type.isBoolean(ComponentRef.getSubscriptedType(c))) in UnorderedSet.toList(Expression.extractCrefs(co))); |
| 1110 | 117 | cond := Expression.toDAE(co); | |
| 1111 | 117 | stmts := convertStatements(Util.tuple22(b)); | |
| 1112 |
4/4✓ Branch 0 taken 53 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 53 times.
✓ Branch 3 taken 117 times.
|
170 | when_stmt := SOME(DAE.Statement.STMT_WHEN(cond, list(ComponentRef.toDAE(c) for c in conditions), false, stmts, when_stmt, source)); |
| 1113 | end for; | ||
| 1114 | |||
| 1115 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81 times.
|
81 | SOME(whenStatement) := when_stmt; |
| 1116 | end convertWhenStatement; | ||
| 1117 | |||
| 1118 | function convertInitialAlgorithms | ||
| 1119 | input list<Algorithm> algorithms; | ||
| 1120 | input output list<DAE.Element> elements; | ||
| 1121 | algorithm | ||
| 1122 |
2/2✓ Branch 1 taken 46 times.
✓ Branch 2 taken 1374 times.
|
1420 | for alg in listReverse(algorithms) loop |
| 1123 | 46 | elements := convertInitialAlgorithm(alg, elements); | |
| 1124 | end for; | ||
| 1125 | end convertInitialAlgorithms; | ||
| 1126 | |||
| 1127 | function convertInitialAlgorithm | ||
| 1128 | input Algorithm alg; | ||
| 1129 | input output list<DAE.Element> elements; | ||
| 1130 | protected | ||
| 1131 | list<DAE.Statement> stmts; | ||
| 1132 | DAE.Algorithm dalg; | ||
| 1133 | algorithm | ||
| 1134 | 46 | stmts := convertStatements(alg.statements); | |
| 1135 | 46 | dalg := DAE.ALGORITHM_STMTS(stmts); | |
| 1136 | 46 | elements := DAE.INITIALALGORITHM(dalg, alg.source) :: elements; | |
| 1137 | end convertInitialAlgorithm; | ||
| 1138 | |||
| 1139 | public function convertFunctionTree | ||
| 1140 | input FunctionTree funcs; | ||
| 1141 | output AvlTreePathFunction.Tree dfuncs; | ||
| 1142 | algorithm | ||
| 1143 | dfuncs := match funcs | ||
| 1144 | local | ||
| 1145 | AvlTreePathFunction.Tree left, right; | ||
| 1146 | DAE.Function fn; | ||
| 1147 | |||
| 1148 | case FunctionTree.NODE() | ||
| 1149 | algorithm | ||
| 1150 | 6232 | fn := convertFunction(funcs.value); | |
| 1151 | 6232 | left := convertFunctionTree(funcs.left); | |
| 1152 | 6232 | right := convertFunctionTree(funcs.right); | |
| 1153 | 6232 | then | |
| 1154 | AvlTreePathFunction.Tree.NODE(funcs.key, SOME(fn), funcs.height, left, right); | ||
| 1155 | |||
| 1156 | case FunctionTree.LEAF() | ||
| 1157 | algorithm | ||
| 1158 | 5153 | fn := convertFunction(funcs.value); | |
| 1159 | 5153 | then | |
| 1160 | AvlTreePathFunction.Tree.LEAF(funcs.key, SOME(fn)); | ||
| 1161 | |||
| 1162 | case FunctionTree.EMPTY() | ||
| 1163 | then AvlTreePathFunction.Tree.EMPTY(); | ||
| 1164 | |||
| 1165 | end match; | ||
| 1166 | end convertFunctionTree; | ||
| 1167 | |||
| 1168 | protected function convertFunction | ||
| 1169 | input Function func; | ||
| 1170 | output DAE.Function dfunc; | ||
| 1171 | protected | ||
| 1172 | Class cls; | ||
| 1173 | list<DAE.Element> elems; | ||
| 1174 | DAE.FunctionDefinition def; | ||
| 1175 | Sections sections; | ||
| 1176 | algorithm | ||
| 1177 | 11385 | cls := InstNode.getClass(Function.instance(func)); | |
| 1178 | |||
| 1179 | dfunc := match cls | ||
| 1180 | case Class.TYPED_DERIVED(restriction = Restriction.FUNCTION()) | ||
| 1181 | guard Function.isPartialDerivative(func) | ||
| 1182 | algorithm | ||
| 1183 | 1 | def := DAE.FunctionDefinition.FUNCTION_PARTIAL_DERIVATIVE( | |
| 1184 | Function.getDerivedFunctionName(func), Function.getDerivedInputNames(func)); | ||
| 1185 | 1 | then | |
| 1186 | Function.toDAE(func, def); | ||
| 1187 | |||
| 1188 | case Class.INSTANCED_CLASS(sections = sections, restriction = Restriction.FUNCTION()) | ||
| 1189 | algorithm | ||
| 1190 | 9809 | elems := convertFunctionParams(func.inputs, {}); | |
| 1191 |
4/4✓ Branch 0 taken 10164 times.
✓ Branch 1 taken 9809 times.
✓ Branch 2 taken 10164 times.
✓ Branch 3 taken 9809 times.
|
19973 | elems := convertFunctionParams(list(InstNode.fromHandle(o) for o in func.outputs), elems); |
| 1192 | 9809 | elems := convertFunctionParams(func.locals, elems); | |
| 1193 | |||
| 1194 | def := match sections | ||
| 1195 | // A function with an algorithm section. | ||
| 1196 | case Sections.SECTIONS() | ||
| 1197 | algorithm | ||
| 1198 | 9500 | elems := convertAlgorithms(sections.algorithms, elems); | |
| 1199 | 9500 | then | |
| 1200 | DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems)); | ||
| 1201 | |||
| 1202 | // An external function. | ||
| 1203 | case Sections.EXTERNAL() | ||
| 1204 | 277 | then convertExternalDecl(sections, listReverse(elems)); | |
| 1205 | |||
| 1206 | // A function without either algorithm or external section. | ||
| 1207 | 32 | else DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems)); | |
| 1208 | end match; | ||
| 1209 | 9809 | then | |
| 1210 | Function.toDAE(func, def); | ||
| 1211 | |||
| 1212 | case Class.INSTANCED_CLASS(restriction = Restriction.RECORD_CONSTRUCTOR()) | ||
| 1213 | 1575 | then DAE.Function.RECORD_CONSTRUCTOR(Function.name(func), | |
| 1214 | Function.makeDAEType(func), | ||
| 1215 | DAE.emptyElementSource); | ||
| 1216 | |||
| 1217 | else | ||
| 1218 | algorithm | ||
| 1219 | ✗ | Error.terminate(getInstanceName() + " got unknown function", sourceInfo()); | |
| 1220 | ✗ | then | |
| 1221 | fail(); | ||
| 1222 | |||
| 1223 | end match; | ||
| 1224 | end convertFunction; | ||
| 1225 | |||
| 1226 | function convertFunctionParams | ||
| 1227 | input list<InstNode> params; | ||
| 1228 | input output list<DAE.Element> elements; | ||
| 1229 | algorithm | ||
| 1230 |
2/2✓ Branch 0 taken 57256 times.
✓ Branch 1 taken 29427 times.
|
86683 | for p in params loop |
| 1231 | 57256 | elements := convertFunctionParam(p) :: elements; | |
| 1232 | end for; | ||
| 1233 | end convertFunctionParams; | ||
| 1234 | |||
| 1235 | function convertFunctionParam | ||
| 1236 | input InstNode node; | ||
| 1237 | output DAE.Element element; | ||
| 1238 | protected | ||
| 1239 | Component comp; | ||
| 1240 | Class cls; | ||
| 1241 | SourceInfo info; | ||
| 1242 | Option<DAE.VariableAttributes> var_attr; | ||
| 1243 | ComponentRef cref; | ||
| 1244 | Attributes attr; | ||
| 1245 | Type ty; | ||
| 1246 | Option<DAE.Exp> binding; | ||
| 1247 | list<tuple<String, Binding>> ty_attr; | ||
| 1248 | algorithm | ||
| 1249 | 57256 | comp := InstNode.component(node); | |
| 1250 | |||
| 1251 | element := match comp | ||
| 1252 | case Component.COMPONENT(ty = ty, info = info, attributes = attr) | ||
| 1253 | algorithm | ||
| 1254 | 57256 | cref := ComponentRef.fromNode(node, ty); | |
| 1255 | 57256 | binding := Binding.toDAEExp(comp.binding); | |
| 1256 | 57256 | cls := InstNode.getClass(comp.classInst); | |
| 1257 |
4/4✓ Branch 1 taken 74439 times.
✓ Branch 2 taken 57256 times.
✓ Branch 3 taken 74439 times.
✓ Branch 4 taken 57256 times.
|
131695 | ty_attr := list((Modifier.name(m), Modifier.binding(m)) for m in Class.getTypeAttributes(cls)); |
| 1258 | 57256 | var_attr := convertVarAttributes(ty_attr, ty, attr); | |
| 1259 | 57256 | then | |
| 1260 | makeDAEVar(cref, ty, binding, attr, InstNode.visibility(node), var_attr, | ||
| 1261 | comp.comment, FUNCTION_VARIABLE_CONVERSION_SETTINGS, info, false); | ||
| 1262 | |||
| 1263 | else | ||
| 1264 | algorithm | ||
| 1265 | ✗ | Error.terminate(getInstanceName() + " got invalid component.", sourceInfo()); | |
| 1266 | ✗ | then | |
| 1267 | fail(); | ||
| 1268 | |||
| 1269 | end match; | ||
| 1270 | end convertFunctionParam; | ||
| 1271 | |||
| 1272 | function convertExternalDecl | ||
| 1273 | input Sections extDecl; | ||
| 1274 | input list<DAE.Element> parameters; | ||
| 1275 | output DAE.FunctionDefinition funcDef; | ||
| 1276 | protected | ||
| 1277 | DAE.ExternalDecl decl; | ||
| 1278 | list<DAE.ExtArg> args; | ||
| 1279 | DAE.ExtArg ret_arg; | ||
| 1280 | algorithm | ||
| 1281 | funcDef := match extDecl | ||
| 1282 | case Sections.EXTERNAL() | ||
| 1283 | algorithm | ||
| 1284 |
4/4✓ Branch 0 taken 965 times.
✓ Branch 1 taken 277 times.
✓ Branch 2 taken 965 times.
✓ Branch 3 taken 277 times.
|
1242 | args := list(convertExternalDeclArg(e) for e in extDecl.args); |
| 1285 | 277 | ret_arg := convertExternalDeclOutput(extDecl.outputRef); | |
| 1286 | 277 | decl := DAE.ExternalDecl.EXTERNALDECL(extDecl.name, args, ret_arg, extDecl.language, extDecl.ann); | |
| 1287 | 277 | then | |
| 1288 | DAE.FunctionDefinition.FUNCTION_EXT(parameters, decl); | ||
| 1289 | end match; | ||
| 1290 | end convertExternalDecl; | ||
| 1291 | |||
| 1292 | function convertExternalDeclArg | ||
| 1293 | input Expression exp; | ||
| 1294 | output DAE.ExtArg arg; | ||
| 1295 | algorithm | ||
| 1296 | arg := match exp | ||
| 1297 | local | ||
| 1298 | Absyn.Direction dir; | ||
| 1299 | ComponentRef cref; | ||
| 1300 | Expression e; | ||
| 1301 | |||
| 1302 | case Expression.CREF(cref = cref as ComponentRef.CREF()) | ||
| 1303 | algorithm | ||
| 1304 | 874 | dir := Prefixes.directionToAbsyn(Component.direction(InstNode.component(ComponentRef.node(cref)))); | |
| 1305 | 874 | then | |
| 1306 | DAE.ExtArg.EXTARG(ComponentRef.toDAE(cref), dir, Type.toDAE(exp.ty)); | ||
| 1307 | |||
| 1308 | case Expression.SIZE(exp = Expression.CREF(cref = cref as ComponentRef.CREF()), dimIndex = SOME(e)) | ||
| 1309 | 87 | then DAE.ExtArg.EXTARGSIZE(ComponentRef.toDAE(cref), Type.toDAE(cref.ty), Expression.toDAE(e)); | |
| 1310 | |||
| 1311 | 4 | else DAE.ExtArg.EXTARGEXP(Expression.toDAE(exp), Type.toDAE(Expression.typeOf(exp))); | |
| 1312 | |||
| 1313 | end match; | ||
| 1314 | end convertExternalDeclArg; | ||
| 1315 | |||
| 1316 | function convertExternalDeclOutput | ||
| 1317 | input ComponentRef cref; | ||
| 1318 | output DAE.ExtArg arg; | ||
| 1319 | algorithm | ||
| 1320 | arg := match cref | ||
| 1321 | local | ||
| 1322 | Absyn.Direction dir; | ||
| 1323 | |||
| 1324 | case ComponentRef.CREF() | ||
| 1325 | algorithm | ||
| 1326 | 177 | dir := Prefixes.directionToAbsyn(Component.direction(InstNode.component(ComponentRef.node(cref)))); | |
| 1327 | 177 | then | |
| 1328 | DAE.ExtArg.EXTARG(ComponentRef.toDAE(cref), dir, Type.toDAE(cref.ty)); | ||
| 1329 | |||
| 1330 | else DAE.ExtArg.NOEXTARG(); | ||
| 1331 | end match; | ||
| 1332 | end convertExternalDeclOutput; | ||
| 1333 | |||
| 1334 | public | ||
| 1335 | function makeTypeVars | ||
| 1336 | input InstNode complexCls; | ||
| 1337 | output list<DAE.Var> typeVars; | ||
| 1338 | protected | ||
| 1339 | algorithm | ||
| 1340 | typeVars := match cls as InstNode.getClass(complexCls) | ||
| 1341 | case Class.INSTANCED_CLASS(restriction = Restriction.RECORD()) | ||
| 1342 |
4/4✓ Branch 1 taken 81916 times.
✓ Branch 2 taken 12781 times.
✓ Branch 4 taken 81916 times.
✓ Branch 5 taken 12781 times.
|
189394 | then list(makeTypeRecordVar(c) for c in ClassTree.getComponents(cls.elements)); |
| 1343 | |||
| 1344 | case Class.INSTANCED_CLASS(restriction = Restriction.RECORD_CONSTRUCTOR()) | ||
| 1345 |
6/6✓ Branch 3 taken 1575 times.
✓ Branch 4 taken 13722 times.
✓ Branch 5 taken 15297 times.
✓ Branch 6 taken 1575 times.
✓ Branch 7 taken 13722 times.
✓ Branch 8 taken 1575 times.
|
32169 | then list(makeTypeRecordVar(c) for c guard not InstNode.isOutput(c) |
| 1346 | in ClassTree.getComponents(cls.elements)); | ||
| 1347 | |||
| 1348 | case Class.INSTANCED_CLASS(elements = ClassTree.FLAT_TREE()) | ||
| 1349 | ✗ | then list(makeTypeVar(c) for c guard not InstNode.isOnlyOuter(c) | |
| 1350 | in ClassTree.getComponents(cls.elements)); | ||
| 1351 | |||
| 1352 | else {}; | ||
| 1353 | end match; | ||
| 1354 | end makeTypeVars; | ||
| 1355 | |||
| 1356 | function makeTypeVar | ||
| 1357 | input InstNode component; | ||
| 1358 | output DAE.Var typeVar; | ||
| 1359 | protected | ||
| 1360 | Component comp; | ||
| 1361 | Attributes attr; | ||
| 1362 | algorithm | ||
| 1363 | ✗ | comp := InstNode.component(InstNode.resolveOuter(component)); | |
| 1364 | ✗ | attr := Component.getAttributes(comp); | |
| 1365 | |||
| 1366 | ✗ | typeVar := DAE.TYPES_VAR( | |
| 1367 | InstNode.name(component), | ||
| 1368 | Attributes.toDAE(attr, InstNode.visibility(component)), | ||
| 1369 | Type.toDAE(Component.getType(comp)), | ||
| 1370 | Binding.toDAE(Component.getBinding(comp)), | ||
| 1371 | false, | ||
| 1372 | NONE() | ||
| 1373 | ); | ||
| 1374 | end makeTypeVar; | ||
| 1375 | |||
| 1376 | function makeTypeRecordVar | ||
| 1377 | input InstNode component; | ||
| 1378 | output DAE.Var typeVar; | ||
| 1379 | protected | ||
| 1380 | Component comp; | ||
| 1381 | Attributes attr; | ||
| 1382 | Visibility vis; | ||
| 1383 | Binding binding; | ||
| 1384 | Boolean bind_from_outside; | ||
| 1385 | Type ty; | ||
| 1386 | algorithm | ||
| 1387 | 95638 | comp := InstNode.component(component); | |
| 1388 | 95638 | attr := Component.getAttributes(comp); | |
| 1389 | |||
| 1390 |
2/2✓ Branch 1 taken 94469 times.
✓ Branch 2 taken 1169 times.
|
95638 | if Component.isFinal(comp) then |
| 1391 | vis := Visibility.PROTECTED; | ||
| 1392 | else | ||
| 1393 | 94469 | vis := InstNode.visibility(component); | |
| 1394 | end if; | ||
| 1395 | |||
| 1396 | 95638 | binding := Component.getBinding(comp); | |
| 1397 | 95638 | binding := Binding.mapExp(binding, stripScopePrefixExp); | |
| 1398 | 95638 | binding := Flatten.flattenBinding(binding, NFFlatten.EMPTY_PREFIX); | |
| 1399 | 95638 | bind_from_outside := Binding.source(binding) == NFBinding.Source.MODIFIER; | |
| 1400 | |||
| 1401 | 95638 | ty := Component.getType(comp); | |
| 1402 | 95638 | ty := Type.mapDims(ty, stripScopePrefixFromDim); | |
| 1403 | |||
| 1404 |
2/2✓ Branch 0 taken 94921 times.
✓ Branch 1 taken 717 times.
|
190559 | typeVar := DAE.TYPES_VAR( |
| 1405 | InstNode.name(component), | ||
| 1406 | Attributes.toDAE(attr, vis), | ||
| 1407 | Type.toDAE(ty), | ||
| 1408 | Binding.toDAE(binding), | ||
| 1409 | bind_from_outside, | ||
| 1410 | NONE() | ||
| 1411 | ); | ||
| 1412 | end makeTypeRecordVar; | ||
| 1413 | |||
| 1414 | protected function stripScopePrefixFromDim | ||
| 1415 | input output Dimension dim; | ||
| 1416 | algorithm | ||
| 1417 | 10844 | dim := Dimension.mapExp(dim, stripScopePrefixCrefExp); | |
| 1418 | end stripScopePrefixFromDim; | ||
| 1419 | |||
| 1420 | function stripScopePrefixExp | ||
| 1421 | input output Expression exp; | ||
| 1422 | algorithm | ||
| 1423 | 24792 | exp := Expression.map(exp, stripScopePrefixCrefExp); | |
| 1424 | end stripScopePrefixExp; | ||
| 1425 | |||
| 1426 | function stripScopePrefixCrefExp | ||
| 1427 | input output Expression exp; | ||
| 1428 | algorithm | ||
| 1429 | () := match exp | ||
| 1430 | case Expression.CREF() | ||
| 1431 | algorithm | ||
| 1432 | 192 | exp.cref := stripScopePrefixCref(exp.cref); | |
| 1433 | then | ||
| 1434 | (); | ||
| 1435 | |||
| 1436 | else (); | ||
| 1437 | end match; | ||
| 1438 | end stripScopePrefixCrefExp; | ||
| 1439 | |||
| 1440 | function stripScopePrefixCref | ||
| 1441 | input output ComponentRef cref; | ||
| 1442 | algorithm | ||
| 1443 | |||
| 1444 |
2/2✓ Branch 1 taken 170 times.
✓ Branch 2 taken 22 times.
|
192 | if ComponentRef.isSimple(cref) then |
| 1445 | 170 | return; | |
| 1446 | end if; | ||
| 1447 | |||
| 1448 | () := match cref | ||
| 1449 | case ComponentRef.CREF() | ||
| 1450 | algorithm | ||
| 1451 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
|
22 | if ComponentRef.isFromCref(cref.restCref) then |
| 1452 | ✗ | cref.restCref := stripScopePrefixCref(cref.restCref); | |
| 1453 | else | ||
| 1454 | 22 | cref.restCref := ComponentRef.EMPTY(); | |
| 1455 | end if; | ||
| 1456 | then | ||
| 1457 | (); | ||
| 1458 | |||
| 1459 | else (); | ||
| 1460 | end match; | ||
| 1461 | |||
| 1462 | end stripScopePrefixCref; | ||
| 1463 | |||
| 1464 | annotation(__OpenModelica_Interface="nf_frontend"); | ||
| 1465 | end NFConvertDAE; | ||
| 1466 |