Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 85.3% 273 / 0 / 320
Functions: -% 0 / 1 / 1
Branches: 76.8% 63 / 0 / 82

OMCompiler/Compiler/FrontEnd/AbsynToSCode.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 AbsynToSCode
37 " file: AbsynToSCode.mo
38 package: AbsynToSCode
39 description: AbsynToSCode translates Absyn to SCode intermediate form
40
41
42 This module contains functions to translate from
43 an Absyn data representation to a simplified version
44 called SCode.
45 The most important function in this module is the *translateAbsyn2SCode*
46 function which turns an abstract syntax tree into an SCode
47 representation. Also *translateClass*, *translateMod*, etc.
48
49 The SCode representation is then used as input to the Inst module"
50
51 public import Absyn;
52 public import AbsynUtil;
53 public import SCode;
54
55 protected
56 import BackendInterface;
57 import Config;
58 import Debug;
59 import Error;
60 import Flags;
61 import List;
62 import MetaUtil;
63 import SCodeUtil;
64 import System;
65 import Util;
66 import MetaModelica.Dangerous;
67 import Dump;
68
69 // Constant expression for AssertionLevel.error.
70 protected constant Absyn.Exp ASSERTION_LEVEL_ERROR = Absyn.CREF(Absyn.CREF_FULLYQUALIFIED(
71 Absyn.CREF_QUAL("AssertionLevel", {}, Absyn.CREF_IDENT("error", {}))));
72
73 public function translateAbsyn2SCode
74 "This function takes an Absyn.Program
75 and constructs a SCode.Program from it.
76 This particular version of translate tries to fix any uniontypes
77 in the inProgram before translating further. This should probably
78 be moved into Parser.parse since you have to modify the tree every
79 single time you translate..."
80 input Absyn.Program inProgram;
81 output SCode.Program outProgram;
82 algorithm
83 outProgram := match inProgram
84 local
85 SCode.Program sp;
86 list<Absyn.Class> inClasses;
87
88 case _
89 algorithm
90 6486 BackendInterface.initInstHashTable();
91 // adrpo: TODO! FIXME! disable function caching for now as some tests fail.
92 // setGlobalRoot(Ceval.cevalHashIndex, Ceval.emptyCevalHashTable());
93 6486 Absyn.PROGRAM(classes=inClasses) := MetaUtil.createMetaClassesInProgram(inProgram);
94
95 // set the external flag that signals the presence of inner/outer components in the model
96 6486 System.setHasInnerOuterDefinitions(false);
97 // set the external flag that signals the presence of expandable connectors in the model
98 6486 System.setHasExpandableConnectors(false);
99 // set the external flag that signals the presence of overconstrained connectors in the model
100 6486 System.setHasOverconstrainedConnectors(false);
101 // set the external flag that signals the presence of expandable connectors in the model
102 6486 System.setHasStreamConnectors(false);
103
104 // translate given absyn to scode.
105
4/4
✓ Branch 0 taken 176542 times.
✓ Branch 1 taken 6486 times.
✓ Branch 2 taken 176542 times.
✓ Branch 3 taken 6486 times.
183028 sp := list(translateClass(c) for c in inClasses);
106
107 // adrpo: note that WE DO NOT NEED to add initial functions to the program
108 // as they are already part of the initialEnv done by Builtin.initialGraph
109 then
110 sp;
111 end match;
112 end translateAbsyn2SCode;
113
114 public function translateClass
115 input Absyn.Class inClass;
116 output SCode.Element outClass;
117 algorithm
118 742809 outClass := translateClass2(inClass, Error.getNumMessages());
119 end translateClass;
120
121 protected function translateClass2
122 "This functions converts an Absyn.Class to a SCode.Class."
123 input Absyn.Class inClass;
124 input Integer inNumMessages;
125 output SCode.Element outClass;
126 algorithm
127 outClass := matchcontinue inClass
128 local
129 SCode.ClassDef d_1;
130 SCode.Restriction r_1;
131 Absyn.Class c;
132 String n;
133 Boolean p,f,e;
134 Absyn.Restriction r;
135 Absyn.ClassDef d;
136 SourceInfo file_info;
137 SCode.Element scodeClass;
138 SCode.Final sFin;
139 SCode.Encapsulated sEnc;
140 SCode.Partial sPar;
141 SCode.Comment cmt;
142
143 case c as Absyn.CLASS(name = n,partialPrefix = p,finalPrefix = f,encapsulatedPrefix = e,restriction = r,body = d,info = file_info)
144 algorithm
145 // fprint(Flags.TRANSLATE, "Translating class:" + n + "\n");
146 742809 r_1 := translateRestriction(c, r); // uniontype will not get translated!
147 742809 (d_1,cmt) := translateClassdef(d,file_info,r_1);
148 742809 sFin := SCodeUtil.boolFinal(f);
149 742809 sEnc := SCodeUtil.boolEncapsulated(e);
150 742809 sPar := SCodeUtil.boolPartial(p);
151 742809 scodeClass :=
152 SCode.CLASS(
153 n,
154 SCode.PREFIXES( // here we set only final as is a top level class!
155 SCode.PUBLIC(),
156 SCode.NOT_REDECLARE(),
157 sFin,
158 Absyn.NOT_INNER_OUTER(),
159 SCode.NOT_REPLACEABLE()),
160 sEnc,
161 sPar,
162 r_1,
163 d_1,
164 cmt,
165 file_info);
166 then
167 scodeClass;
168
169 case Absyn.CLASS(name = n,info = file_info)
170 algorithm
171 // Print out an internal error msg only if no other errors have already
172 // been printed.
173 ✗ true := intEq(Error.getNumMessages(), inNumMessages);
174 ✗ n := "AbsynToSCode.translateClass2 failed: " + n;
175 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR,{n},file_info);
176 ✗ then
177 fail();
178 end matchcontinue;
179 end translateClass2;
180
181
182 //mahge: FIX HERE. Check for proper input and output
183 //declarations in operators according to the specifications.
184 public function translateOperatorDef
185 input Absyn.ClassDef inClassDef;
186 input Absyn.Ident operatorName;
187 input SourceInfo info;
188 output SCode.ClassDef outOperDef;
189 output SCode.Comment cmt;
190 algorithm
191 (outOperDef,cmt) := match inClassDef
192 local
193 Option<String> cmtString;
194 list<SCode.Element> els;
195 list<Absyn.ClassPart> parts;
196 list<Absyn.Annotation> aann;
197 Option<SCode.Annotation> ann;
198
199 case Absyn.PARTS(classParts = parts,ann=aann, comment = cmtString)
200 algorithm
201 1922 els := translateClassdefElements(parts);
202 1922 cmt := translateCommentList(aann,cmtString);
203 1922 then
204 (SCode.PARTS(els,{},{},{},{},{},{},NONE()),cmt);
205 else
206 algorithm
207 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {"Could not translate operator to SCode because it is not using class parts."}, info);
208 ✗ then fail();
209 end match;
210 end translateOperatorDef;
211
212 public function getOperatorGivenName
213 input SCode.Element inOperatorFunction;
214 output Absyn.Path outName;
215 algorithm
216 outName := match inOperatorFunction
217 local
218 SCode.Ident name;
219 case SCode.CLASS(name,_,_,_,SCode.R_FUNCTION(SCode.FR_OPERATOR_FUNCTION()),_,_,_)
220 ✗ then Absyn.IDENT(name);
221
222 end match;
223 end getOperatorGivenName;
224
225 public function getOperatorQualName
226 input SCode.Element inOperatorFunction;
227 input SCode.Ident operName;
228 output SCode.Path outName;
229 algorithm
230 outName := match (inOperatorFunction,operName)
231 local
232 SCode.Ident name,opname;
233 case (SCode.CLASS(name,_,_,_,SCode.R_FUNCTION(_),_,_,_),opname)
234 97 then AbsynUtil.joinPaths(Absyn.IDENT(opname), Absyn.IDENT(name));
235
236 end match;
237 end getOperatorQualName;
238
239
240 public function getListofQualOperatorFuncsfromOperator
241 input SCode.Element inOperator;
242 output list<SCode.Path> outNames;
243 algorithm
244 outNames := match inOperator
245 local
246 list<SCode.Element> els;
247 SCode.Ident opername;
248 list<SCode.Path> names;
249
250 //If operator get the list of functions in it.
251 case SCode.CLASS(opername,_,_,_, SCode.R_OPERATOR() ,SCode.PARTS(elementLst = els),_,_)
252 algorithm
253 88 names := List.map1(els,getOperatorQualName,opername);
254 then
255 names;
256
257 //If operator function return its name
258 case SCode.CLASS(opername,_,_,_, SCode.R_FUNCTION(SCode.FR_OPERATOR_FUNCTION()),_,_,_)
259 algorithm
260 11 names := {Absyn.IDENT(opername)};
261 then
262 names;
263 end match;
264 end getListofQualOperatorFuncsfromOperator;
265
266 public function translateRestriction
267 "Convert a class restriction."
268 input Absyn.Class inClass;
269 input Absyn.Restriction inRestriction;
270 output SCode.Restriction outRestriction;
271 algorithm
272 outRestriction := match (inClass,inRestriction)
273 local
274 Absyn.Class d;
275 Absyn.Path name;
276 Integer index;
277 Boolean singleton, moved;
278 Absyn.FunctionPurity purity;
279 list<String> typeVars;
280
281 // ?? Only normal functions can have 'external'
282 case (d,Absyn.R_FUNCTION(Absyn.FR_NORMAL_FUNCTION(purity)))
283
2/2
✓ Branch 1 taken 3332007 times.
✓ Branch 2 taken 1250740 times.
4582747 then if containsExternalFuncDecl(d)
284 then SCode.R_FUNCTION(SCode.FR_EXTERNAL_FUNCTION(purity))
285 else SCode.R_FUNCTION(SCode.FR_NORMAL_FUNCTION(purity));
286
287 case (_,Absyn.R_FUNCTION(Absyn.FR_OPERATOR_FUNCTION())) then SCode.R_FUNCTION(SCode.FR_OPERATOR_FUNCTION());
288 case (_,Absyn.R_FUNCTION(Absyn.FR_PARALLEL_FUNCTION())) then SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION());
289 case (_,Absyn.R_FUNCTION(Absyn.FR_KERNEL_FUNCTION())) then SCode.R_FUNCTION(SCode.FR_KERNEL_FUNCTION());
290
291 case (_,Absyn.R_CLASS()) then SCode.R_CLASS();
292 case (_,Absyn.R_OPTIMIZATION()) then SCode.R_OPTIMIZATION();
293 case (_,Absyn.R_MODEL()) then SCode.R_MODEL();
294 case (_,Absyn.R_RECORD()) then SCode.R_RECORD(false);
295 case (_,Absyn.R_OPERATOR_RECORD()) then SCode.R_RECORD(true);
296
297 case (_,Absyn.R_BLOCK()) then SCode.R_BLOCK();
298
299 case (_,Absyn.R_CONNECTOR()) then SCode.R_CONNECTOR(false);
300 4436 case (_,Absyn.R_EXP_CONNECTOR()) algorithm System.setHasExpandableConnectors(true); then SCode.R_CONNECTOR(true);
301
302 case (_,Absyn.R_OPERATOR()) then SCode.R_OPERATOR();
303
304 case (_,Absyn.R_TYPE()) then SCode.R_TYPE();
305 case (_,Absyn.R_PACKAGE()) then SCode.R_PACKAGE();
306 case (_,Absyn.R_ENUMERATION()) then SCode.R_ENUMERATION();
307 case (_,Absyn.R_PREDEFINED_INTEGER()) then SCode.R_PREDEFINED_INTEGER();
308 case (_,Absyn.R_PREDEFINED_REAL()) then SCode.R_PREDEFINED_REAL();
309 case (_,Absyn.R_PREDEFINED_STRING()) then SCode.R_PREDEFINED_STRING();
310 case (_,Absyn.R_PREDEFINED_BOOLEAN()) then SCode.R_PREDEFINED_BOOLEAN();
311 // BTH
312 case (_,Absyn.R_PREDEFINED_CLOCK()) then SCode.R_PREDEFINED_CLOCK();
313 case (_,Absyn.R_PREDEFINED_ENUMERATION()) then SCode.R_PREDEFINED_ENUMERATION();
314
315 case (_,Absyn.R_METARECORD(name,index,singleton,moved,typeVars)) //MetaModelica extension, added by x07simbj
316
4/4
✓ Branch 0 taken 8203 times.
✓ Branch 1 taken 8203 times.
✓ Branch 2 taken 14054 times.
✓ Branch 3 taken 2352 times.
38663 then SCode.R_METARECORD(name,index,singleton,moved,typeVars);
317 2621 case (Absyn.CLASS(body=Absyn.PARTS(typeVars=typeVars)),Absyn.R_UNIONTYPE()) then SCode.R_UNIONTYPE(typeVars); /*MetaModelica extension added by x07simbj */
318 case (_,Absyn.R_UNIONTYPE()) then SCode.R_UNIONTYPE({}); /*MetaModelica extension added by x07simbj */
319
320 end match;
321 end translateRestriction;
322
323 protected function containsExternalFuncDecl
324 "Returns true if the Absyn.Class contains an external function declaration."
325 input Absyn.Class inClass;
326 output Boolean outBoolean;
327 algorithm
328 outBoolean := match inClass
329 local
330 list<Absyn.ClassPart> parts;
331 4307800 case Absyn.CLASS(body = Absyn.PARTS(classParts = parts)) then List.any(parts,AbsynUtil.isExternalPart);
332 162266 case Absyn.CLASS(body = Absyn.CLASS_EXTENDS(parts = parts)) then List.any(parts,AbsynUtil.isExternalPart);
333 else false;
334 end match;
335 end containsExternalFuncDecl;
336
337 protected function translateAttributes
338 "@author: adrpo
339 translates from Absyn.ElementAttributes to SCode.Attributes"
340 input Absyn.ElementAttributes inEA;
341 input list<Absyn.Subscript> extraArrayDim;
342 output SCode.Attributes outA;
343 algorithm
344 outA := match(inEA,extraArrayDim)
345 local
346 Boolean f, s;
347 Absyn.Variability v;
348 Absyn.Parallelism p;
349 Absyn.ArrayDim adim,extraADim;
350 Absyn.Direction dir;
351 Absyn.IsField fi;
352 SCode.ConnectorType ct;
353 SCode.Parallelism sp;
354 SCode.Variability sv;
355
356 case (Absyn.ATTR(f, s, p, v, dir, fi, adim),extraADim)
357 algorithm
358 648811 ct := translateConnectorType(f, s);
359 648811 sv := translateVariability(v);
360 648811 sp := translateParallelism(p);
361 648811 adim := listAppend(extraADim, adim);
362 648811 then
363 SCode.ATTR(adim, ct, sp, sv, dir, fi);
364 end match;
365 end translateAttributes;
366
367 protected function translateConnectorType
368 input Boolean inFlow;
369 input Boolean inStream;
370 output SCode.ConnectorType outType;
371 algorithm
372 outType := match(inFlow, inStream)
373 case (false, false) then SCode.POTENTIAL();
374 case (true, false) then SCode.FLOW();
375 case (false, true) then SCode.STREAM();
376 // Both flow and stream is not allowed by the grammar, so this shouldn't be
377 // possible.
378 case (true, true)
379 algorithm
380 ✗ Error.addMessage(Error.INTERNAL_ERROR,
381 {"AbsynToSCode.translateConnectorType got both flow and stream prefix."});
382 ✗ then
383 fail();
384 end match;
385 end translateConnectorType;
386
387 protected function translateClassdef
388 "This function converts an Absyn.ClassDef to a SCode.ClassDef.
389 For the DERIVED case, the conversion is fairly trivial, but for
390 the PARTS case more work is needed.
391 The result contains separate lists for:
392 elements, equations and algorithms, which are mixed in the input.
393 LS: Divided the translateClassdef into separate functions for collecting the different parts"
394 input Absyn.ClassDef inClassDef;
395 input SourceInfo info;
396 input SCode.Restriction re;
397 output SCode.ClassDef outClassDef;
398 output SCode.Comment outComment;
399 algorithm
400 (outClassDef,outComment) := match inClassDef
401 local
402 SCode.Mod mod;
403 Absyn.TypeSpec t;
404 Absyn.ElementAttributes attr;
405 list<Absyn.ElementArg> a,cmod;
406 Option<Absyn.Comment> cmt;
407 Option<String> cmtString;
408 list<SCode.Element> els,tvels;
409 list<SCode.Equation> eqs,initeqs;
410 list<SCode.AlgorithmSection> als,initals;
411 list<SCode.ConstraintSection> cos;
412 Option<SCode.ExternalDecl> decl;
413 list<Absyn.ClassPart> parts;
414 list<String> vars;
415 list<SCode.Enum> lst_1;
416 list<Absyn.EnumLiteral> lst;
417 SCode.Comment scodeCmt;
418 Absyn.Path path;
419 list<Absyn.Path> pathLst;
420 list<String> typeVars;
421 SCode.Attributes scodeAttr;
422 list<Absyn.NamedArg> classAttrs;
423 list<Absyn.Annotation> ann;
424
425 case Absyn.DERIVED(typeSpec = t,attributes = attr,arguments = a,comment = cmt)
426 algorithm
427 648811 checkTypeSpec(t, info);
428 // fprintln(Flags.TRANSLATE, "translating derived class: " + Dump.unparseTypeSpec(t));
429 1297622 mod := translateMod(SOME(Absyn.CLASSMOD(a,Absyn.NOMOD())), SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), info) "TODO: attributes of derived classes";
430 648811 scodeAttr := translateAttributes(attr, {});
431 648811 scodeCmt := translateComment(cmt);
432 648811 then
433 (SCode.DERIVED(t,mod,scodeAttr), scodeCmt);
434
435 case Absyn.PARTS(typeVars = typeVars, classAttrs = classAttrs, classParts = parts,ann=ann,comment = cmtString)
436 algorithm
437 // fprintln(Flags.TRANSLATE, "translating class parts");
438 typeVars := match re
439 16406 case SCode.R_METARECORD() then List.union(typeVars, re.typeVars);
440 2621 case SCode.R_UNIONTYPE() then List.union(typeVars, re.typeVars);
441 else typeVars;
442 end match;
443 6713827 tvels := List.map1(typeVars, makeTypeVarElement, info);
444 6713827 els := translateClassdefElements(parts);
445 6713827 els := listAppend(tvels,els);
446 6713827 eqs := translateClassdefEquations(parts);
447 6713827 initeqs := translateClassdefInitialequations(parts);
448 6713827 als := translateClassdefAlgorithms(parts);
449 6713827 initals := translateClassdefInitialalgorithms(parts);
450 6713827 cos := translateClassdefConstraints(parts);
451 6713827 scodeCmt := translateCommentList(ann, cmtString);
452 6713827 decl := translateClassdefExternaldecls(parts);
453 6713827 decl := translateAlternativeExternalAnnotation(decl, scodeCmt, info);
454 6713827 then
455 (SCode.PARTS(els,eqs,initeqs,als,initals,cos,classAttrs,decl),scodeCmt);
456
457 case Absyn.ENUMERATION(Absyn.ENUMLITERALS(enumLiterals = lst), cmt)
458 algorithm
459 // fprintln(Flags.TRANSLATE, "translating enumerations");
460 170981 lst_1 := translateEnumlist(lst);
461 170981 scodeCmt := translateComment(cmt);
462 170981 then
463 (SCode.ENUMERATION(lst_1), scodeCmt);
464
465 case Absyn.ENUMERATION(Absyn.ENUM_COLON(), cmt)
466 algorithm
467 // fprintln(Flags.TRANSLATE, "translating enumeration of ':'");
468 6 scodeCmt := translateComment(cmt);
469 then
470 (SCode.ENUMERATION({}),scodeCmt);
471
472 case Absyn.OVERLOAD(pathLst,cmt)
473 algorithm
474 // fprintln(Flags.TRANSLATE, "translating overloaded");
475 59562 scodeCmt := translateComment(cmt);
476 59562 then
477 (SCode.OVERLOAD(pathLst),scodeCmt);
478
479 case Absyn.CLASS_EXTENDS(modifications = cmod,ann=ann,comment = cmtString,parts = parts)
480 algorithm
481 // fprintln(Flags.TRANSLATE "translating model extends " + name + " ... end " + name + ";");
482 175868 els := translateClassdefElements(parts);
483 175868 eqs := translateClassdefEquations(parts);
484 175868 initeqs := translateClassdefInitialequations(parts);
485 175868 als := translateClassdefAlgorithms(parts);
486 175868 initals := translateClassdefInitialalgorithms(parts);
487 175868 cos := translateClassdefConstraints(parts);
488 351736 mod := translateMod(SOME(Absyn.CLASSMOD(cmod,Absyn.NOMOD())), SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), Absyn.dummyInfo);
489 175868 scodeCmt := translateCommentList(ann, cmtString);
490 175868 decl := translateClassdefExternaldecls(parts);
491 175868 decl := translateAlternativeExternalAnnotation(decl, scodeCmt, info);
492 175868 then
493 (SCode.CLASS_EXTENDS(mod,SCode.PARTS(els,eqs,initeqs,als,initals,cos,{},decl)),scodeCmt);
494
495 case Absyn.PDER(functionName = path,vars = vars, comment=cmt)
496 algorithm
497 // fprintln(Flags.TRANSLATE, "translating pder( " + AbsynUtil.pathString(path) + ", vars)");
498 2 scodeCmt := translateComment(cmt);
499 2 then
500 (SCode.PDER(path,vars),scodeCmt);
501
502 else
503 algorithm
504 ✗ Error.addMessage(Error.INTERNAL_ERROR,{"AbsynToSCode.translateClassdef failed"});
505 ✗ then
506 fail();
507 end match;
508 end translateClassdef;
509
510 protected function translateAlternativeExternalAnnotation
511 "Checks if the annotation for an external declaration is misplaced, i.e.
512 external \"C\"; annotation(Library=\"foo.lib\");
513 instead of
514 external \"C\" annotation(Library=\"foo.lib\");
515 "
516 input Option<SCode.ExternalDecl> decl;
517 input SCode.Comment comment;
518 input SourceInfo info;
519 output Option<SCode.ExternalDecl> outDecl;
520 protected
521 SCode.ExternalDecl ext_decl;
522 SCode.Annotation ann;
523
524 function whitelist_mod
525 input SCode.SubMod submod;
526 output Boolean keep;
527 algorithm
528 keep := match submod.ident
529 case "Library" then true;
530 case "Include" then true;
531 case "LibraryDirectory" then true;
532 case "SourceDirectory" then true;
533 case "License" then true;
534 else false;
535 end match;
536 end whitelist_mod;
537 algorithm
538 outDecl := match (decl, comment)
539 // The external declaration is missing an annotation but there is one on the function.
540 case (SOME(ext_decl as SCode.EXTERNALDECL(annotation_ = NONE())), SCode.COMMENT(annotation_ = SOME(ann)))
541 algorithm
542 // Filter out only the modifiers allowed on an external declaration.
543 3070339 ann.modification := SCodeUtil.filterSubMods(ann.modification, whitelist_mod);
544
545 // If any matching modifiers were found, issue a warning and copy them to the external declaration.
546
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3070334 times.
3070339 if not SCodeUtil.isEmptyMod(ann.modification) then
547
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if Config.languageStandardAtLeast(Config.LanguageStandard._3_3) then
548 5 Error.addSourceMessage(Error.MISPLACED_EXTERNAL_ANNOTATION, {}, info);
549 end if;
550 5 ext_decl.annotation_ := SOME(ann);
551 end if;
552 then
553 SOME(ext_decl);
554
555 else decl;
556 end match;
557 end translateAlternativeExternalAnnotation;
558
559 protected function translateEnumlist
560 "Convert an EnumLiteral list to an Ident list.
561 Comments are lost."
562 input list<Absyn.EnumLiteral> inAbsynEnumLiteralLst;
563 output list<SCode.Enum> outEnumLst;
564 algorithm
565 outEnumLst := match inAbsynEnumLiteralLst
566 local
567 list<SCode.Enum> res;
568 String id;
569 Option<Absyn.Comment> cmtOpt;
570 SCode.Comment cmt;
571 list<Absyn.EnumLiteral> rest;
572
573 case {} then {};
574 case Absyn.ENUMLITERAL(id, cmtOpt) :: rest
575 algorithm
576 787088 cmt := translateComment(cmtOpt);
577 787088 res := translateEnumlist(rest);
578 787088 then
579 (SCode.ENUM(id, cmt) :: res);
580 end match;
581 end translateEnumlist;
582
583 public function translateClassdefElements
584 "Convert an Absyn.ClassPart list to an Element list."
585 input list<Absyn.ClassPart> inAbsynClassPartLst;
586 output list<SCode.Element> outElementLst;
587 algorithm
588 outElementLst := match inAbsynClassPartLst
589 local
590 list<SCode.Element> els,es_1;
591 list<Absyn.ElementItem> es;
592 list<Absyn.ClassPart> rest;
593
594 case {} then {};
595
596 case Absyn.PUBLIC(contents = es) :: rest
597 algorithm
598 6976826 es_1 := translateEitemlist(es, SCode.PUBLIC());
599 6976826 els := translateClassdefElements(rest);
600 6976826 els := listAppend(es_1, els);
601 then
602 els;
603
604 case Absyn.PROTECTED(contents = es) :: rest
605 algorithm
606 766606 es_1 := translateEitemlist(es, SCode.PROTECTED());
607 766606 els := translateClassdefElements(rest);
608 766606 els := listAppend(es_1, els);
609 then
610 els;
611
612 case _ :: rest /* ignore all other than PUBLIC and PROTECTED, i.e. elements */
613 5626714 then translateClassdefElements(rest);
614
615 end match;
616 end translateClassdefElements;
617
618 protected function translateClassdefEquations
619 "Convert an Absyn.ClassPart list to an Equation list."
620 input list<Absyn.ClassPart> inAbsynClassPartLst;
621 output list<SCode.Equation> outEquationLst;
622 algorithm
623 outEquationLst := match inAbsynClassPartLst
624 local
625 list<SCode.Equation> eqs,eql_1,eqs_1;
626 list<Absyn.EquationItem> eql;
627 list<Absyn.ClassPart> rest;
628 case {} then {};
629 case Absyn.EQUATIONS(contents = eql) :: rest
630 algorithm
631 1070551 eql_1 := translateEquations(eql, false);
632 1070551 eqs := translateClassdefEquations(rest);
633 1070551 eqs_1 := listAppend(eqs, eql_1);
634 then
635 eqs_1;
636 case _ :: rest /* ignore everthing other than equations */
637 algorithm
638 12297673 eqs := translateClassdefEquations(rest);
639 then
640 eqs;
641 end match;
642 end translateClassdefEquations;
643
644 protected function translateClassdefInitialequations
645 "Convert an Absyn.ClassPart list to an initial Equation list."
646 input list<Absyn.ClassPart> inAbsynClassPartLst;
647 output list<SCode.Equation> outEquationLst;
648 algorithm
649 outEquationLst := match inAbsynClassPartLst
650 local
651 list<SCode.Equation> eqs,eql_1,eqs_1;
652 list<Absyn.EquationItem> eql;
653 list<Absyn.ClassPart> rest;
654 case {} then {};
655 case Absyn.INITIALEQUATIONS(contents = eql) :: rest
656 algorithm
657 104417 eql_1 := translateEquations(eql, true);
658 104417 eqs := translateClassdefInitialequations(rest);
659 104417 eqs_1 := listAppend(eqs, eql_1);
660 then
661 eqs_1;
662 case _ :: rest /* ignore everthing other than equations */
663 algorithm
664 13263807 eqs := translateClassdefInitialequations(rest);
665 then
666 eqs;
667 end match;
668 end translateClassdefInitialequations;
669
670 protected function translateClassdefAlgorithms
671 "Convert an Absyn.ClassPart list to an Algorithm list."
672 input list<Absyn.ClassPart> inAbsynClassPartLst;
673 output list<SCode.AlgorithmSection> outAlgorithmLst;
674 algorithm
675 outAlgorithmLst := match inAbsynClassPartLst
676 local
677 list<SCode.AlgorithmSection> als,als_1;
678 list<SCode.Statement> al_1;
679 list<Absyn.AlgorithmItem> al;
680 list<Absyn.ClassPart> rest;
681 case {} then {};
682 case Absyn.ALGORITHMS(contents = al) :: rest
683 algorithm
684 1112394 al_1 := translateClassdefAlgorithmitems(al);
685 1112394 als := translateClassdefAlgorithms(rest);
686 1112394 als_1 := (SCode.ALGORITHM(al_1) :: als);
687 then
688 als_1;
689 case _ :: rest /* ignore everthing other than algorithms */
690 algorithm
691 12255830 als := translateClassdefAlgorithms(rest);
692 then
693 als;
694 case _
695 algorithm
696 ✗ true := Flags.isSet(Flags.FAILTRACE);
697 ✗ Debug.trace("- AbsynToSCode.translateClassdefAlgorithms failed\n");
698 ✗ then fail();
699 end match;
700 end translateClassdefAlgorithms;
701
702 protected function translateClassdefConstraints
703 "Convert an Absyn.ClassPart list to an Constraint list."
704 input list<Absyn.ClassPart> inAbsynClassPartLst;
705 output list<SCode.ConstraintSection> outConstraintLst;
706 algorithm
707 outConstraintLst := match inAbsynClassPartLst
708 local
709 list<SCode.ConstraintSection> cos,cos_1;
710 list<Absyn.Exp> consts;
711 list<Absyn.ClassPart> rest;
712 case {} then {};
713 case Absyn.CONSTRAINTS(contents = consts) :: rest
714 algorithm
715 7 cos := translateClassdefConstraints(rest);
716 7 cos_1 := (SCode.CONSTRAINTS(consts) :: cos);
717 then
718 cos_1;
719 case _ :: rest /* ignore everthing other than Constraints */
720 algorithm
721 13368217 cos := translateClassdefConstraints(rest);
722 then
723 cos;
724 case _
725 algorithm
726 ✗ true := Flags.isSet(Flags.FAILTRACE);
727 ✗ Debug.trace("- AbsynToSCode.translateClassdefConstraints failed\n");
728 ✗ then fail();
729 end match;
730 end translateClassdefConstraints;
731
732 protected function translateClassdefInitialalgorithms
733 "Convert an Absyn.ClassPart list to an initial Algorithm list."
734 input list<Absyn.ClassPart> inAbsynClassPartLst;
735 output list<SCode.AlgorithmSection> outAlgorithmLst;
736 algorithm
737 outAlgorithmLst := match inAbsynClassPartLst
738 local
739 list<SCode.AlgorithmSection> als,als_1;
740 list<SCode.Statement> stmts;
741 list<Absyn.AlgorithmItem> al;
742 list<Absyn.ClassPart> rest;
743 case {} then {};
744 case Absyn.INITIALALGORITHMS(contents = al) :: rest
745 algorithm
746 7337 stmts := translateClassdefAlgorithmitems(al);
747 7337 als := translateClassdefInitialalgorithms(rest);
748 7337 als_1 := (SCode.ALGORITHM(stmts) :: als);
749 then
750 als_1;
751 case _ :: rest /* ignore everthing other than algorithms */
752 algorithm
753 13360887 als := translateClassdefInitialalgorithms(rest);
754 then
755 als;
756 end match;
757 end translateClassdefInitialalgorithms;
758
759 public function translateClassdefAlgorithmitems
760 input list<Absyn.AlgorithmItem> inStatements;
761 output list<SCode.Statement> outStatements;
762 algorithm
763
6/6
✓ Branch 1 taken 554750 times.
✓ Branch 2 taken 5725373 times.
✓ Branch 3 taken 6280123 times.
✓ Branch 4 taken 2377884 times.
✓ Branch 5 taken 5725373 times.
✓ Branch 6 taken 2377884 times.
8658007 outStatements := list(translateClassdefAlgorithmItem(stmt) for stmt guard AbsynUtil.isAlgorithmItem(stmt) in inStatements);
764 end translateClassdefAlgorithmitems;
765
766 protected function translateClassdefAlgorithmItem
767 "Translates an Absyn algorithm (statement) into SCode statement."
768 input Absyn.AlgorithmItem inAlgorithm;
769 output SCode.Statement outStatement;
770 protected
771 Option<Absyn.Comment> absynComment;
772 SCode.Comment comment;
773 SourceInfo info;
774 Absyn.Algorithm alg;
775 algorithm
776
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5725373 times.
5725373 Absyn.ALGORITHMITEM(algorithm_=alg, comment=absynComment, info=info) := inAlgorithm;
777 5725373 (comment, info) := translateCommentWithLineInfoChanges(absynComment, info);
778 outStatement := match alg
779 local
780 list<SCode.Statement> body, else_body;
781 list<tuple<Absyn.Exp, list<SCode.Statement>>> branches;
782 String iter_name;
783 Option<Absyn.Exp> iter_range;
784 Absyn.Exp e1, e2, e3;
785
786 case Absyn.ALG_ASSIGN()
787 4846476 then SCode.ALG_ASSIGN(alg.assignComponent, alg.value,
788 comment, info);
789
790 case Absyn.ALG_IF()
791 algorithm
792 448990 body := translateClassdefAlgorithmitems(alg.trueBranch);
793 448990 else_body := translateClassdefAlgorithmitems(alg.elseBranch);
794 448990 branches := translateAlgBranches(alg.elseIfAlgorithmBranch);
795 448990 then
796 SCode.ALG_IF(alg.ifExp, body, branches, else_body, comment, info);
797
798 case Absyn.ALG_FOR()
799 algorithm
800 139256 body := translateClassdefAlgorithmitems(alg.forBody);
801
802 // Convert for-loops with multiple iterators into nested for-loops.
803
2/2
✓ Branch 1 taken 139258 times.
✓ Branch 2 taken 139256 times.
278514 for i in listReverse(alg.iterators) loop
804 139258 (iter_name, iter_range) := translateIterator(i, info);
805 139258 body := {SCode.ALG_FOR(iter_name, iter_range, body, comment, info)};
806 end for;
807 139256 then
808 listHead(body);
809
810 case Absyn.ALG_PARFOR()
811 algorithm
812 ✗ body := translateClassdefAlgorithmitems(alg.parforBody);
813
814 // Convert for-loops with multiple iterators into nested for-loops.
815 ✗ for i in listReverse(alg.iterators) loop
816 ✗ (iter_name, iter_range) := translateIterator(i, info);
817 ✗ body := {SCode.ALG_PARFOR(iter_name, iter_range, body, comment, info)};
818 end for;
819 ✗ then
820 listHead(body);
821
822 case Absyn.ALG_WHILE()
823 algorithm
824 40332 body := translateClassdefAlgorithmitems(alg.whileBody);
825 40332 then
826 SCode.ALG_WHILE(alg.boolExpr, body, comment, info);
827
828 case Absyn.ALG_WHEN_A()
829 algorithm
830 10054 branches := translateAlgBranches((alg.boolExpr, alg.whenBody)
831 :: alg.elseWhenAlgorithmBranch);
832 10054 then
833 SCode.ALG_WHEN_A(branches, comment, info);
834
835 // assert(condition, message)
836 case Absyn.ALG_NORETCALL(functionCall = Absyn.CREF_IDENT(name = "assert"),
837 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2}, argNames = {}))
838 114938 then SCode.ALG_ASSERT(e1, e2, ASSERTION_LEVEL_ERROR, comment, info);
839
840 // assert(condition, message, level)
841 case Absyn.ALG_NORETCALL(functionCall = Absyn.CREF_IDENT(name = "assert"),
842 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2, e3}, argNames = {}))
843 459 then SCode.ALG_ASSERT(e1, e2, e3, comment, info);
844
845 // assert(condition, message, level = arg)
846 case Absyn.ALG_NORETCALL(functionCall = Absyn.CREF_IDENT(name = "assert"),
847 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2},
848 argNames = {Absyn.NAMEDARG("level", e3)}))
849 1496 then SCode.ALG_ASSERT(e1, e2, e3, comment, info);
850
851 case Absyn.ALG_NORETCALL(functionCall = Absyn.CREF_IDENT(name = "terminate"),
852 functionArgs = Absyn.FUNCTIONARGS(args = {e1}, argNames = {}))
853 63 then SCode.ALG_TERMINATE(e1, comment, info);
854
855 case Absyn.ALG_NORETCALL(functionCall = Absyn.CREF_IDENT(name = "reinit"),
856 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2}, argNames = {}))
857 25 then SCode.ALG_REINIT(e1, e2, comment, info);
858
859 case Absyn.ALG_NORETCALL()
860 algorithm
861 103195 e1 := Absyn.CALL(alg.functionCall, alg.functionArgs, {});
862 103195 then
863 SCode.ALG_NORETCALL(e1, comment, info);
864
865 case Absyn.ALG_FAILURE()
866 algorithm
867 20 body := translateClassdefAlgorithmitems(alg.equ);
868 20 then
869 SCode.ALG_FAILURE(body, comment, info);
870
871 case Absyn.ALG_TRY()
872 algorithm
873 2093 body := translateClassdefAlgorithmitems(alg.body);
874 2093 else_body := translateClassdefAlgorithmitems(alg.elseBody);
875 2093 then
876 SCode.ALG_TRY(body, else_body, comment, info);
877
878 9652 case Absyn.ALG_RETURN() then SCode.ALG_RETURN(comment, info);
879 8233 case Absyn.ALG_BREAK() then SCode.ALG_BREAK(comment, info);
880 91 case Absyn.ALG_CONTINUE() then SCode.ALG_CONTINUE(comment, info);
881
882 end match;
883 end translateClassdefAlgorithmItem;
884
885 protected function translateAlgBranches
886 "Translates the elseif or elsewhen branches from Absyn to SCode form."
887 input list<tuple<Absyn.Exp, list<Absyn.AlgorithmItem>>> inBranches;
888 output list<tuple<Absyn.Exp, list<SCode.Statement>>> outBranches;
889 protected
890 Absyn.Exp condition;
891 list<Absyn.AlgorithmItem> body;
892 algorithm
893
4/4
✓ Branch 0 taken 171215 times.
✓ Branch 1 taken 459044 times.
✓ Branch 2 taken 171215 times.
✓ Branch 3 taken 459044 times.
630259 outBranches := list(
894 match branch case (condition, body)
895 171215 then (condition, translateClassdefAlgorithmitems(body));
896 end match
897 for branch in inBranches);
898 end translateAlgBranches;
899
900 protected function translateClassdefExternaldecls
901 "Converts an Absyn.ClassPart list to an SCode.ExternalDecl option.
902 The list should only contain one external declaration, so pick the first one."
903 input list<Absyn.ClassPart> inAbsynClassPartLst;
904 output Option<SCode.ExternalDecl> outAbsynExternalDeclOption;
905 algorithm
906 outAbsynExternalDeclOption := match inAbsynClassPartLst
907 local
908 Option<SCode.ExternalDecl> res;
909 list<Absyn.ClassPart> rest;
910 Option<SCode.Ident> fn_name;
911 Option<String> lang;
912 Option<Absyn.ComponentRef> output_;
913 list<Absyn.Exp> args;
914 Option<Absyn.Annotation> aann;
915 Option<SCode.Annotation> sann;
916
917 case Absyn.EXTERNAL(externalDecl =
918 Absyn.EXTERNALDECL(fn_name, lang, output_, args, aann)) :: _
919 algorithm
920 3332008 sann := translateAnnotationOpt(aann);
921 3332008 then SOME(SCode.EXTERNALDECL(fn_name, lang, output_, args, sann));
922 case _ :: rest
923 algorithm
924 10036216 res := translateClassdefExternaldecls(rest);
925 then
926 res;
927 case {} then NONE();
928 end match;
929 end translateClassdefExternaldecls;
930
931 public function translateEitemlist
932 "This function converts a list of Absyn.ElementItem to a list of SCode.Element.
933 The boolean argument flags whether the elements are protected.
934 Annotations are not translated, i.e. they are removed when converting to SCode."
935 input list<Absyn.ElementItem> inAbsynElementItemLst;
936 input SCode.Visibility inVisibility;
937 output list<SCode.Element> outElementLst;
938 protected
939 list<SCode.Element> l = {};
940 list<Absyn.ElementItem> es = inAbsynElementItemLst;
941 Absyn.ElementItem ei;
942 Absyn.Element e;
943 algorithm
944
2/2
✓ Branch 0 taken 41126437 times.
✓ Branch 1 taken 7744399 times.
48870836 for ei in es loop
945 () := match ei
946 local
947 list<SCode.Element> e_1;
948 case Absyn.ELEMENTITEM(element = e)
949 algorithm
950 // fprintln(Flags.TRANSLATE, "translating element: " + Dump.unparseElementStr(1, e));
951 40144533 e_1 := translateElement(e, inVisibility);
952 40144533 l := List.append_reverse(e_1, l);
953 then ();
954 else ();
955 end match;
956 end for;
957 7744399 outElementLst := Dangerous.listReverseInPlace(l);
958 end translateEitemlist;
959
960 // stefan
961 public function translateAnnotation
962 "translates an Absyn.Annotation into an SCode.Annotation"
963 input Absyn.Annotation inAnnotation;
964 output Option<SCode.Annotation> outAnnotation;
965 algorithm
966 outAnnotation := match inAnnotation
967 local
968 list<Absyn.ElementArg> args;
969 SCode.Mod m;
970
971 case Absyn.ANNOTATION(elementArgs = {}) then NONE();
972
973 case Absyn.ANNOTATION(elementArgs = args)
974 algorithm
975 // Keep empty modifiers since they might have meaning in annotations, e.g. annotation(Dialog()).
976 35028602 m := translateMod(SOME(Absyn.CLASSMOD(args,Absyn.NOMOD())), SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), Absyn.dummyInfo, keepEmpty = true);
977
978
1/2
✓ Branch 1 taken 17514301 times.
✗ Branch 2 not taken.
17514301 then
979 if SCodeUtil.isEmptyMod(m) then NONE() else SOME(SCode.ANNOTATION(m));
980
981 end match;
982 end translateAnnotation;
983
984 public function translateAnnotationOpt
985 input Option<Absyn.Annotation> absynAnnotation;
986 output Option<SCode.Annotation> scodeAnnotation;
987 algorithm
988 scodeAnnotation := match absynAnnotation
989 local
990 Absyn.Annotation ann;
991
992 11775853 case SOME(ann) then translateAnnotation(ann);
993 else NONE();
994 end match;
995 end translateAnnotationOpt;
996
997 public function translateElement
998 "This function converts an Absyn.Element to a list of SCode.Element.
999 The original element may declare several components at once, and
1000 those are separated to several declarations in the result."
1001 input Absyn.Element inElement;
1002 input SCode.Visibility inVisibility;
1003 output list<SCode.Element> outElementLst;
1004 algorithm
1005 outElementLst := match (inElement,inVisibility)
1006 local
1007 list<SCode.Element> es;
1008 Boolean f;
1009 Option<Absyn.RedeclareKeywords> repl;
1010 Absyn.ElementSpec s;
1011 Absyn.InnerOuter io;
1012 SourceInfo info;
1013 Option<Absyn.ConstrainClass> cc;
1014 Option<String> expOpt;
1015 Option<Real> weightOpt;
1016 list<Absyn.NamedArg> args;
1017 String name;
1018 SCode.Visibility vis;
1019
1020 case (Absyn.ELEMENT(constrainClass = cc,finalPrefix = f,innerOuter = io, redeclareKeywords = repl,specification = s,info = info),vis)
1021 algorithm
1022 40144539 es := translateElementspec(cc, f, io, repl, vis, s, info);
1023 then
1024 es;
1025
1026 case(Absyn.DEFINEUNIT(name, args, info), vis)
1027 algorithm
1028 ✗ expOpt := translateDefineunitParam(args,"exp");
1029 ✗ weightOpt := translateDefineunitParam2(args,"weight");
1030 ✗ then {SCode.DEFINEUNIT(name,vis,expOpt,weightOpt,info)};
1031 end match;
1032 end translateElement;
1033
1034 protected function translateDefineunitParam " help function to translateElement"
1035 input list<Absyn.NamedArg> inArgs;
1036 input String inArg;
1037 output Option<String> expOpt;
1038 algorithm
1039 expOpt := match (inArgs,inArg)
1040 local
1041 String str,name, arg;
1042 list<Absyn.NamedArg> args;
1043
1044 case(Absyn.NAMEDARG(name,Absyn.STRING(str))::_,arg) guard name == arg
1045 then SOME(str);
1046 case({},_) then NONE();
1047 ✗ case(_::args,arg) then translateDefineunitParam(args,arg);
1048 end match;
1049 end translateDefineunitParam;
1050
1051 protected function translateDefineunitParam2 " help function to translateElement"
1052 input list<Absyn.NamedArg> inArgs;
1053 input String inArg;
1054 output Option<Real> weightOpt;
1055 algorithm
1056 weightOpt := match (inArgs,inArg)
1057 local
1058 String name, arg, s;
1059 Real r;
1060 list<Absyn.NamedArg> args;
1061
1062 case (Absyn.NAMEDARG(name,Absyn.REAL(s))::_,arg) guard name == arg
1063 algorithm
1064 ✗ r := stringReal(s);
1065 ✗ then SOME(r);
1066 case({},_) then NONE();
1067 ✗ case(_::args,arg) then translateDefineunitParam2(args,arg);
1068 end match;
1069 end translateDefineunitParam2;
1070
1071 protected function translateElementspec
1072 "This function turns an Absyn.ElementSpec to a list of SCode.Element.
1073 The boolean arguments say if the element is final and protected, respectively."
1074 input Option<Absyn.ConstrainClass> cc;
1075 input Boolean finalPrefix;
1076 input Absyn.InnerOuter io;
1077 input Option<Absyn.RedeclareKeywords> inRedeclareKeywords;
1078 input SCode.Visibility inVisibility;
1079 input Absyn.ElementSpec inElementSpec4;
1080 input SourceInfo inInfo;
1081 output list<SCode.Element> outElementLst;
1082 algorithm
1083 outElementLst := match (inRedeclareKeywords, inVisibility, inElementSpec4, inInfo)
1084 local
1085 SCode.ClassDef de_1;
1086 SCode.Restriction re_1;
1087 Boolean rp,pa,e,repl_1,fl,st,redecl;
1088 Option<Absyn.RedeclareKeywords> repl;
1089 Absyn.Class cl;
1090 String n;
1091 Absyn.Restriction re;
1092 Absyn.ClassDef de;
1093 SCode.Mod mod;
1094 list<Absyn.ElementArg> args;
1095 list<SCode.Element> xs_1;
1096 SCode.Parallelism prl1;
1097 SCode.Variability var1;
1098 list<SCode.Subscript> tot_dim,ad,d;
1099 Absyn.Direction di;
1100 Absyn.IsField isf;
1101 Absyn.TypeSpec t;
1102 Option<Absyn.Modification> m;
1103 Option<Absyn.Comment> comment;
1104 SCode.Comment cmt;
1105 Absyn.Import imp;
1106 Option<Absyn.Exp> cond;
1107 Absyn.Path path;
1108 Absyn.Annotation absann;
1109 Option<SCode.Annotation> ann;
1110 Absyn.Variability variability;
1111 Absyn.Parallelism parallelism;
1112 SourceInfo i,info;
1113 SCode.Element cls;
1114 SCode.Redeclare sRed;
1115 SCode.Final sFin;
1116 SCode.Replaceable sRep;
1117 SCode.Encapsulated sEnc;
1118 SCode.Partial sPar;
1119 SCode.Visibility vis;
1120 SCode.ConnectorType ct;
1121 SCode.Prefixes prefixes;
1122 Option<SCode.ConstrainClass> scc;
1123
1124
1125 case (repl, vis, Absyn.CLASSDEF(replaceable_ = rp, class_ = (Absyn.CLASS(name = n,partialPrefix = pa,encapsulatedPrefix = e,restriction = Absyn.R_OPERATOR(),body = de,info = i))), _)
1126 algorithm
1127 1922 (de_1,cmt) := translateOperatorDef(de,n,i);
1128 1922 (_, redecl) := translateRedeclarekeywords(repl);
1129 1922 sRed := SCodeUtil.boolRedeclare(redecl);
1130 1922 sFin := SCodeUtil.boolFinal(finalPrefix);
1131 1922 scc := translateConstrainClass(cc);
1132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1922 times.
1922 sRep := if rp then SCode.REPLACEABLE(scc) else SCode.NOT_REPLACEABLE();
1133 1922 sEnc := SCodeUtil.boolEncapsulated(e);
1134 1922 sPar := SCodeUtil.boolPartial(pa);
1135 1922 cls := SCode.CLASS(
1136 n,
1137 SCode.PREFIXES(vis,sRed,sFin,io,sRep),
1138 sEnc, sPar, SCode.R_OPERATOR(), de_1, cmt, i);
1139 then
1140 {cls};
1141
1142
1143 case (repl, vis, Absyn.CLASSDEF(replaceable_ = rp, class_ = (cl as Absyn.CLASS(name = n,partialPrefix = pa,encapsulatedPrefix = e,restriction = re,body = de,info = i))), _)
1144 algorithm
1145 // fprintln(Flags.TRANSLATE, "translating local class: " + n);
1146 7026248 re_1 := translateRestriction(cl, re); // uniontype will not get translated!
1147 7026248 (de_1,cmt) := translateClassdef(de,i,re_1);
1148 7026248 (_, redecl) := translateRedeclarekeywords(repl);
1149 7026248 sRed := SCodeUtil.boolRedeclare(redecl);
1150 7026248 sFin := SCodeUtil.boolFinal(finalPrefix);
1151 7026248 scc := translateConstrainClass(cc);
1152
2/2
✓ Branch 0 taken 109222 times.
✓ Branch 1 taken 6917026 times.
7026248 sRep := if rp then SCode.REPLACEABLE(scc) else SCode.NOT_REPLACEABLE();
1153 7026248 sEnc := SCodeUtil.boolEncapsulated(e);
1154 7026248 sPar := SCodeUtil.boolPartial(pa);
1155 7026248 cls := SCode.CLASS(
1156 n,
1157 SCode.PREFIXES(vis,sRed,sFin,io,sRep),
1158 sEnc, sPar, re_1, de_1, cmt, i);
1159 then
1160 {cls};
1161
1162 case (_, vis, Absyn.EXTENDS(path = path,elementArg = args,annotationOpt = NONE()), info)
1163 algorithm
1164 // fprintln(Flags.TRANSLATE, "translating extends: " + AbsynUtil.pathString(n));
1165 5103574 mod := translateMod(SOME(Absyn.CLASSMOD(args,Absyn.NOMOD())), SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), Absyn.dummyInfo);
1166 2551787 then
1167 {SCode.EXTENDS(path,vis,mod,NONE(),info)};
1168
1169 case (_, vis, Absyn.EXTENDS(path = path,elementArg = args,annotationOpt = SOME(absann)), info)
1170 algorithm
1171 // fprintln(Flags.TRANSLATE, "translating extends: " + AbsynUtil.pathString(n));
1172 2016 mod := translateMod(SOME(Absyn.CLASSMOD(args,Absyn.NOMOD())), SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), Absyn.dummyInfo);
1173 1008 ann := translateAnnotation(absann);
1174 1008 then
1175 {SCode.EXTENDS(path,vis,mod,ann,info)};
1176
1177 case (_, _, Absyn.COMPONENTS(components = {}), _) then {};
1178
1179 case (repl, vis, Absyn.COMPONENTS(attributes =
1180 (Absyn.ATTR(flowPrefix = fl,streamPrefix=st,parallelism=parallelism,variability = variability,direction = di,isField = isf,arrayDim = ad)), typeSpec = t), info)
1181 algorithm
1182 xs_1 := {};
1183
2/2
✓ Branch 0 taken 30441352 times.
✓ Branch 1 taken 30284306 times.
60725658 for comp in inElementSpec4.components loop
1184 30441352 Absyn.COMPONENTITEM(component=Absyn.COMPONENT(name = n,arrayDim = d,modification = m),comment = comment, condition=cond) := comp;
1185 // TODO: Improve performance by iterating over all elements at once instead of creating a new Absyn.COMPONENTS in each step...
1186 30441352 checkTypeSpec(t,info);
1187 // fprintln(Flags.TRANSLATE, "translating component: " + n + " final: " + SCodeUtil.finalStr(SCodeUtil.boolFinal(finalPrefix)));
1188 30441352 setHasInnerOuterDefinitionsHandler(io); // signal the external flag that we have inner/outer definitions
1189 30441352 setHasStreamConnectorsHandler(st); // signal the external flag that we have stream connectors
1190 30441352 mod := translateMod(m, SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), info);
1191 30441352 prl1 := translateParallelism(parallelism);
1192 30441352 var1 := translateVariability(variability);
1193 // PR. This adds the arraydimension that may be specified together with the type of the component.
1194 30441352 tot_dim := listAppend(d, ad);
1195 30441352 (repl_1, redecl) := translateRedeclarekeywords(repl);
1196 30441352 (cmt,info) := translateCommentWithLineInfoChanges(comment,info);
1197 30441352 sFin := SCodeUtil.boolFinal(finalPrefix);
1198 30441352 sRed := SCodeUtil.boolRedeclare(redecl);
1199 30441352 scc := translateConstrainClass(cc);
1200
2/2
✓ Branch 0 taken 18770 times.
✓ Branch 1 taken 30422582 times.
30441352 sRep := if repl_1 then SCode.REPLACEABLE(scc) else SCode.NOT_REPLACEABLE();
1201 30441352 ct := translateConnectorType(fl, st);
1202 30441352 prefixes := SCode.PREFIXES(vis,sRed,sFin,io,sRep);
1203 xs_1 := match di
1204 local
1205 SCode.Attributes attr1,attr2;
1206 SCode.Mod mod2;
1207 String inName;
1208 case Absyn.INPUT_OUTPUT() guard not Flags.isSet(Flags.SKIP_INPUT_OUTPUT_SYNTACTIC_SUGAR)
1209 algorithm
1210 22669 inName := "$in_"+n;
1211 22669 attr1 := SCode.ATTR(tot_dim,ct,prl1,var1,Absyn.INPUT(),isf);
1212 22669 attr2 := SCode.ATTR(tot_dim,ct,prl1,var1,Absyn.OUTPUT(),isf);
1213 22669 mod2 := SCode.MOD(SCode.FINAL(), SCode.NOT_EACH(), {}, SOME(Absyn.CREF(Absyn.CREF_IDENT(inName,{}))), NONE(), info);
1214 22669 then SCode.COMPONENT(n,prefixes,attr2,t,mod2,cmt,cond,info) :: SCode.COMPONENT(inName,prefixes,attr1,t,mod,cmt,cond,info) :: xs_1;
1215 30418683 else SCode.COMPONENT(n,prefixes,SCode.ATTR(tot_dim,ct,prl1,var1,di,isf),t,mod,cmt,cond,info) :: xs_1;
1216 end match;
1217 end for;
1218 30284306 xs_1 := Dangerous.listReverseInPlace(xs_1);
1219 then xs_1;
1220 case (_, vis, Absyn.IMPORT(import_ = imp, info = info), _)
1221 algorithm
1222 // fprintln(Flags.TRANSLATE, "translating import: " + Dump.unparseImportStr(imp));
1223 561882 xs_1 := translateImports(imp,vis,info);
1224 then
1225 xs_1;
1226
1227 else
1228 algorithm
1229 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"AbsynToSCode.translateElementspec failed"});
1230 ✗ then fail();
1231 end match;
1232 end translateElementspec;
1233
1234 protected function translateImports "Used to handle group imports, i.e. A.B.C.{x=a,b}"
1235 input Absyn.Import imp;
1236 input SCode.Visibility visibility;
1237 input SourceInfo info;
1238 output list<SCode.Element> elts;
1239 algorithm
1240 elts := match imp
1241 local
1242 String name;
1243 Absyn.Path p;
1244 list<Absyn.GroupImport> groups;
1245
1246 /* Maybe these should give warnings? I don't know. See https://trac.modelica.org/Modelica/ticket/955 */
1247 case Absyn.NAMED_IMPORT(name,Absyn.FULLYQUALIFIED(p))
1248 ✗ then translateImports(Absyn.NAMED_IMPORT(name,p),visibility,info);
1249 case Absyn.QUAL_IMPORT(Absyn.FULLYQUALIFIED(p))
1250 ✗ then translateImports(Absyn.QUAL_IMPORT(p),visibility,info);
1251 case Absyn.UNQUAL_IMPORT(Absyn.FULLYQUALIFIED(p))
1252 ✗ then translateImports(Absyn.UNQUAL_IMPORT(p),visibility,info);
1253
1254 case Absyn.GROUP_IMPORT(prefix=p,groups=groups)
1255 6164 then List.map3(groups, translateGroupImport, p, visibility, info);
1256 555718 else {SCode.IMPORT(imp, visibility, info)};
1257 end match;
1258 end translateImports;
1259
1260 protected function translateGroupImport "Used to handle group imports, i.e. A.B.C.{x=a,b}"
1261 input Absyn.GroupImport gimp;
1262 input Absyn.Path prefix;
1263 input SCode.Visibility visibility;
1264 input SourceInfo info;
1265 output SCode.Element elt;
1266 algorithm
1267 elt := match (gimp, visibility)
1268 local
1269 String name,rename;
1270 Absyn.Path path;
1271 SCode.Visibility vis;
1272
1273 case (Absyn.GROUP_IMPORT_NAME(name=name), vis)
1274 algorithm
1275 18549 path := AbsynUtil.joinPaths(prefix,Absyn.IDENT(name));
1276 18549 then SCode.IMPORT(Absyn.QUAL_IMPORT(path),vis,info);
1277 case (Absyn.GROUP_IMPORT_RENAME(rename=rename,name=name), vis)
1278 algorithm
1279 ✗ path := AbsynUtil.joinPaths(prefix,Absyn.IDENT(name));
1280 ✗ then SCode.IMPORT(Absyn.NAMED_IMPORT(rename,path),vis,info);
1281 end match;
1282 end translateGroupImport;
1283
1284 protected function setHasInnerOuterDefinitionsHandler
1285 "@author: adrpo
1286 This function will set the external flag that signals
1287 that a model has inner/outer component definitions"
1288 input Absyn.InnerOuter io;
1289 algorithm
1290 () := match io
1291 // no inner outer!
1292 case Absyn.NOT_INNER_OUTER() then ();
1293 // has inner, outer or innerouter components
1294 else
1295 algorithm
1296 63081 System.setHasInnerOuterDefinitions(true);
1297 then ();
1298 end match;
1299 end setHasInnerOuterDefinitionsHandler;
1300
1301 protected function setHasStreamConnectorsHandler
1302 "@author: adrpo
1303 This function will set the external flag that signals
1304 that a model has stream connectors"
1305 input Boolean streamPrefix;
1306 algorithm
1307 () := match streamPrefix
1308 // no stream prefix
1309 case false then ();
1310 // has stream prefix
1311 case true
1312 algorithm
1313 1512 System.setHasStreamConnectors(true);
1314 then ();
1315 end match;
1316 end setHasStreamConnectorsHandler;
1317
1318 protected function translateRedeclarekeywords
1319 "author: PA
1320 For now, translate to bool, replaceable."
1321 input Option<Absyn.RedeclareKeywords> inRedeclKeywords;
1322 output Boolean outIsReplaceable;
1323 output Boolean outIsRedeclared;
1324 algorithm
1325 (outIsReplaceable, outIsRedeclared) := match inRedeclKeywords
1326 case SOME(Absyn.REDECLARE()) then (false, true);
1327 case SOME(Absyn.REPLACEABLE()) then (true, false);
1328 case SOME(Absyn.REDECLARE_REPLACEABLE()) then (true, true);
1329 else (false, false);
1330 end match;
1331 end translateRedeclarekeywords;
1332
1333 protected function translateConstrainClass
1334 input Option<Absyn.ConstrainClass> inConstrainClass;
1335 output Option<SCode.ConstrainClass> outConstrainClass;
1336 algorithm
1337 outConstrainClass := match inConstrainClass
1338 local
1339 Absyn.Path cc_path;
1340 list<Absyn.ElementArg> eltargs;
1341 Option<Absyn.Comment> cmt;
1342 SCode.Comment cc_cmt;
1343 Absyn.Modification mod;
1344 SCode.Mod cc_mod;
1345
1346 case SOME(Absyn.CONSTRAINCLASS(elementSpec =
1347 Absyn.EXTENDS(path = cc_path, elementArg = eltargs), comment = cmt))
1348 algorithm
1349 19520 mod := Absyn.CLASSMOD(eltargs, Absyn.NOMOD());
1350 19520 cc_mod := translateMod(SOME(mod), SCode.NOT_FINAL(), SCode.NOT_EACH(), NONE(), Absyn.dummyInfo);
1351 19520 cc_cmt := translateComment(cmt);
1352 19520 then
1353 SOME(SCode.CONSTRAINCLASS(cc_path, cc_mod, cc_cmt));
1354
1355 else NONE();
1356 end match;
1357 end translateConstrainClass;
1358
1359 protected function translateParallelism
1360 "Converts an Absyn.Parallelism to SCode.Parallelism."
1361 input Absyn.Parallelism inParallelism;
1362 output SCode.Parallelism outParallelism;
1363 algorithm
1364 outParallelism := match inParallelism
1365 case Absyn.PARGLOBAL() then SCode.PARGLOBAL();
1366 case Absyn.PARLOCAL() then SCode.PARLOCAL();
1367 case Absyn.NON_PARALLEL() then SCode.NON_PARALLEL();
1368 end match;
1369 end translateParallelism;
1370
1371 protected function translateVariability
1372 "Converts an Absyn.Variability to SCode.Variability."
1373 input Absyn.Variability inVariability;
1374 output SCode.Variability outVariability;
1375 algorithm
1376 outVariability := match inVariability
1377 case Absyn.VAR() then SCode.VAR();
1378 case Absyn.DISCRETE() then SCode.DISCRETE();
1379 case Absyn.PARAM() then SCode.PARAM();
1380 case Absyn.CONST() then SCode.CONST();
1381 end match;
1382 end translateVariability;
1383
1384 protected function translateEquations
1385 "This function transforms a list of Absyn.Equation to a list of
1386 SCode.Equation, by applying the translateEquation function to each
1387 equation."
1388 input list<Absyn.EquationItem> inAbsynEquationItemLst;
1389 input Boolean inIsInitial;
1390 output list<SCode.Equation> outEquationLst;
1391 algorithm
1392
2/2
✓ Branch 0 taken 10009695 times.
✓ Branch 1 taken 2022924 times.
12032619 outEquationLst := list(
1393 match eq
1394 local
1395 SCode.Comment com;
1396 SourceInfo info;
1397 case Absyn.EQUATIONITEM()
1398 algorithm
1399 9412008 (com,info) := translateCommentWithLineInfoChanges(eq.comment, eq.info);
1400 9412008 then translateEquation(eq.equation_,com,info,inIsInitial);
1401 end match
1402 for eq guard match eq case Absyn.EQUATIONITEM() then true; else false; end match in inAbsynEquationItemLst
1403 );
1404 end translateEquations;
1405
1406 protected function translateCommentWithLineInfoChanges
1407 "turns an Absyn.Comment into an SCode.Comment"
1408 input Option<Absyn.Comment> inComment;
1409 input SourceInfo inInfo;
1410 output SCode.Comment outComment;
1411 output SourceInfo outInfo;
1412 algorithm
1413 45578733 outComment := translateComment(inComment);
1414 45578733 outInfo := getInfoAnnotationOrDefault(outComment, inInfo);
1415 end translateCommentWithLineInfoChanges;
1416
1417 protected function getInfoAnnotationOrDefault "Replaces the file info if there is an annotation __OpenModelica_FileInfo=(\"fileName\",line). Should be improved."
1418 input SCode.Comment comment;
1419 input SourceInfo default;
1420 output SourceInfo info;
1421 algorithm
1422 info := match comment
1423 local
1424 list<SCode.SubMod> lst;
1425 case SCode.COMMENT(annotation_=SOME(SCode.ANNOTATION(modification=SCode.MOD(subModLst=lst))))
1426 11560847 then getInfoAnnotationOrDefault2(lst,default);
1427 else default;
1428 end match;
1429 end getInfoAnnotationOrDefault;
1430
1431 protected function getInfoAnnotationOrDefault2
1432 input list<SCode.SubMod> lst;
1433 input SourceInfo default;
1434 output SourceInfo info;
1435 algorithm
1436 info := match lst
1437 local
1438 list<SCode.SubMod> rest;
1439 String fileName;
1440 Integer line;
1441 case {} then default;
1442 case SCode.NAMEMOD(ident="__OpenModelica_FileInfo",mod=SCode.MOD(binding=SOME(Absyn.TUPLE({Absyn.STRING(fileName),Absyn.INTEGER(line)}))))::_
1443 ✗ then SOURCEINFO(fileName,false,line,0,line,0,0.0);
1444 11910990 case _::rest then getInfoAnnotationOrDefault2(rest,default);
1445 end match;
1446 end getInfoAnnotationOrDefault2;
1447
1448 protected function translateComment
1449 "turns an Absyn.Comment into an SCode.Comment"
1450 input Option<Absyn.Comment> inComment;
1451 output SCode.Comment outComment;
1452 algorithm
1453 outComment := match inComment
1454 local
1455 Option<Absyn.Annotation> absann;
1456 Option<SCode.Annotation> ann;
1457 Option<String> ostr;
1458
1459 case NONE() then SCode.noComment;
1460 case SOME(Absyn.COMMENT(absann,ostr))
1461 algorithm
1462 23023508 ann := translateAnnotationOpt(absann);
1463 23023508 ostr := Util.applyOption(ostr,System.unescapedString);
1464 23023508 then SCode.COMMENT(ann,ostr);
1465 end match;
1466 end translateComment;
1467
1468 protected function translateCommentList
1469 "turns an Absyn.Comment into an SCode.Comment"
1470 input list<Absyn.Annotation> inAnns;
1471 input Option<String> inString;
1472 output SCode.Comment outComment;
1473 algorithm
1474 outComment := match inAnns
1475 local
1476 Absyn.Annotation absann;
1477 list<Absyn.Annotation> anns;
1478 Option<SCode.Annotation> ann;
1479 Option<String> ostr;
1480
1481 1154136 case {} then SCode.COMMENT(NONE(),inString);
1482 case {absann}
1483 algorithm
1484 5737435 ann := translateAnnotation(absann);
1485 5737435 ostr := Util.applyOption(inString,System.unescapedString);
1486 5737435 then SCode.COMMENT(ann,ostr);
1487 case absann::anns
1488 algorithm
1489 46 absann := AbsynUtil.mergeAnnotationsList(absann, anns);
1490 46 ann := translateAnnotation(absann);
1491 46 ostr := Util.applyOption(inString,System.unescapedString);
1492 46 then SCode.COMMENT(ann,ostr);
1493 end match;
1494 end translateCommentList;
1495
1496 protected function translateCommentSeparate
1497 "turns an Absyn.Comment into an SCode.Annotation + string"
1498 input Option<Absyn.Comment> inComment;
1499 output Option<SCode.Annotation> outAnn;
1500 output Option<String> outStr;
1501 algorithm
1502 (outAnn,outStr) := match inComment
1503 local Absyn.Annotation absann;
1504 Option<SCode.Annotation> ann;
1505 String str;
1506
1507 case NONE() then (NONE(),NONE());
1508 case SOME(Absyn.COMMENT(NONE(),NONE())) then (NONE(),NONE());
1509 case SOME(Absyn.COMMENT(NONE(),SOME(str))) then (NONE(),SOME(str));
1510 case SOME(Absyn.COMMENT(SOME(absann),NONE()))
1511 algorithm
1512 ✗ ann := translateAnnotation(absann);
1513 then
1514 (ann,NONE());
1515 case SOME(Absyn.COMMENT(SOME(absann),SOME(str)))
1516 algorithm
1517 ✗ ann := translateAnnotation(absann);
1518 then
1519 (ann,SOME(str));
1520 end match;
1521 end translateCommentSeparate;
1522
1523 protected function translateEquation
1524 input Absyn.Equation inEquation;
1525 input SCode.Comment inComment;
1526 input SourceInfo inInfo;
1527 input Boolean inIsInitial;
1528 output SCode.Equation outEquation;
1529 algorithm
1530 outEquation := match inEquation
1531 local
1532 Absyn.Exp e1, e2, e3;
1533 list<SCode.Equation> else_branch, body;
1534 list<tuple<Absyn.Exp, list<SCode.Equation>>> branches;
1535 String iter_name;
1536 Option<Absyn.Exp> iter_range;
1537 list<Absyn.Exp> conditions;
1538 list<list<SCode.Equation>> bodies;
1539
1540 case Absyn.EQ_IF()
1541 algorithm
1542 313632 body := translateEquations(inEquation.equationTrueItems, inIsInitial);
1543
2/2
✓ Branch 0 taken 255340 times.
✓ Branch 1 taken 58292 times.
568972 (conditions, bodies) :=
1544 List.map1_2(inEquation.elseIfBranches, translateEqBranch, inIsInitial);
1545 313632 conditions := inEquation.ifExp :: conditions;
1546 313632 else_branch := translateEquations(inEquation.equationElseItems, inIsInitial);
1547 313632 then
1548 SCode.EQ_IF(conditions, body :: bodies, else_branch, inComment, inInfo);
1549
1550 case Absyn.EQ_WHEN_E()
1551 algorithm
1552 40578 body := translateEquations(inEquation.whenEquations, inIsInitial);
1553
1/2
✓ Branch 0 taken 40578 times.
✗ Branch 1 not taken.
81156 (conditions, bodies) :=
1554 List.map1_2(inEquation.elseWhenEquations, translateEqBranch, inIsInitial);
1555
7/8
✓ Branch 0 taken 2140 times.
✓ Branch 1 taken 40578 times.
✓ Branch 2 taken 2140 times.
✓ Branch 3 taken 40578 times.
✓ Branch 4 taken 2140 times.
✓ Branch 5 taken 40578 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40578 times.
42718 branches := list((c, b) threaded for c in conditions, b in bodies);
1556 40578 then
1557 SCode.EQ_WHEN(inEquation.whenExp, body, branches, inComment, inInfo);
1558
1559 case Absyn.EQ_EQUALS()
1560 3215301 then SCode.EQ_EQUALS(inEquation.leftSide, inEquation.rightSide, inComment, inInfo);
1561
1562 case Absyn.EQ_PDE()
1563 4 then SCode.EQ_PDE(inEquation.leftSide, inEquation.rightSide, inEquation.domain, inComment, inInfo);
1564
1565 case Absyn.EQ_CONNECT()
1566 5555396 then SCode.EQ_CONNECT(inEquation.connector1, inEquation.connector2, inComment, inInfo);
1567
1568 case Absyn.EQ_FOR()
1569 algorithm
1570 99923 body := translateEquations(inEquation.forEquations, inIsInitial);
1571
1572 // Convert for-loops with multiple iterators into nested for-loops.
1573
2/2
✓ Branch 1 taken 99928 times.
✓ Branch 2 taken 99923 times.
199851 for i in listReverse(inEquation.iterators) loop
1574 99928 (iter_name, iter_range) := translateIterator(i, inInfo);
1575 99928 body := {SCode.EQ_FOR(iter_name, iter_range, body, inComment, inInfo)};
1576 end for;
1577 99923 then
1578 listHead(body);
1579
1580 // assert(condition, message)
1581 case Absyn.EQ_NORETCALL(functionName = Absyn.CREF_IDENT(name = "assert"),
1582 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2}, argNames = {}))
1583 131895 then SCode.EQ_ASSERT(e1, e2, ASSERTION_LEVEL_ERROR, inComment, inInfo);
1584
1585 // assert(condition, message, level)
1586 case Absyn.EQ_NORETCALL(functionName = Absyn.CREF_IDENT(name = "assert"),
1587 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2, e3}, argNames = {}))
1588 505 then SCode.EQ_ASSERT(e1, e2, e3, inComment, inInfo);
1589
1590 // assert(condition, message, level = arg)
1591 case Absyn.EQ_NORETCALL(functionName = Absyn.CREF_IDENT(name = "assert"),
1592 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2},
1593 argNames = {Absyn.NAMEDARG("level", e3)}))
1594 6972 then SCode.EQ_ASSERT(e1, e2, e3, inComment, inInfo);
1595
1596 // terminate(message)
1597 case Absyn.EQ_NORETCALL(functionName = Absyn.CREF_IDENT(name = "terminate"),
1598 functionArgs = Absyn.FUNCTIONARGS(args = {e1}, argNames = {}))
1599 572 then SCode.EQ_TERMINATE(e1, inComment, inInfo);
1600
1601 // reinit(cref, exp)
1602 case Absyn.EQ_NORETCALL(functionName = Absyn.CREF_IDENT(name = "reinit"),
1603 functionArgs = Absyn.FUNCTIONARGS(args = {e1, e2},
1604 argNames = {}))
1605 3915 then SCode.EQ_REINIT(e1, e2, inComment, inInfo);
1606
1607 // Other nonreturning calls. assert, terminate and reinit with the wrong
1608 // number of arguments is also turned into a noretcall, since it's
1609 // preferable to handle the error during instantation instead of here.
1610 case Absyn.EQ_NORETCALL()
1611 43315 then SCode.EQ_NORETCALL(Absyn.CALL(inEquation.functionName, inEquation.functionArgs, {}),
1612 inComment, inInfo);
1613
1614 end match;
1615 end translateEquation;
1616
1617 protected function translateEqBranch
1618 input tuple<Absyn.Exp, list<Absyn.EquationItem>> inBranch;
1619 input Boolean inIsInitial;
1620 output Absyn.Exp outCondition;
1621 output list<SCode.Equation> outBody;
1622 protected
1623 list<Absyn.EquationItem> body;
1624 algorithm
1625 80191 (outCondition, body) := inBranch;
1626 80191 outBody := translateEquations(body, inIsInitial);
1627 end translateEqBranch;
1628
1629 protected function translateIterator
1630 input Absyn.ForIterator inIterator;
1631 input SourceInfo inInfo;
1632 output String outName;
1633 output Option<Absyn.Exp> outRange;
1634 protected
1635 Option<Absyn.Exp> guard_exp;
1636 algorithm
1637 239186 Absyn.ITERATOR(name = outName, guardExp = guard_exp, range = outRange) := inIterator;
1638
1639
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 239186 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 239186 times.
239186 if isSome(guard_exp) then
1640 ✗ Error.addSourceMessageAndFail(Error.INTERNAL_ERROR,
1641 {"For loops with guards not yet implemented"}, inInfo);
1642 end if;
1643 end translateIterator;
1644
1645 protected function translateElementAddinfo
1646 "function: translateElementAddinfo"
1647 input SCode.Element elem;
1648 input SourceInfo nfo;
1649 output SCode.Element oelem;
1650 algorithm
1651 oelem := match elem
1652 local
1653 SCode.Ident a1;
1654 SCode.Attributes a6;
1655 Absyn.TypeSpec a7;
1656 SCode.Mod a8;
1657 SCode.Comment a10;
1658 Option<Absyn.Exp> a11;
1659 SCode.Prefixes p;
1660
1661 case SCode.COMPONENT(a1,p,a6,a7,a8,a10,a11,_)
1662 ✗ then SCode.COMPONENT(a1,p,a6,a7,a8,a10,a11,nfo);
1663
1664 else elem;
1665 end match;
1666 end translateElementAddinfo;
1667
1668 /* Modification management */
1669 public function translateMod
1670 "Builds an SCode.Mod from an Absyn.Modification."
1671 input Option<Absyn.Modification> inMod;
1672 input SCode.Final finalPrefix;
1673 input SCode.Each eachPrefix;
1674 input Option<String> comment;
1675 input SourceInfo info;
1676 input Boolean keepEmpty = false; // Keep empty modifiers, e.g. (x).
1677 output SCode.Mod outMod;
1678 protected
1679 list<Absyn.ElementArg> args;
1680 Absyn.EqMod eqmod;
1681 list<SCode.SubMod> subs;
1682 Option<Absyn.Exp> binding;
1683 algorithm
1684 (args, eqmod) := match inMod
1685 case SOME(Absyn.CLASSMOD(elementArgLst = args, eqMod = eqmod)) then (args, eqmod);
1686 else ({}, Absyn.NOMOD());
1687 end match;
1688
1689
2/2
✓ Branch 0 taken 48682848 times.
✓ Branch 1 taken 81908671 times.
130591519 subs := if listEmpty(args) then {} else translateArgs(args, keepEmpty);
1690
1691 binding := match eqmod
1692 63162056 case Absyn.EQMOD() then SOME(eqmod.exp);
1693 else NONE();
1694 end match;
1695
1696 outMod := match (subs, binding, finalPrefix, eachPrefix)
1697 case ({}, NONE(), SCode.NOT_FINAL(), SCode.NOT_EACH()) then SCode.NOMOD();
1698 111141359 else SCode.MOD(finalPrefix, eachPrefix, subs, binding, comment, info);
1699 end match;
1700 end translateMod;
1701
1702 protected function translateArgs
1703 input list<Absyn.ElementArg> args;
1704 input Boolean keepEmpty;
1705 output list<SCode.SubMod> subMods = {};
1706 protected
1707 SCode.Mod smod;
1708 SCode.Element elem;
1709 SCode.SubMod sub;
1710 Absyn.ComponentRef cr1, cr2;
1711 String name;
1712 algorithm
1713
2/2
✓ Branch 0 taken 79521362 times.
✓ Branch 1 taken 48682848 times.
128204210 for arg in args loop
1714 subMods := match arg
1715 case Absyn.MODIFICATION()
1716 algorithm
1717 79238730 smod := translateMod(arg.modification, SCodeUtil.boolFinal(arg.finalPrefix),
1718 translateEach(arg.eachPrefix), arg.comment, arg.info);
1719
1720
4/4
✓ Branch 1 taken 116859 times.
✓ Branch 2 taken 79121871 times.
✓ Branch 3 taken 95940 times.
✓ Branch 4 taken 20919 times.
79238730 if not SCodeUtil.isEmptyMod(smod) or keepEmpty then
1721 79217811 sub := translateSub(arg.path, smod, arg.info);
1722 subMods := sub :: subMods;
1723 end if;
1724 then
1725 subMods;
1726
1727 case Absyn.REDECLARATION()
1728 algorithm
1729
2/4
✗ Branch 2 not taken.
✓ Branch 3 taken 282614 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 282614 times.
282614 elem::{} := translateElementspec(arg.constrainClass, arg.finalPrefix,
1730 Absyn.NOT_INNER_OUTER(), SOME(arg.redeclareKeywords), SCode.PUBLIC(),
1731 arg.elementSpec, arg.info);
1732
1733 282614 sub := SCode.NAMEMOD(AbsynUtil.elementSpecName(arg.elementSpec),
1734 SCode.REDECL(
1735 SCodeUtil.boolFinal(arg.finalPrefix),
1736 translateEach(arg.eachPrefix),
1737 elem));
1738 then
1739 sub :: subMods;
1740
1741 case Absyn.ELEMENTARGCOMMENT() then subMods;
1742
1743 case Absyn.INHERITANCEBREAK(Absyn.EQ_CONNECT(connector1 = Absyn.ComponentRef.CREF_IDENT(name = "break"),
1744 connector2 = Absyn.ComponentRef.CREF_IDENT(name = name)))
1745 10 then SCode.SubMod.NAMEMOD(name, SCode.Mod.BREAK_COMPONENT(arg.info)) :: subMods;
1746
1747 case Absyn.INHERITANCEBREAK(Absyn.EQ_CONNECT(connector1 = cr1, connector2 = cr2))
1748 5 then SCode.SubMod.NAMEMOD("", SCode.Mod.BREAK_CONNECT(cr1, cr2, arg.info)) :: subMods;
1749
1750 end match;
1751 end for;
1752
1753 48682848 subMods := listReverse(subMods);
1754 end translateArgs;
1755
1756 protected function translateSub
1757 "This function converts a Absyn.ComponentRef plus a list
1758 of modifications into a number of nested SCode.SUBMOD."
1759 input Absyn.Path inPath;
1760 input SCode.Mod inMod;
1761 input SourceInfo info;
1762 output SCode.SubMod outSubMod;
1763 algorithm
1764 outSubMod := match inPath
1765 local
1766 String i;
1767 Absyn.Path path;
1768 SCode.Mod mod;
1769 SCode.SubMod sub;
1770
1771 // Then the normal rules
1772 79217811 case Absyn.IDENT(name = i) then SCode.NAMEMOD(i,inMod);
1773 case Absyn.QUALIFIED(name = i,path = path)
1774 algorithm
1775 52 sub := translateSub(path, inMod, info);
1776 52 mod := SCode.MOD(SCode.NOT_FINAL(),SCode.NOT_EACH(),{sub},NONE(),NONE(),info);
1777 52 then SCode.NAMEMOD(i,mod);
1778 end match;
1779 end translateSub;
1780
1781 protected function makeTypeVarElement
1782 input String str;
1783 input SourceInfo info;
1784 output SCode.Element elt;
1785 protected
1786 SCode.ClassDef cd;
1787 Absyn.TypeSpec ts;
1788 algorithm
1789 ts := Absyn.TCOMPLEX(Absyn.IDENT("polymorphic"),{Absyn.TPATH(Absyn.IDENT("Any"),NONE())},NONE());
1790 163856 cd := SCode.DERIVED(ts,SCode.NOMOD(),
1791 SCode.ATTR({},SCode.POTENTIAL(), SCode.NON_PARALLEL(), SCode.VAR(),Absyn.BIDIR(),Absyn.NONFIELD()));
1792 163856 elt := SCode.CLASS(
1793 str,
1794 SCode.PREFIXES(
1795 SCode.PUBLIC(),
1796 SCode.NOT_REDECLARE(),
1797 SCode.FINAL(),
1798 Absyn.NOT_INNER_OUTER(),
1799 SCode.NOT_REPLACEABLE()),
1800 SCode.NOT_ENCAPSULATED(),SCode.NOT_PARTIAL(),SCode.R_TYPE(),cd,SCode.noComment,info);
1801 end makeTypeVarElement;
1802
1803 protected function translateEach
1804 input Absyn.Each inAEach;
1805 output SCode.Each outSEach;
1806 algorithm
1807 outSEach := match inAEach
1808 case Absyn.EACH() then SCode.EACH();
1809 case Absyn.NON_EACH() then SCode.NOT_EACH();
1810 end match;
1811 end translateEach;
1812
1813 protected function checkTypeSpec
1814 input Absyn.TypeSpec ts;
1815 input SourceInfo info;
1816 algorithm
1817 () := match ts
1818 local
1819 list<Absyn.TypeSpec> tss;
1820 Absyn.TypeSpec ts2;
1821 String str;
1822 case Absyn.TPATH() then ();
1823 case Absyn.TCOMPLEX(path=Absyn.IDENT("tuple"),typeSpecs={ts2})
1824 algorithm
1825 ✗ str := AbsynUtil.typeSpecString(ts);
1826 ✗ Error.addSourceMessage(Error.TCOMPLEX_TUPLE_ONE_NAME,{str},info);
1827 ✗ checkTypeSpec(ts2,info);
1828 then ();
1829 // It is okay for tuples to have multiple typespecs
1830 case Absyn.TCOMPLEX(path=Absyn.IDENT("tuple"),typeSpecs=tss as (_::_::_))
1831 algorithm
1832 16614 List.map1_0(tss, checkTypeSpec, info);
1833 then ();
1834 case Absyn.TCOMPLEX(typeSpecs={ts2})
1835 algorithm
1836 142304 checkTypeSpec(ts2,info);
1837 then ();
1838 case Absyn.TCOMPLEX(typeSpecs=tss)
1839 algorithm
1840
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 857 times.
857 if listMember(ts.path, {Absyn.IDENT("list"),Absyn.IDENT("List"),Absyn.IDENT("array"),Absyn.IDENT("Array"),Absyn.IDENT("polymorphic"),Absyn.IDENT("Option")}) then
1841 ✗ str := AbsynUtil.typeSpecString(ts);
1842 ✗ Error.addSourceMessage(Error.TCOMPLEX_MULTIPLE_NAMES,{str},info);
1843 ✗ List.map1_0(tss, checkTypeSpec, info);
1844 end if;
1845 then ();
1846 end match;
1847 end checkTypeSpec;
1848
1849 annotation(__OpenModelica_Interface="frontend_dump");
1850 end AbsynToSCode;
1851