Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 55.7% 603 / 0 / 1083
Functions: -% 0 / 1 / 1
Branches: 38.9% 306 / 0 / 786

OMCompiler/Compiler/FrontEnd/Ceval.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 Ceval
37 " file: Ceval.mo
38 package: Ceval
39 description: Constant propagation of expressions
40
41
42 This module handles constant propagation (or evaluation)
43 When elaborating expressions, in the Static module, expressions are checked to
44 find out its type. It also checks whether the expressions are constant and the function
45 ceval in this module will then evaluate the expression to a constant value, defined
46 in the Values module.
47
48 Input:
49 Env: Environment with bindings
50 Exp: Expression to check for constant evaluation
51 Bool flag determines whether the current instantiation is implicit
52 InteractiveSymbolTable is optional, and used in interactive mode, e.g. from OMShell
53
54 Output:
55 Value: The evaluated value
56 InteractiveSymbolTable: Modified symbol table
57 Subscript list : Evaluates subscripts and generates constant expressions."
58
59 public import Absyn;
60 public import AbsynUtil;
61 public import DAE;
62 public import FCore;
63 public import FGraph;
64 public import InstTypes;
65 public import Values;
66 public import Lookup;
67
68 // protected imports
69 protected
70 protected import BackendCevalInterface;
71 protected import ComponentReference;
72 protected import ComponentReferenceBasics;
73 protected import Config;
74 protected import Debug;
75 protected import Error;
76 protected import Expression;
77 protected import ExpressionBasics;
78 protected import ExpressionDump;
79 protected import ExpressionSimplify;
80 protected import Flags;
81 protected import InstBinding;
82 protected import InstUtil;
83 protected import List;
84 protected import Print;
85 protected import SCode;
86 import SCodeUtil;
87 protected import Static;
88 protected import System;
89 protected import Types;
90 protected import Util;
91 protected import ValuesDump;
92 protected import ValuesUtil;
93 protected import ClassInf;
94 protected import Global;
95 protected import MetaModelica.Dangerous.listReverseInPlace;
96
97 public function ceval "
98 This function is used when the value of a constant expression is
99 needed. It takes an environment and an expression and calculates
100 its value.
101 The third argument indicates whether the evaluation is performed in the
102 interactive environment (implicit instantiation), in which case function
103 calls are evaluated.
104 The last argument is an optional dimension."
105 input FCore.Cache inCache;
106 input FCore.Graph inEnv;
107 input DAE.Exp inExp;
108 input Boolean inBoolean "impl";
109 input Absyn.Msg inMsg = Absyn.MSG(Absyn.dummyInfo);
110 input Integer numIter = 0 "Maximum recursion depth";
111 output FCore.Cache outCache;
112 output Values.Value outValue;
113 algorithm
114 4785462 (outCache,outValue) := cevalWork1(inCache,inEnv,inExp,inBoolean,inMsg,numIter,numIter > Global.recursionDepthLimit);
115 end ceval;
116
117 protected function cevalWork1
118 input FCore.Cache inCache;
119 input FCore.Graph inEnv;
120 input DAE.Exp inExp;
121 input Boolean inBoolean "impl";
122 input Absyn.Msg inMsg;
123 input Integer numIter "Maximum recursion depth";
124 input Boolean iterReached;
125 output FCore.Cache outCache;
126 output Values.Value outValue;
127 algorithm
128 (outCache,outValue) := match (inMsg, iterReached)
129 local
130 SourceInfo info;
131 String str1,str2;
132 case (_, false)
133 algorithm
134 4785462 (outCache,outValue) := cevalWork2(inCache,inEnv,inExp,inBoolean,inMsg,numIter);
135 then (outCache,outValue);
136 case (Absyn.MSG(info=info), true)
137 algorithm
138 str1 := intString(Global.recursionDepthLimit);
139 ✗ str2 := ExpressionBasics.printExpStr(inExp);
140 ✗ Error.addSourceMessage(Error.RECURSION_DEPTH_WARNING, {str1,str2,FGraph.printGraphPathStr(inEnv)}, info);
141 ✗ then fail();
142 end match;
143 end cevalWork1;
144
145 protected function cevalWork2 "
146 This function is used when the value of a constant expression is
147 needed. It takes an environment and an expression and calculates
148 its value.
149 The third argument indicates whether the evaluation is performed in the
150 interactive environment (implicit instantiation), in which case function
151 calls are evaluated.
152 The last argument is an optional dimension."
153 input FCore.Cache inCache;
154 input FCore.Graph inEnv;
155 input DAE.Exp inExp;
156 input Boolean inBoolean "impl";
157 input Absyn.Msg inMsg;
158 input Integer numIter;
159 output FCore.Cache outCache;
160 output Values.Value outValue;
161
162 partial function ReductionOperator
163 input Values.Value v1;
164 input Values.Value v2;
165 output Values.Value res;
166 end ReductionOperator;
167 algorithm
168 (outCache,outValue):=
169 matchcontinue (inCache, inEnv, inExp, inBoolean, inMsg)
170 local
171 Integer i,indx,index;
172 Real lhvReal,rhvReal,sum,r;
173 String str,lhvStr,rhvStr,s,foldName,resultName;
174 Boolean impl,b,b_1,lhvBool,rhvBool,resBool;
175 Absyn.Exp exp_1,exp;
176 FCore.Graph env;
177 Absyn.Msg msg;
178 Absyn.Element elt_1,elt;
179 Absyn.CodeNode c;
180 list<Values.Value> es_1,elts,vallst,vlst1,vlst2,reslst,aval,rhvals,lhvals,arr,arr_1,ivals,rvals,vals;
181 list<DAE.Exp> es,expl;
182 list<list<DAE.Exp>> expll;
183 Values.Value v,newval,value,sval,elt1,elt2,v_1,lhs_1,rhs_1,resVal,lhvVal,rhvVal;
184 DAE.Exp lh,rh,e,lhs,rhs,e1,e2,cond;
185 Absyn.Path funcpath, name;
186 DAE.Operator relop;
187 FCore.Cache cache;
188 DAE.Exp expExp;
189 list<Integer> dims;
190 DAE.Dimensions arrayDims;
191 DAE.ComponentRef cr;
192 list<String> fieldNames, n, names;
193 DAE.Exp daeExp;
194 Absyn.Path path;
195 Option<Values.Value> ov;
196 Option<DAE.Exp> foldExp;
197 DAE.Type ty;
198 list<DAE.Type> tys;
199 DAE.ReductionIterators iterators;
200 list<list<Values.Value>> valMatrix;
201 SourceInfo info;
202 list<String> comp;
203 Absyn.ReductionIterType iterType;
204 list<DAE.Subscript> subs;
205
206 // uncomment for debugging
207 // case (cache,env,inExp,_,_,_)
208 // equation print("Ceval.ceval: " + ExpressionBasics.printExpStr(inExp) + " in env: " + FGraph.printGraphPathStr(env) + "\n");
209 // then fail();
210
211 773926 case (cache, _, DAE.ICONST(integer = i), _, _) then (cache,Values.INTEGER(i));
212
213 1722886 case (cache, _, DAE.RCONST(real = r), _, _) then (cache,Values.REAL(r));
214
215 692491 case (cache, _, DAE.SCONST(string = s), _, _) then (cache,Values.STRING(s));
216
217
2/2
✓ Branch 0 taken 83360 times.
✓ Branch 1 taken 39570 times.
206290 case (cache, _, DAE.BCONST(bool = b), _, _) then (cache,Values.BOOL(b));
218
219 case (cache, _, DAE.ENUM_LITERAL(name = name, index = i), _, _)
220 10543 then (cache, Values.ENUM_LITERAL(name, i));
221
222 case (cache, env, DAE.CODE(code = Absyn.C_EXPRESSION(exp = exp)), impl, msg)
223 algorithm
224 573 (cache, exp_1) := cevalAstExp(cache, env, exp, impl, msg, Absyn.dummyInfo);
225 573 then
226 (cache,Values.CODE(Absyn.C_EXPRESSION(exp_1)));
227
228 case (cache, env, DAE.CODE(code = Absyn.C_ELEMENT(element = elt)), impl, msg)
229 algorithm
230 ✗ (cache,elt_1) := cevalAstElt(cache,env, elt, impl, msg);
231 ✗ then
232 (cache,Values.CODE(Absyn.C_ELEMENT(elt_1)));
233
234 14433 case (cache, _, DAE.CODE(code = c), _, _) then (cache,Values.CODE(c));
235
236 case (cache, env, DAE.ARRAY(array = es, ty = DAE.T_ARRAY(dims = arrayDims)), impl, msg)
237 algorithm
238 294121 (cache, es_1) := cevalList(cache, env, es, impl, msg, numIter);
239 v :=
240 matchcontinue()
241 case ()
242 algorithm
243 293848 dims := List.map(arrayDims, Expression.dimensionSize);
244 293845 v := Values.ARRAY(es_1,dims);
245 then v;
246 else
247 algorithm
248 3 v := ValuesMake.makeArray(es_1);
249 then
250 v;
251 end matchcontinue;
252 293848 then
253 (cache,v);
254
255 // annotation(Icon(graphics))
256 case (cache, env, DAE.ARRAY(array = es, ty = DAE.T_UNKNOWN()), impl, msg)
257 guard Config.getGraphicsExpMode() and Config.getEvaluateParametersInAnnotations()
258 algorithm
259 ✗ (cache, es_1) := cevalList(cache, env, es, impl, msg, numIter);
260 v :=
261 matchcontinue()
262 case ()
263 algorithm
264 ✗ dims := {1};
265 ✗ v := Values.ARRAY(es_1,dims);
266 then v;
267 else
268 algorithm
269 ✗ v := ValuesMake.makeArray(es_1);
270 then
271 v;
272 end matchcontinue;
273 ✗ then
274 (cache,v);
275
276 case (cache, env, DAE.MATRIX(matrix = expll, ty = DAE.T_ARRAY(dims = arrayDims)), impl, msg)
277 algorithm
278 10386 dims := List.map(arrayDims, Expression.dimensionSize);
279 10386 (cache,elts) := cevalMatrixElt(cache, env, expll, impl,msg,numIter+1);
280 10359 then
281 (cache,Values.ARRAY(elts,dims));
282
283 // MetaModelica
284 case (cache, env, DAE.LIST(valList = expl), impl, msg)
285 algorithm
286 10762 (cache,es_1) := cevalList(cache,env, expl, impl, msg,numIter);
287 10762 then
288 (cache,Values.LIST(es_1));
289
290 case (cache, env, DAE.BOX(exp=e1), impl, msg)
291 algorithm
292 26271 (cache,v) := ceval(cache,env,e1,impl,msg,numIter+1);
293 then
294 (cache,v);
295
296 case (cache, env, DAE.UNBOX(exp=e1), impl, msg)
297 algorithm
298
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
54 (cache,Values.META_BOX(v)) := ceval(cache,env,e1,impl,msg,numIter+1);
299 46 then
300 (cache,v);
301
302 case (cache, env, DAE.CONS(car=e1,cdr=e2), impl, msg)
303 algorithm
304 19 (cache,v) := ceval(cache,env,e1,impl,msg,numIter+1);
305
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
19 (cache,Values.LIST(vallst)) := ceval(cache,env,e2,impl,msg,numIter);
306 19 then
307 (cache,Values.LIST(v::vallst));
308
309 // MetaModelica Partial Function
310 case (_, _, DAE.CREF(ty = DAE.T_FUNCTION_REFERENCE_VAR()), _, _)
311 then
312 fail();
313
314
315 // MetaModelica Uniontype Constructor
316 case (cache, env, DAE.METARECORDCALL(path=funcpath,args=expl,fieldNames=fieldNames,index=index), impl, msg)
317 algorithm
318 54675 (cache,vallst) := cevalList(cache, env, expl, impl, msg,numIter);
319 54675 then (cache,Values.RECORD(funcpath,vallst,fieldNames,index));
320
321 // MetaModelica Option type. sjoelund 2009-07-01
322 case (cache, _, DAE.META_OPTION(NONE()), _, _)
323 10662 then (cache,Values.OPTION(NONE()));
324 case (cache, env, DAE.META_OPTION(SOME(expExp)), impl, msg)
325 algorithm
326 817 (cache,value) := ceval(cache,env,expExp,impl,msg,numIter+1);
327 817 then (cache,Values.OPTION(SOME(value)));
328
329 // MetaModelica Tuple. sjoelund 2009-07-02
330 case (cache, env, DAE.META_TUPLE(expl), impl, msg)
331 algorithm
332
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4505 times.
4505 true := Config.acceptMetaModelicaGrammar();
333 4505 (cache,vallst) := cevalList(cache, env, expl, impl, msg,numIter);
334 4505 then (cache,Values.META_TUPLE(vallst));
335
336 case (cache, env, DAE.TUPLE(expl), impl, msg)
337 algorithm
338 // true = Config.acceptMetaModelicaGrammar();
339 127 (cache,vallst) := cevalList(cache, env, expl, impl, msg,numIter);
340 127 then (cache,Values.TUPLE(vallst));
341
342 case (cache, env, DAE.CREF(componentRef = cr), (false), msg)
343 algorithm
344 63658 (cache,v) := cevalCref(cache, env, cr, false, msg, numIter+1) "When in interactive mode, always evaluate crefs, i.e non-implicit mode.." ;
345 //Debug.traceln("cevalCref cr: " + ComponentReferenceBasics.printComponentRefStr(c) + " in s: " + FGraph.printGraphPathStr(env) + " v:" + ValuesDump.valString(v));
346 then
347 (cache,v);
348
349 case (cache, env, DAE.CREF(componentRef = cr), impl, msg)
350 algorithm
351 398672 (cache,v) := cevalCref(cache,env, cr, impl,msg,numIter+1);
352 //Debug.traceln("cevalCref cr: " + ComponentReferenceBasics.printComponentRefStr(c) + " in s: " + FGraph.printGraphPathStr(env) + " v:" + ValuesDump.valString(v));
353 then
354 (cache,v);
355
356 // Evaluates for build in types. ADD, SUB, MUL, DIV for Reals and Integers.
357 case (cache, env, expExp, impl, msg)
358 algorithm
359 587927 (cache,v) := cevalBuiltin(cache,env, expExp, impl, msg,numIter+1);
360 then
361 (cache,v);
362
363 // ceval smooth(0, expr) -> expr
364 case (cache, env, (DAE.CALL(path=funcpath, expLst={DAE.ICONST(0), expExp}, attr=DAE.CALL_ATTR(isImpure=false))), impl, msg)
365 algorithm
366
4/6
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 590 times.
✓ Branch 3 taken 590 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 590 times.
591 Absyn.IDENT("smooth") := AbsynUtil.makeNotFullyQualified(funcpath);
367 590 (cache,value) := ceval(cache,env,expExp,impl,msg,numIter+1);
368 then
369 (cache,value);
370
371 // adrpo: TODO! this needs more work as if we don't have a symtab we run into unloading of dlls problem
372 // lochel: do not evaluate impure function calls
373 case (cache, env, (e as DAE.CALL(path=funcpath, expLst=expl, attr=DAE.CALL_ATTR(isImpure=false))), impl, msg)
374 algorithm
375 // do not handle Connection.isRoot here!
376
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 51695 times.
51695 false := AbsynUtil.pathEqual(Absyn.QUALIFIED("Connection",Absyn.IDENT("isRoot")), funcpath);
377 // do not roll back errors generated by evaluating the arguments
378 51695 (cache, vallst) := cevalList(cache, env, expl, impl, msg,numIter);
379 51159 (cache, newval):= BackendCevalInterface.cevalCallFunction(cache, env, e, vallst, impl, msg,numIter+1);
380 then
381 (cache,newval);
382
383 // Cast of records (Check done by static, so ok to just evaluate the expression and return)
384 case(cache, env, DAE.CAST(ty = ty,exp = e), impl, msg)
385 algorithm
386
2/2
✓ Branch 1 taken 8144 times.
✓ Branch 2 taken 5 times.
8149 true := Types.isRecord(ty);
387 5 (cache,value) := ceval(cache, env, e, impl, msg, numIter+1);
388 then (cache,value);
389
390 // Try Interactive functions last
391 case (cache, env, (e as DAE.CALL()), (true), msg)
392 algorithm
393 11333 (cache,value) := BackendCevalInterface.cevalInteractiveFunctions(cache, env, e, msg,numIter+1);
394 then
395 (cache,value);
396
397 case (_, _, e as DAE.CALL(), _, _)
398 algorithm
399
1/2
✓ Branch 1 taken 3435 times.
✗ Branch 2 not taken.
3435 true := Flags.isSet(Flags.FAILTRACE);
400 ✗ Debug.trace("- Ceval.ceval DAE.CALL failed: ");
401 ✗ str := ExpressionBasics.printExpStr(e);
402 ✗ Debug.traceln(str);
403 ✗ then
404 fail();
405
406 case (cache, env, DAE.RECORD(path=funcpath, exps=expl, comp = fieldNames), impl, msg)
407 algorithm
408 8386 (cache, vallst) := cevalList(cache, env, expl, impl, msg,numIter);
409 8386 then
410 (cache,Values.RECORD(funcpath,vallst,fieldNames,-1));
411
412 // Strings
413 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.ADD(ty = DAE.T_STRING()),exp2 = rh), impl, msg)
414 algorithm
415
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7543 times.
7565 (cache,Values.STRING(lhvStr)) := ceval(cache,env, lh, impl, msg,numIter);
416
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7499 times.
7543 (cache,Values.STRING(rhvStr)) := ceval(cache,env, rh, impl, msg,numIter);
417 7499 str := stringAppend(lhvStr, rhvStr);
418 7499 then
419 (cache,Values.STRING(str));
420
421 // Numerical
422 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.ADD(ty = DAE.T_REAL()),exp2 = rh), impl, msg)
423 algorithm
424
2/2
✓ Branch 1 taken 126 times.
✓ Branch 2 taken 86243 times.
86409 (cache,Values.REAL(lhvReal)) := ceval(cache,env, lh, impl, msg,numIter);
425
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 86222 times.
86243 (cache,Values.REAL(rhvReal)) := ceval(cache,env, rh, impl, msg,numIter);
426 86222 sum := lhvReal + rhvReal;
427 86222 then
428 (cache,Values.REAL(sum));
429
430 // Array addition
431 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.ADD_ARR(),exp2 = rh), impl, msg)
432 algorithm
433
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 306 times.
306 (cache,Values.ARRAY(vlst1,dims)) := ceval(cache,env, lh, impl, msg,numIter);
434
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 306 times.
306 (cache,Values.ARRAY(vlst2,_)) := ceval(cache,env, rh, impl, msg,numIter);
435 306 reslst := ValuesUtil.addElementwiseArrayelt(vlst1, vlst2);
436 306 then
437 (cache,Values.ARRAY(reslst,dims));
438
439 // Array subtraction
440 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.SUB_ARR(),exp2 = rh), impl, msg)
441 algorithm
442 ✗ (cache,Values.ARRAY(vlst1,dims)) := ceval(cache,env, lh, impl, msg,numIter);
443 ✗ (cache,Values.ARRAY(vlst2,_)) := ceval(cache,env, rh, impl, msg,numIter);
444 ✗ reslst := ValuesUtil.subElementwiseArrayelt(vlst1, vlst2);
445 ✗ then
446 (cache,Values.ARRAY(reslst,dims));
447
448 // Array multiplication
449 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL_ARR(),exp2 = rh), impl, msg)
450 algorithm
451 ✗ (cache,Values.ARRAY(vlst1,dims)) := ceval(cache,env, lh, impl, msg,numIter);
452 ✗ (cache,Values.ARRAY(vlst2,_)) := ceval(cache,env, rh, impl, msg,numIter);
453 ✗ reslst := ValuesUtil.mulElementwiseArrayelt(vlst1, vlst2);
454 ✗ then
455 (cache,Values.ARRAY(reslst,dims));
456
457 // Array division
458 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.DIV_ARR(),exp2 = rh), impl, msg)
459 algorithm
460 ✗ (cache,Values.ARRAY(vlst1,dims)) := ceval(cache,env, lh, impl, msg,numIter);
461 ✗ (cache,Values.ARRAY(vlst2,_)) := ceval(cache,env, rh, impl, msg,numIter);
462 ✗ reslst := ValuesUtil.divElementwiseArrayelt(vlst1, vlst2);
463 ✗ then
464 (cache,Values.ARRAY(reslst,dims));
465
466 // Array power
467 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.POW_ARR2(),exp2 = rh), impl, msg)
468 algorithm
469 ✗ (cache,Values.ARRAY(vlst1,dims)) := ceval(cache,env, lh, impl, msg,numIter);
470 ✗ (cache,Values.ARRAY(vlst2,_)) := ceval(cache,env, rh, impl, msg,numIter);
471 ✗ reslst := ValuesUtil.powElementwiseArrayelt(vlst1, vlst2);
472 ✗ then
473 (cache,Values.ARRAY(reslst,dims));
474
475 // Array multipled scalar
476 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL_ARRAY_SCALAR(),exp2 = rh), impl, msg)
477 algorithm
478 453 (cache,sval) := ceval(cache,env, rh, impl, msg,numIter);
479
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 453 times.
453 (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, lh, impl, msg,numIter);
480 453 reslst := ValuesUtil.multScalarArrayelt(sval, aval);
481 453 then
482 (cache,Values.ARRAY(reslst,dims));
483
484 // Array add scalar
485 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.ADD_ARRAY_SCALAR(),exp2 = rh), impl, msg)
486 algorithm
487 ✗ (cache,sval) := ceval(cache,env, rh, impl, msg,numIter);
488 ✗ (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, lh, impl, msg,numIter);
489 ✗ reslst := ValuesUtil.addScalarArrayelt(sval, aval);
490 ✗ then
491 (cache,Values.ARRAY(reslst,dims));
492
493 // Array subtract scalar
494 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.SUB_SCALAR_ARRAY(),exp2 = rh), impl, msg)
495 algorithm
496 1 (cache,sval) := ceval(cache,env, lh, impl, msg,numIter);
497
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, rh, impl, msg,numIter);
498 1 reslst := ValuesUtil.subScalarArrayelt(sval, aval);
499 1 then
500 (cache,Values.ARRAY(reslst,dims));
501
502 // Array power scalar
503 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.POW_SCALAR_ARRAY(),exp2 = rh), impl, msg)
504 algorithm
505 ✗ (cache,sval) := ceval(cache,env, lh, impl, msg,numIter);
506 ✗ (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, rh, impl, msg,numIter);
507 ✗ reslst := ValuesUtil.powScalarArrayelt(sval, aval);
508 ✗ then
509 (cache,Values.ARRAY(reslst,dims));
510
511 // Array power scalar
512 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.POW_ARRAY_SCALAR(),exp2 = rh), impl, msg)
513 algorithm
514 ✗ (cache,sval) := ceval(cache,env, rh, impl, msg,numIter);
515 ✗ (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, lh, impl, msg,numIter);
516 ✗ reslst := ValuesUtil.powArrayeltScalar(sval, aval);
517 ✗ then
518 (cache,Values.ARRAY(reslst,dims));
519
520 // scalar div array
521 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.DIV_SCALAR_ARRAY(),exp2 = rh), impl, msg)
522 algorithm
523 ✗ (cache,sval) := ceval(cache,env, lh, impl, msg,numIter);
524 ✗ (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, rh, impl, msg,numIter);
525 ✗ reslst := ValuesUtil.divScalarArrayelt(sval, aval);
526 ✗ then
527 (cache,Values.ARRAY(reslst,dims));
528
529 // array div scalar
530 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.DIV_ARRAY_SCALAR(),exp2 = rh), impl, msg)
531 algorithm
532 1250 (cache,sval) := ceval(cache,env, rh, impl, msg,numIter+1);
533
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1250 times.
1250 (cache,Values.ARRAY(aval,dims)) := ceval(cache,env, lh, impl, msg,numIter);
534 1250 reslst := ValuesUtil.divArrayeltScalar(sval, aval);
535 1250 then
536 (cache,Values.ARRAY(reslst,dims));
537
538 // scalar multiplied array
539 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL_SCALAR_PRODUCT(),exp2 = rh), impl, msg)
540 algorithm
541
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3146 times.
3146 (cache,Values.ARRAY(valueLst = rhvals)) := ceval(cache,env, rh, impl, msg,numIter);
542
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3146 times.
3146 (cache,Values.ARRAY(valueLst = lhvals)) := ceval(cache,env, lh, impl, msg,numIter);
543 3146 resVal := ValuesUtil.multScalarProduct(rhvals, lhvals);
544 3146 then
545 (cache,resVal);
546
547 // array multipled array
548 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL_MATRIX_PRODUCT(),exp2 = rh), impl, msg)
549 algorithm
550
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750 times.
1500 (cache,Values.ARRAY(valueLst = (lhvals as (elt1 :: _)))) := ceval(cache,env, lh, impl, msg,numIter) "{{..}..{..}} {...}" ;
551
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750 times.
750 (cache,Values.ARRAY(valueLst = (rhvals as (elt2 :: _)))) := ceval(cache,env, rh, impl, msg,numIter);
552
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
750 true := ValuesUtil.isArray(elt1);
553
1/2
✓ Branch 1 taken 750 times.
✗ Branch 2 not taken.
750 false := ValuesUtil.isArray(elt2);
554 ✗ resVal := ValuesUtil.multScalarProduct(lhvals, rhvals);
555 ✗ then
556 (cache,resVal);
557
558 // array multiplied array
559 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL_MATRIX_PRODUCT(),exp2 = rh), impl, msg)
560 algorithm
561
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750 times.
1500 (cache,Values.ARRAY(valueLst = (rhvals as (elt1 :: _)))) := ceval(cache,env, rh, impl, msg,numIter) "{...} {{..}..{..}}" ;
562
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750 times.
750 (cache,Values.ARRAY(valueLst = (lhvals as (elt2 :: _)))) := ceval(cache,env, lh, impl, msg,numIter);
563
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
750 true := ValuesUtil.isArray(elt1);
564
1/2
✓ Branch 1 taken 750 times.
✗ Branch 2 not taken.
750 false := ValuesUtil.isArray(elt2);
565 ✗ resVal := ValuesUtil.multScalarProduct(lhvals, rhvals);
566 ✗ then
567 (cache,resVal);
568
569 // array multiplied array
570 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL_MATRIX_PRODUCT(),exp2 = rh), impl, msg)
571 algorithm
572
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750 times.
750 (cache,Values.ARRAY((rhvals as (elt1 :: _)),_)) := ceval(cache,env, rh, impl, msg,numIter+1) "{{..}..{..}} {{..}..{..}}" ;
573
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 750 times.
750 (cache,Values.ARRAY((lhvals as (elt2 :: _)),_)) := ceval(cache,env, lh, impl, msg,numIter+1);
574
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
750 true := ValuesUtil.isArray(elt1);
575
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 750 times.
750 true := ValuesUtil.isArray(elt2);
576 750 vallst := ValuesUtil.multMatrix(lhvals, rhvals);
577 750 then
578 (cache,ValuesMake.makeArray(vallst));
579
580 //POW (integer or real)
581 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.POW(),exp2 = rh), impl, msg)
582 algorithm
583 11742 (cache,lhvVal) := ceval(cache,env, lh, impl, msg,numIter);
584 11726 (cache,rhvVal) := ceval(cache,env, rh, impl, msg,numIter);
585 11726 resVal := ValuesUtil.safeIntRealOp(lhvVal, rhvVal, Values.POWOP());
586 11726 then
587 (cache,resVal);
588
589 //MUL (integer or real)
590 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.MUL(),exp2 = rh), impl, msg)
591 algorithm
592 172241 (cache,lhvVal) := ceval(cache,env, lh, impl, msg,numIter);
593 172236 (cache,rhvVal) := ceval(cache,env, rh, impl, msg,numIter);
594 172058 resVal := ValuesUtil.safeIntRealOp(lhvVal, rhvVal, Values.MULOP());
595 172058 then
596 (cache,resVal);
597
598 //DIV (integer or real)
599 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.DIV(),exp2 = rh), impl, msg)
600 algorithm
601 16769 (cache,lhvVal) := ceval(cache,env, lh, impl, msg,numIter);
602 16756 (cache,rhvVal) := ceval(cache,env, rh, impl, msg,numIter);
603 16740 resVal := ValuesUtil.safeIntRealOp(lhvVal, rhvVal, Values.DIVOP());
604 16740 then
605 (cache,resVal);
606
607 //DIV (handle div by zero)
608 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.DIV(), exp2 = rh), impl, msg as Absyn.MSG(info = info))
609 algorithm
610 ✗ (_,lhvVal) := ceval(cache,env, rh, impl, msg,numIter);
611 ✗ true := ValuesUtil.isZero(lhvVal);
612 ✗ lhvStr := ExpressionBasics.printExpStr(lh);
613 ✗ rhvStr := ExpressionBasics.printExpStr(rh);
614 ✗ Error.addSourceMessage(Error.DIVISION_BY_ZERO, {lhvStr,rhvStr}, info);
615 ✗ then
616 fail();
617
618 //ADD (integer or real)
619 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.ADD(),exp2 = rh), impl, msg)
620 algorithm
621 10920 (cache,lhvVal) := ceval(cache,env, lh, impl, msg,numIter);
622 10850 (cache,rhvVal) := ceval(cache,env, rh, impl, msg,numIter);
623 10611 resVal := ValuesUtil.safeIntRealOp(lhvVal, rhvVal, Values.ADDOP());
624 10611 then
625 (cache,resVal);
626
627 //SUB (integer or real)
628 case (cache, env, DAE.BINARY(exp1 = lh,operator = DAE.SUB(),exp2 = rh), impl, msg)
629 algorithm
630 14967 (cache,lhvVal) := ceval(cache,env, lh, impl, msg,numIter);
631 14953 (cache,rhvVal) := ceval(cache,env, rh, impl, msg,numIter);
632 14953 resVal := ValuesUtil.safeIntRealOp(lhvVal, rhvVal, Values.SUBOP());
633 14953 then
634 (cache,resVal);
635
636 // unary minus of array
637 case (cache, env, DAE.UNARY(operator = DAE.UMINUS_ARR(),exp = daeExp), impl, msg)
638 algorithm
639
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 (cache,Values.ARRAY(arr,dims)) := ceval(cache,env, daeExp, impl, msg,numIter+1);
640 10 arr_1 := List.map(arr, ValuesUtil.valueNeg);
641 10 then
642 (cache,Values.ARRAY(arr_1,dims));
643
644 // unary minus of expression
645 case (cache, env, DAE.UNARY(operator = DAE.UMINUS(),exp = daeExp), impl, msg)
646 algorithm
647 88558 (cache,v) := ceval(cache,env, daeExp, impl, msg,numIter+1);
648 88540 v_1 := ValuesUtil.valueNeg(v);
649 88540 then
650 (cache,v_1);
651
652 // Logical lhs AND rhs (handle lhs = false)
653 case (cache, env, DAE.LBINARY(exp1 = lh,operator = DAE.AND(_),exp2 = rh), impl, msg)
654 algorithm
655
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2358 times.
2365 (cache,Values.BOOL(lhvBool)) := ceval(cache,env, lh, impl, msg,numIter);
656
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 1854 times.
2358 if not lhvBool then
657 504 v := Values.BOOL(false);
658 else
659
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1854 times.
1854 (cache,Values.BOOL(rhvBool)) := ceval(cache,env, rh, impl, msg,numIter);
660 1854 resBool := boolAnd(lhvBool, rhvBool);
661
2/2
✓ Branch 0 taken 595 times.
✓ Branch 1 taken 1259 times.
2449 v := Values.BOOL(resBool);
662 end if;
663 2358 then
664 (cache,v);
665
666 // lhs OR rhs (handle lhs = true)
667 case (cache, env, DAE.LBINARY(exp1 = lh,operator = DAE.OR(_),exp2 = rh), impl, msg)
668 algorithm
669
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1181 times.
1370 (cache,Values.BOOL(lhvBool)) := ceval(cache, env, lh, impl, msg, numIter);
670
2/2
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 595 times.
1181 if lhvBool then
671 586 v := Values.BOOL(true);
672 else
673
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 595 times.
595 (cache,Values.BOOL(rhvBool)) := ceval(cache, env, rh, impl, msg, numIter);
674 595 resBool := boolOr(lhvBool, rhvBool);
675
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 195 times.
995 v := Values.BOOL(resBool);
676 end if;
677 1181 then
678 (cache,v);
679
680 // Special case for a boolean expression like if( expression or ARRAY_IDEX_OUT_OF_BOUNDS_ERROR)
681 // "expression" in this case we return the lh expression to be equall to
682 // the previous c-code generation.
683 case (cache, env, DAE.LBINARY(exp1 = lh,operator = DAE.OR(_),exp2 = rh), impl, msg)
684 algorithm
685
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
189 (cache,v as Values.BOOL(_)) := ceval(cache,env, lh, impl,msg,numIter);
686 ✗ failure(ceval(cache,env, rh, impl, msg, numIter));
687 ✗ then
688 (cache,v);
689
690 // NOT
691 case (cache, env, DAE.LUNARY(operator = DAE.NOT(_),exp = e), impl, msg)
692 algorithm
693
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
1329 (cache,Values.BOOL(b)) := ceval(cache,env, e, impl, msg,numIter+1);
694 b_1 := boolNot(b);
695
2/2
✓ Branch 0 taken 781 times.
✓ Branch 1 taken 508 times.
2070 then
696 (cache,Values.BOOL(b_1));
697
698 // relations <, >, <=, >=, <>
699 case (cache, env, DAE.RELATION(exp1 = lhs,operator = relop,exp2 = rhs), impl, msg)
700 algorithm
701 29164 (cache,lhs_1) := ceval(cache,env, lhs, impl,msg,numIter);
702 28335 (cache,rhs_1) := ceval(cache,env, rhs, impl,msg,numIter);
703 28335 v := cevalRelation(lhs_1, relop, rhs_1);
704 28335 then
705 (cache,v);
706
707 case (_, _, DAE.RANGE(), _, _)
708 2808 then cevalRange(inCache, inEnv, inExp, inBoolean, inMsg, numIter);
709
710 // cast integer to real
711 case (cache, env, DAE.CAST(ty = DAE.T_REAL(),exp = e), impl, msg)
712 algorithm
713
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7967 times.
8118 (cache,Values.INTEGER(i)) := ceval(cache,env, e, impl, msg,numIter+1);
714 7967 r := intReal(i);
715 7967 then
716 (cache,Values.REAL(r));
717
718 // cast real to integer
719 case (cache, env, DAE.CAST(ty = DAE.T_INTEGER(), exp = e), impl, msg)
720 algorithm
721 ✗ (cache,Values.REAL(r)) := ceval(cache, env, e, impl,msg,numIter+1);
722 ✗ i := realInt(r);
723 ✗ then
724 (cache,Values.INTEGER(i));
725
726 // cast integer to enum
727 case (cache, env, DAE.CAST(ty = DAE.T_ENUMERATION(path = path, names = n), exp = e), impl, msg)
728 algorithm
729 ✗ (cache, Values.INTEGER(i)) := ceval(cache, env, e, impl, msg,numIter+1);
730 ✗ str := listGet(n, i);
731 ✗ path := AbsynUtil.joinPaths(path, Absyn.IDENT(str));
732 ✗ then
733 (cache, Values.ENUM_LITERAL(path, i));
734
735 // cast integer array to real array
736 case (cache, env, DAE.CAST(ty = DAE.T_ARRAY(ty = DAE.T_REAL()),exp = e), impl, msg)
737 algorithm
738
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 (cache,Values.ARRAY(ivals,dims)) := ceval(cache,env, e, impl, msg,numIter+1);
739 26 rvals := ValuesUtil.typeConvert(DAE.T_INTEGER_DEFAULT, DAE.T_REAL_DEFAULT, ivals);
740 26 then
741 (cache,Values.ARRAY(rvals,dims));
742
743 // if expressions, select then/else branch if condition is true/false
744 case (cache, env, DAE.IFEXP(expCond = cond,expThen = e1,expElse = e2), impl, msg)
745 algorithm
746 20904 (cache,v) := ceval(cache, env, cond, impl, msg, numIter+1);
747 // ifexp true then then branch, else else branch"
748
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16926 times.
16930 Values.BOOL(resBool) := v;
749
2/2
✓ Branch 0 taken 10459 times.
✓ Branch 1 taken 6467 times.
27385 (cache, v) := ceval(cache, env, if resBool then e1 else e2, impl, msg,numIter);
750 then
751 (cache,v);
752
753 // indexing for array[integer index]
754 case (cache, env, DAE.ASUB(exp = e,sub = ((DAE.INDEX(DAE.ICONST(indx)))::{})), impl, msg)
755 algorithm
756
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 581 times.
581 (cache,Values.ARRAY(vals,_)) := ceval(cache,env, e, impl, msg,numIter+1) "asub" ;
757 581 v := listGet(vals, indx);
758 581 then
759 (cache,v);
760
761 // indexing for array[subscripts]
762 case (cache, env, DAE.ASUB(exp = e,sub = subs ), impl, msg)
763 algorithm
764
4/4
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 320 times.
✓ Branch 2 taken 398 times.
✓ Branch 3 taken 320 times.
718 expl := list(Expression.getSubscriptExp(sub) for sub in subs);
765
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 318 times.
320 (cache,Values.ARRAY(vals,dims)) := ceval(cache,env, e, impl, msg,numIter+1);
766 318 (cache,es_1) := cevalList(cache,env, expl, impl, msg,numIter);
767 310 v := listHead(es_1);
768 310 v := ValuesUtil.nthnthArrayelt(es_1,Values.ARRAY(vals,dims),v);
769 310 then
770 (cache,v);
771
772 // indexing for tuple[index]
773 case (cache, env, DAE.TSUB(exp = e,ix = indx), impl, msg)
774 algorithm
775
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 (cache,Values.TUPLE(vals)) := ceval(cache,env, e, impl, msg,numIter+1);
776 32 v := listGet(vals, indx);
777 32 then
778 (cache,v);
779
780 case (cache, env, DAE.REDUCTION(reductionInfo=DAE.REDUCTIONINFO(iterType = iterType, path = path, foldName=foldName, resultName=resultName, foldExp = foldExp, defaultValue = ov, exprType = ty), expr = daeExp, iterators = iterators), impl, msg)
781 algorithm
782 137 env := FGraph.openScope(env, SCode.NOT_ENCAPSULATED(), FCore.forScopeName, NONE());
783 137 (cache, valMatrix, names, dims, tys) := cevalReductionIterators(cache, env, iterators, impl, msg,numIter+1);
784 // print("Before:\n");print(stringDelimitList(List.map1(List.mapList(valMatrix, ValuesDump.valString), stringDelimitList, ","), "\n") + "\n");
785 135 valMatrix := makeReductionAllCombinations(valMatrix,iterType);
786 // print("After:\n");print(stringDelimitList(List.map1(List.mapList(valMatrix, ValuesDump.valString), stringDelimitList, ","), "\n") + "\n");
787 // print("Start cevalReduction: " + AbsynUtil.pathString(path) + " " + ExpressionBasics.printExpStr(daeExp) + "\n");
788 135 (cache, ov) := cevalReduction(cache, env, path, ov, daeExp, ty, foldName, resultName, foldExp, names, listReverse(valMatrix), tys, impl, msg,numIter+1);
789 135 value := Util.getOptionOrDefault(ov, Values.META_FAIL());
790 135 value := backpatchArrayReduction(path, iterType, value, dims);
791 135 then (cache, value);
792
793 case (_, _, DAE.EMPTY(), _, _)
794 algorithm
795 2 s := ComponentReferenceBasics.printComponentRefStr(inExp.name);
796 2 v := Types.typeToValue(inExp.ty);
797 2 then
798 (inCache, Values.EMPTY(inExp.scope, s, v, inExp.tyStr));
799
800 case (_, _, _, _, _) guard Config.getGraphicsExpMode()
801 algorithm
802 ✗ ty := Expression.typeof(inExp);
803 ✗ v := Types.typeToValue(ty);
804 ✗ then (inCache, Values.EMPTY("#graphicsExp#", ExpressionBasics.printExpStr(inExp), v, TypesDump.unparseType(ty)));
805
806 // ceval can fail and that is ok, caught by other rules...
807 case (_, env, e, _, _) // Absyn.MSG())
808 algorithm
809
1/2
✓ Branch 1 taken 17576 times.
✗ Branch 2 not taken.
17576 true := Flags.isSet(Flags.CEVAL);
810 ✗ Debug.traceln("- Ceval.ceval failed: " + ExpressionBasics.printExpStr(e));
811 ✗ Debug.traceln(" Scope: " + FGraph.printGraphPathStr(env));
812 // Debug.traceln(" Env:" + FGraph.printGraphStr(env));
813 ✗ then
814 fail();
815 end matchcontinue;
816 end cevalWork2;
817
818 public function cevalIfConstant
819 "This function constant evaluates an expression if the expression is constant,
820 or if the expression is a call of parameter constness whose return type
821 contains unknown dimensions (in which case we need to determine the size of
822 those dimensions)."
823 input output FCore.Cache cache;
824 input FCore.Graph inEnv;
825 input output DAE.Exp exp;
826 input output DAE.Properties prop;
827 input Boolean impl;
828 input SourceInfo inInfo;
829 algorithm
830
2/2
✓ Branch 1 taken 1071137 times.
✓ Branch 2 taken 246620 times.
1317757 if Expression.isEvaluatedConst(exp) then
831 // Don't mess up the dimensions, etc by using the Values module
832 1071137 return;
833 end if;
834 (cache, exp, prop) := matchcontinue prop
835 local
836 Values.Value v;
837 DAE.Type tp;
838
839 case DAE.PROP(constFlag = DAE.C_PARAM(), type_ = tp)
840 // BoschRexroth specifics
841 guard not Flags.getConfigBool(Flags.CEVAL_EQUATION)
842 ✗ then (cache, exp, DAE.PROP(tp, DAE.C_VAR()));
843
844 case DAE.PROP(constFlag = DAE.C_CONST(), type_ = tp)
845 algorithm
846 84592 (cache, v) := ceval(cache, inEnv, exp, impl, Absyn.MSG(inInfo), 0);
847 81512 exp := ValuesUtil.valueExp(v,SOME(exp));
848 81512 exp := ValuesUtil.fixZeroSizeArray(exp, tp);
849 81512 then (cache, exp, prop);
850
851 case DAE.PROP_TUPLE()
852 algorithm
853
2/2
✓ Branch 1 taken 2126 times.
✓ Branch 2 taken 155 times.
2281 DAE.C_CONST() := Types.propAllConst(prop);
854 155 (cache, v) := ceval(cache, inEnv, exp, false, Absyn.MSG(inInfo), 0);
855 57 exp := ValuesUtil.valueExp(v, SOME(exp));
856 57 then (cache, exp, prop);
857
858 case DAE.PROP_TUPLE()
859 // BoschRexroth specifics
860 guard not Flags.getConfigBool(Flags.CEVAL_EQUATION)
861 algorithm
862 ✗ DAE.C_PARAM() := Types.propAllConst(prop);
863 ✗ print(" tuple non constant evaluation not implemented yet\n");
864 ✗ then fail();
865
866 case _
867 // Structural parameters and the like... we can ceval them if we want to
868 guard Expression.isConst(exp) and not Config.acceptMetaModelicaGrammar()
869 algorithm
870 2250 (_, v) := ceval(cache, inEnv, exp, impl, Absyn.MSG(inInfo), 0);
871 2060 exp := ValuesUtil.valueExp(v,SOME(exp));
872 2060 exp := ValuesUtil.fixZeroSizeArray(exp, Types.getPropType(prop));
873 2060 then (cache, exp, prop);
874
875 else
876 algorithm
877 // If we fail to evaluate, at least we should simplify the expression
878 162991 (exp,_) := ExpressionSimplify.simplify1(exp);
879 162991 then (cache, exp, prop);
880
881 end matchcontinue;
882 end cevalIfConstant;
883
884 protected function cevalWholedimRetCall
885 "Helper function to cevalIfConstant. Determines the size of any unknown
886 dimensions in a function calls return type."
887 input DAE.Exp inExp;
888 input FCore.Cache inCache;
889 input FCore.Graph inEnv;
890 input SourceInfo inInfo;
891 input Integer numIter;
892 output DAE.Exp outExp;
893 output DAE.Properties outProp;
894 algorithm
895 (outExp, outProp) := match inExp
896 local
897 DAE.Exp e;
898 Absyn.Path p;
899 list<DAE.Exp> el;
900 DAE.Dimensions dims;
901 Values.Value v;
902 DAE.Type cevalType, ty;
903 DAE.CallAttributes attr;
904
905 case e as DAE.CALL(path = p, expLst = el, attr = attr as DAE.CALL_ATTR(ty = DAE.T_ARRAY(dims = dims)))
906 algorithm
907 ✗ true := Expression.arrayContainWholeDimension(dims);
908 ✗ (_, v) := ceval(inCache, inEnv, e, true, Absyn.MSG(inInfo), numIter+1);
909 ✗ ty := Types.typeOfValue(v);
910 ✗ cevalType := Types.simplifyType(ty);
911 ✗ attr.ty := cevalType;
912 ✗ then
913 (DAE.CALL(p, el, attr), DAE.PROP(ty, DAE.C_PARAM()));
914 end match;
915 end cevalWholedimRetCall;
916
917 public function cevalRangeIfConstant
918 "Constant evaluates the limits of a range if they are constant."
919 input FCore.Cache inCache;
920 input FCore.Graph inEnv;
921 input DAE.Exp inExp;
922 input DAE.Properties inProp;
923 input Boolean impl;
924 input SourceInfo inInfo;
925 output FCore.Cache outCache;
926 output DAE.Exp outExp;
927 algorithm
928 (outCache, outExp) := matchcontinue inExp
929 local
930 DAE.Exp e1, e2;
931 Option<DAE.Exp> e3;
932 DAE.Type ty;
933 FCore.Cache cache;
934
935 case DAE.RANGE(ty = ty, start = e1, stop = e2, step = e3)
936 algorithm
937 232 (cache, e1, _) := cevalIfConstant(inCache, inEnv, e1, inProp, impl, inInfo);
938 232 (_, e2, _) := cevalIfConstant(cache, inEnv, e2, inProp, impl, inInfo);
939 232 then
940 (inCache, DAE.RANGE(ty, e1, e3, e2));
941 else (inCache, inExp);
942 end matchcontinue;
943 end cevalRangeIfConstant;
944
945 protected function cevalBuiltin
946 "Helper for ceval. Parts for builtin calls are moved here, for readability.
947 See ceval for documentation.
948 NOTE: It\'s ok if cevalBuiltin fails. Just means the call was not a builtin function"
949 input FCore.Cache inCache;
950 input FCore.Graph inEnv;
951 input DAE.Exp inExp;
952 input Boolean inBoolean "impl";
953 input Absyn.Msg inMsg;
954 input Integer numIter;
955 output FCore.Cache outCache;
956 output Values.Value outValue;
957 partial function HandlerFunc
958 input FCore.Cache inCache;
959 input FCore.Graph inEnvFrameLst;
960 input list<DAE.Exp> inExpExpLst;
961 input Boolean inBoolean;
962 input Absyn.Msg inMsg;
963 input Integer numIter;
964 output FCore.Cache outCache;
965 output Values.Value outValue;
966 end HandlerFunc;
967 algorithm
968 (outCache,outValue):=
969 matchcontinue (inCache, inEnv, inExp, inBoolean, inMsg)
970 local
971 Values.Value v,newval;
972 FCore.Graph env;
973 DAE.Exp exp,dim,e;
974 Boolean impl;
975 Absyn.Msg msg;
976 HandlerFunc handler;
977 String id;
978 list<DAE.Exp> args,expl;
979 list<Values.Value> vallst;
980 Absyn.Path path;
981 FCore.Cache cache;
982
983 case (cache, env, DAE.SIZE(exp = exp,sz = SOME(dim)), impl, msg)
984 algorithm
985 2296 (cache,v) := cevalBuiltinSize(cache,env, exp, dim, impl, msg, numIter+1) "Handle size separately" ;
986 then
987 (cache,v);
988 case (cache, env, DAE.SIZE(exp = exp,sz = NONE()), impl, msg)
989 algorithm
990 ✗ (cache,v) := cevalBuiltinSizeMatrix(cache,env, exp, impl, msg,numIter+1);
991 then
992 (cache,v);
993 case (cache, env, DAE.CALL(path = path,expLst = args,attr = DAE.CALL_ATTR(builtin = true)), impl, msg)
994 algorithm
995 47758 id := AbsynUtil.pathString(path);
996 47758 handler := cevalBuiltinHandler(id);
997
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 34511 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 5 taken 3365 times.
✓ Branch 6 taken 31146 times.
37876 (cache,v) := handler(cache, env, args, impl, msg,numIter+1);
998 then (cache,v);
999 case (cache, env, (e as DAE.CALL(expLst = expl,attr = DAE.CALL_ATTR(builtin = true))), impl, msg)
1000 algorithm
1001 13410 (cache,vallst) := cevalList(cache, env, expl, impl, msg, numIter);
1002 13136 (cache,newval) := BackendCevalInterface.cevalCallFunction(cache, env, e, vallst, impl, msg,numIter+1);
1003 then (cache,newval);
1004 end matchcontinue;
1005 end cevalBuiltin;
1006
1007 protected function cevalBuiltinHandler
1008 "This function dispatches builtin functions and operators to a dedicated
1009 function that evaluates that particular function.
1010 It takes an identifier as input and returns a function that evaluates that
1011 function or operator.
1012 NOTE: size handled specially. see cevalBuiltin:
1013 removed: case (\"size\") => cevalBuiltinSize"
1014 input Absyn.Ident inIdent;
1015 output HandlerFunc handler;
1016 partial function HandlerFunc
1017 input FCore.Cache inCache;
1018 input FCore.Graph inEnv;
1019 input list<DAE.Exp> inExpExpLst;
1020 input Boolean inBoolean;
1021 input Absyn.Msg inMsg;
1022 input Integer numIter;
1023 output FCore.Cache outCache;
1024 output Values.Value outValue;
1025 end HandlerFunc;
1026 algorithm
1027 handler := match inIdent
1028 local
1029 String id;
1030 case "floor" then cevalBuiltinFloor;
1031 case "ceil" then cevalBuiltinCeil;
1032 case "abs" then cevalBuiltinAbs;
1033 case "sqrt" then cevalBuiltinSqrt;
1034 case "nthRoot" then cevalBuiltinNthRoot;
1035 case "div" then cevalBuiltinDiv;
1036 case "sin" then cevalBuiltinSin;
1037 case "cos" then cevalBuiltinCos;
1038 case "tan" then cevalBuiltinTan;
1039 case "sinh" then cevalBuiltinSinh;
1040 case "cosh" then cevalBuiltinCosh;
1041 case "tanh" then cevalBuiltinTanh;
1042 case "asin" then cevalBuiltinAsin;
1043 case "acos" then cevalBuiltinAcos;
1044 case "atan" then cevalBuiltinAtan;
1045 case "atan2" then cevalBuiltinAtan2;
1046 case "log" then cevalBuiltinLog;
1047 case "log10" then cevalBuiltinLog10;
1048 case "integer" then cevalBuiltinInteger;
1049 case "boolean" then cevalBuiltinBoolean;
1050 case "mod" then cevalBuiltinMod;
1051 case "max" then cevalBuiltinMax;
1052 case "min" then cevalBuiltinMin;
1053 case "rem" then cevalBuiltinRem;
1054 case "sum" then cevalBuiltinSum;
1055 case "diagonal" then cevalBuiltinDiagonal;
1056 case "sign" then cevalBuiltinSign;
1057 case "exp" then cevalBuiltinExp;
1058 case "noEvent" then cevalBuiltinNoevent;
1059 case "cat" then cevalBuiltinCat;
1060 case "identity" then cevalBuiltinIdentity;
1061 case "promote" then cevalBuiltinPromote;
1062 case "String" then cevalBuiltinString;
1063 case "Integer" then cevalBuiltinIntegerEnumeration;
1064 case "rooted" then cevalBuiltinRooted; //
1065 case "cross" then cevalBuiltinCross;
1066 case "fill" then cevalBuiltinFill;
1067 case "Modelica.Utilities.Strings.substring" then cevalBuiltinSubstring;
1068 case "print" then cevalBuiltinPrint;
1069 case "fail" then cevalBuiltinFail;
1070 // BTH
1071 /*
1072 case "Clock"
1073 algorithm
1074 true = Config.synchronousFeaturesAllowed();
1075 then cevalBuiltinClock; */
1076 // MetaModelica type conversions
1077 case "intString" guard Config.acceptMetaModelicaGrammar() then cevalIntString;
1078 case "realString" guard Config.acceptMetaModelicaGrammar() then cevalRealString;
1079 case "stringCharInt" guard Config.acceptMetaModelicaGrammar() then cevalStringCharInt;
1080 case "intStringChar" guard Config.acceptMetaModelicaGrammar() then cevalIntStringChar;
1081 case "stringLength" guard Config.acceptMetaModelicaGrammar() then cevalStringLength;
1082 case "stringInt" guard Config.acceptMetaModelicaGrammar() then cevalStringInt;
1083 case "stringListStringChar" guard Config.acceptMetaModelicaGrammar() then cevalStringListStringChar;
1084 case "listStringCharString" guard Config.acceptMetaModelicaGrammar() then cevalListStringCharString;
1085 case "stringAppendList" guard Config.acceptMetaModelicaGrammar() then cevalStringAppendList;
1086 case "stringDelimitList" guard Config.acceptMetaModelicaGrammar() then cevalStringDelimitList;
1087 case "listLength" guard Config.acceptMetaModelicaGrammar() then cevalListLength;
1088 case "listAppend" guard Config.acceptMetaModelicaGrammar() then cevalListAppend;
1089 case "listReverse" guard Config.acceptMetaModelicaGrammar() then cevalListReverse;
1090 case "listHead" guard Config.acceptMetaModelicaGrammar() then cevalListFirst;
1091 case "listRest" guard Config.acceptMetaModelicaGrammar() then cevalListRest;
1092 case "listMember" guard Config.acceptMetaModelicaGrammar() then cevalListMember;
1093 case "anyString" guard Config.acceptMetaModelicaGrammar() then cevalAnyString;
1094 case "listArrayLiteral" guard Config.acceptMetaModelicaGrammar() then cevalListArrayLiteral;
1095 case "intBitAnd" guard Config.acceptMetaModelicaGrammar() then cevalIntBitAnd;
1096 case "intBitOr" guard Config.acceptMetaModelicaGrammar() then cevalIntBitOr;
1097 case "intBitXor" guard Config.acceptMetaModelicaGrammar() then cevalIntBitXor;
1098 case "intBitLShift" guard Config.acceptMetaModelicaGrammar() then cevalIntBitLShift;
1099 case "intBitRShift" guard Config.acceptMetaModelicaGrammar() then cevalIntBitRShift;
1100 case "numBits" then cevalNumBits;
1101 case "integerMax" then cevalIntegerMax;
1102
1103 //case "semiLinear" then cevalBuiltinSemiLinear;
1104 //case "delay" then cevalBuiltinDelay;
1105 case id
1106 algorithm
1107
1/2
✓ Branch 1 taken 13247 times.
✗ Branch 2 not taken.
13247 true := Flags.isSet(Flags.CEVAL);
1108 ✗ Debug.traceln("No cevalBuiltinHandler found for " + id);
1109 ✗ then
1110 fail();
1111 end match;
1112 end cevalBuiltinHandler;
1113
1114
1115
1116
1117 public function cevalKnownExternalFuncs "Evaluates external functions that are known, e.g. all math functions."
1118 input FCore.Cache inCache;
1119 input FCore.Graph env;
1120 input Absyn.Path funcpath;
1121 input list<Values.Value> vals;
1122 input Absyn.Msg msg;
1123 output FCore.Cache outCache;
1124 output Values.Value res;
1125 protected
1126 SCode.Element cdef;
1127 FCore.Graph env_1;
1128 String fid,id;
1129 Option<String> oid;
1130 Option<SCode.ExternalDecl> extdecl;
1131 SCode.FunctionRestriction funcRest;
1132 algorithm
1133 77790 (outCache,cdef,env_1) := Lookup.lookupClass(inCache,env, funcpath);
1134
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 42956 times.
✓ Branch 3 taken 708 times.
✓ Branch 4 taken 42248 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 42234 times.
42956 SCode.CLASS(name=fid,restriction = SCode.R_FUNCTION(funcRest), classDef=SCode.PARTS(externalDecl=extdecl)) := cdef;
1135
2/2
✓ Branch 0 taken 37739 times.
✓ Branch 1 taken 4495 times.
42234 SCode.FR_EXTERNAL_FUNCTION(_) := funcRest;
1136
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4495 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4495 times.
4495 SOME(SCode.EXTERNALDECL(oid,_,_,_,_)) := extdecl;
1137 // oid=NONE() is more safe, but most of the functions are declared is a certain way =/
1138 4495 id := Util.getOptionOrDefault(oid,fid);
1139 4495 isKnownExternalFunc(id);
1140 2268 res := cevalKnownExternalFuncs2(id, vals, msg);
1141 end cevalKnownExternalFuncs;
1142
1143 public function isKnownExternalFunc "\"known\", i.e. no compilation required."
1144 input String id;
1145 algorithm
1146 ():= match id
1147 case "acos" then ();
1148 case "asin" then ();
1149 case "atan" then ();
1150 case "atan2" then ();
1151 case "cos" then ();
1152 case "cosh" then ();
1153 case "exp" then ();
1154 case "log" then ();
1155 case "log10" then ();
1156 case "sin" then ();
1157 case "sinh" then ();
1158 case "tan" then ();
1159 case "tanh" then ();
1160 case "print" then ();
1161 case "ModelicaStreams_closeFile" then ();
1162 case "ModelicaStrings_substring" then ();
1163 case "ModelicaStrings_length" then ();
1164 case "ModelicaInternal_print" then ();
1165 case "ModelicaInternal_countLines" then ();
1166 case "ModelicaInternal_readLine" then ();
1167 case "ModelicaInternal_stat" then ();
1168 case "ModelicaInternal_fullPathName" then ();
1169 case "ModelicaStrings_compare" then ();
1170 case "ModelicaStrings_scanReal" then ();
1171 case "ModelicaStrings_skipWhiteSpace" then ();
1172 case "ModelicaError" then ();
1173 case "OpenModelica_regex" then ();
1174 end match;
1175 end isKnownExternalFunc;
1176
1177 protected function cevalKnownExternalFuncs2 "Helper function to cevalKnownExternalFuncs, does the evaluation."
1178 input String id;
1179 input list<Values.Value> inValuesValueLst;
1180 input Absyn.Msg inMsg;
1181 output Values.Value outValue;
1182 algorithm
1183 outValue := match (id, inValuesValueLst)
1184 local
1185 Real rv_1,rv,rv1,rv2;
1186 String str,re;
1187 Integer start, stop, i, n;
1188 Boolean extended, insensitive;
1189 list<String> strs;
1190 list<Values.Value> vals;
1191 Values.Value v;
1192
1193 case ("acos", {Values.REAL(real = rv)})
1194 algorithm
1195 ✗ true := rv >= -1.0 and rv <= 1.0;
1196 ✗ rv_1 := acos(rv);
1197 ✗ then
1198 Values.REAL(rv_1);
1199 case ("asin", {Values.REAL(real = rv)})
1200 algorithm
1201 ✗ true := rv >= -1.0 and rv <= 1.0;
1202 ✗ rv_1 := asin(rv);
1203 ✗ then
1204 Values.REAL(rv_1);
1205 case ("atan", {Values.REAL(real = rv)})
1206 algorithm
1207 ✗ rv_1 := atan(rv);
1208 ✗ then
1209 Values.REAL(rv_1);
1210 case ("atan2", {Values.REAL(real = rv1),Values.REAL(real = rv2)})
1211 algorithm
1212 ✗ rv_1 := atan2(rv1, rv2);
1213 ✗ then
1214 Values.REAL(rv_1);
1215 case ("cos", {Values.REAL(real = rv)})
1216 algorithm
1217 ✗ rv_1 := cos(rv);
1218 ✗ then
1219 Values.REAL(rv_1);
1220 case ("cosh", {Values.REAL(real = rv)})
1221 algorithm
1222 ✗ rv_1 := cosh(rv);
1223 ✗ then
1224 Values.REAL(rv_1);
1225 case ("exp", {Values.REAL(real = rv)})
1226 algorithm
1227 ✗ rv_1 := exp(rv);
1228 ✗ then
1229 Values.REAL(rv_1);
1230 case ("log", {Values.REAL(real = rv)})
1231 algorithm
1232 ✗ true := rv > 0;
1233 ✗ rv_1 := log(rv);
1234 ✗ then
1235 Values.REAL(rv_1);
1236 case ("log10", {Values.REAL(real = rv)})
1237 algorithm
1238 ✗ true := rv > 0;
1239 ✗ rv_1 := log10(rv);
1240 ✗ then
1241 Values.REAL(rv_1);
1242 case ("sin", {Values.REAL(real = rv)})
1243 algorithm
1244 ✗ rv_1 := sin(rv);
1245 ✗ then
1246 Values.REAL(rv_1);
1247 case ("sinh", {Values.REAL(real = rv)})
1248 algorithm
1249 ✗ rv_1 := sinh(rv);
1250 ✗ then
1251 Values.REAL(rv_1);
1252 case ("tan", {Values.REAL(real = rv)})
1253 algorithm
1254 ✗ rv_1 := tan(rv);
1255 ✗ then
1256 Values.REAL(rv_1);
1257 case ("tanh", {Values.REAL(real = rv)})
1258 algorithm
1259 ✗ rv_1 := tanh(rv);
1260 ✗ then
1261 Values.REAL(rv_1);
1262
1263 case ("ModelicaStrings_substring", {
1264 Values.STRING(string = str),
1265 Values.INTEGER(integer = start),
1266 Values.INTEGER(integer = stop)
1267 })
1268 algorithm
1269 ✗ str := substring(str, start, stop);
1270 ✗ then
1271 Values.STRING(str);
1272 case ("ModelicaStrings_length", {Values.STRING(str)})
1273 algorithm
1274 ✗ i := stringLength(str);
1275 ✗ then Values.INTEGER(i);
1276 case ("print", {Values.STRING(str)})
1277 algorithm
1278 2224 print(str);
1279 then Values.NORETCALL();
1280
1281 case ("OpenModelica_regex", {Values.STRING(str),Values.STRING(re),Values.INTEGER(i),Values.BOOL(extended),Values.BOOL(insensitive)})
1282 algorithm
1283 41 (n,strs) := System.regex(str,re,i,extended,insensitive);
1284 41 vals := List.map(strs,ValuesMake.makeString);
1285 41 v := Values.ARRAY(vals,{i});
1286 82 then Values.TUPLE({Values.INTEGER(n),v});
1287
1288 end match;
1289 end cevalKnownExternalFuncs2;
1290
1291 protected constant Absyn.Path EnumCompareLess = Absyn.QUALIFIED("Modelica",Absyn.QUALIFIED("Utilities",Absyn.QUALIFIED("Types",Absyn.QUALIFIED("Compare",Absyn.IDENT("Less")))));
1292 protected constant Absyn.Path EnumCompareEqual = Absyn.QUALIFIED("Modelica",Absyn.QUALIFIED("Utilities",Absyn.QUALIFIED("Types",Absyn.QUALIFIED("Compare",Absyn.IDENT("Equal")))));
1293 protected constant Absyn.Path EnumCompareGreater = Absyn.QUALIFIED("Modelica",Absyn.QUALIFIED("Utilities",Absyn.QUALIFIED("Types",Absyn.QUALIFIED("Compare",Absyn.IDENT("Greater")))));
1294
1295 protected function cevalMatrixElt "Evaluates the expression of a matrix constructor, e.g. {1,2;3,4}"
1296 input FCore.Cache inCache;
1297 input FCore.Graph inEnv;
1298 input list<list<DAE.Exp>> inMatrix "matrix constr. elts";
1299 input Boolean inBoolean "impl";
1300 input Absyn.Msg inMsg;
1301 input Integer numIter;
1302 output FCore.Cache outCache = inCache;
1303 output list<Values.Value> outValues = {};
1304 protected
1305 Values.Value v;
1306 list<Values.Value> vl;
1307 algorithm
1308
2/2
✓ Branch 0 taken 40260 times.
✓ Branch 1 taken 10359 times.
50619 for expl in inMatrix loop
1309 40260 (outCache,vl) := cevalList(outCache,inEnv,expl,inBoolean,inMsg,numIter);
1310 40233 v := ValuesMake.makeArray(vl);
1311 outValues := v::outValues;
1312 end for;
1313 10359 outValues := listReverseInPlace(outValues);
1314 end cevalMatrixElt;
1315
1316 protected function cevalBuiltinSize "Evaluates the size operator."
1317 input FCore.Cache inCache;
1318 input FCore.Graph inEnv1;
1319 input DAE.Exp inExp2;
1320 input DAE.Exp inDimExp;
1321 input Boolean inBoolean4;
1322 input Absyn.Msg inMsg6;
1323 input Integer numIter;
1324 output FCore.Cache outCache;
1325 output Values.Value outValue;
1326 algorithm
1327 (outCache,outValue):=
1328 matchcontinue (inCache, inEnv1, inExp2, inDimExp, inBoolean4, inMsg6)
1329 local
1330 DAE.Type tp;
1331 DAE.Binding binding;
1332 list<Integer> sizelst,adims;
1333 Integer dim,dim_1,dimv,len,i;
1334 FCore.Graph env;
1335 DAE.ComponentRef cr;
1336 Boolean impl,bl;
1337 Absyn.Msg msg;
1338 DAE.Dimensions dims;
1339 Values.Value v2,val;
1340 DAE.Exp exp,e,dimExp;
1341 String cr_str,dim_str,size_str,expstr;
1342 list<DAE.Exp> es;
1343 FCore.Cache cache;
1344 list<list<DAE.Exp>> mat;
1345 SourceInfo info;
1346 DAE.Dimension ddim;
1347
1348 case (cache, _, DAE.MATRIX(matrix=mat), DAE.ICONST(1), _, _)
1349 algorithm
1350 ✗ i := listLength(mat);
1351 ✗ then
1352 (cache,Values.INTEGER(i));
1353
1354 case (cache, _, DAE.MATRIX(matrix=mat), DAE.ICONST(2), _, _)
1355 algorithm
1356 ✗ i := listLength(listHead(mat));
1357 ✗ then
1358 (cache,Values.INTEGER(i));
1359
1360 case (cache, env, DAE.MATRIX(matrix=mat), DAE.ICONST(dim), impl, msg)
1361 algorithm
1362 bl := (dim>2);
1363 ✗ true := bl;
1364 ✗ dim_1 := dim-2;
1365 ✗ e := listHead(listHead(mat));
1366 ✗ (cache,Values.INTEGER(i)) := cevalBuiltinSize(cache,env,e,DAE.ICONST(dim_1),impl,msg,numIter+1);
1367 ✗ then
1368 (cache,Values.INTEGER(i));
1369
1370 case (cache, env, DAE.CREF(componentRef = cr), dimExp, impl, msg)
1371 algorithm
1372 2296 (cache,_,tp,_,_,_,_,_) := Lookup.lookupVar(cache,env, cr) "If dimensions known, always ceval" ;
1373
2/2
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 2182 times.
2297 true := Types.dimensionsKnown(tp);
1374
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2180 times.
2182 sizelst as (_ :: _) := Types.getDimensionSizes(tp);
1375
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2180 times.
2180 (cache,Values.INTEGER(dim)) := ceval(cache, env, dimExp, impl, msg,numIter+1);
1376 2180 i := listGet(sizelst, dim);
1377 2180 then
1378 (cache,Values.INTEGER(i));
1379
1380 case (cache, env, DAE.CREF(componentRef = cr), dimExp, (impl as false), msg)
1381 algorithm
1382 45 (cache,dims) := InstUtil.elabComponentArraydimFromEnv(cache,env,cr,Absyn.dummyInfo)
1383 "If component not instantiated yet, recursive definition.
1384 For example,
1385 Real x[:](min=fill(1.0,size(x,1))) = {1.0}
1386 When size(x,1) should be determined, x must be instantiated, but
1387 that is not done yet. Solution: Examine Element to find modifier
1388 which will determine dimension size.";
1389
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
44 (cache,Values.INTEGER(dimv)) := ceval(cache, env, dimExp, impl, msg,numIter+1);
1390 44 ddim := listGet(dims, dimv);
1391 7 (cache, v2) := cevalDimension(cache, env, ddim, impl, msg,numIter+1);
1392 then
1393 (cache,v2);
1394
1395 case (cache, env, DAE.CREF(componentRef = cr), dimExp, false, Absyn.MSG(info = info))
1396 algorithm
1397 ✗ (_,_,tp,binding,_,_,_,_,_) := Lookup.lookupVar(cache, env, cr) "If dimensions not known and impl=false, error message";
1398 ✗ if not Types.dimensionsKnown(tp)
1399 then
1400 ✗ cr_str := ComponentReferenceBasics.printComponentRefStr(cr);
1401 ✗ dim_str := ExpressionBasics.printExpStr(dimExp);
1402 ✗ size_str := stringAppendList({"size(",cr_str,", ",dim_str,")"});
1403 ✗ Error.addSourceMessage(Error.DIMENSION_NOT_KNOWN, {size_str}, info);
1404 else
1405 _ := match binding
1406 case DAE.UNBOUND()
1407 algorithm
1408 ✗ expstr := ExpressionBasics.printExpStr(inExp2);
1409 ✗ Error.addSourceMessage(Error.UNBOUND_VALUE, {expstr}, info);
1410 ✗ then
1411 fail();
1412 end match;
1413 end if;
1414 ✗ then
1415 fail();
1416
1417 // For crefs with value binding e.g. size(x,1) when Real x[:]=fill(0,1);
1418 case (cache, env, (DAE.CREF(componentRef = cr)), dimExp, impl, msg)
1419 algorithm
1420 110 (cache,_,_,binding,_,_,_,_,_) := Lookup.lookupVar(cache, env, cr) ;
1421
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 109 times.
109 (cache,Values.INTEGER(dimv)) := ceval(cache,env,dimExp,impl,msg,numIter+1);
1422 109 (cache,val) := cevalCrefBinding(cache,env, cr, binding, impl,msg,numIter+1);
1423 35 v2 := cevalBuiltinSize2(val, dimv);
1424 35 then
1425 (cache,v2);
1426
1427 case (cache, env, DAE.ARRAY(array = (exp :: es)), dimExp, impl, msg)
1428 algorithm
1429 // Special case for array expressions with nonconstant values.
1430 // For now: only arrays of scalar elements.
1431 // TODO generalize to arbitrary dimensions
1432 ✗ (cache,Values.INTEGER(1)) := ceval(cache, env, dimExp, impl, msg, numIter+1);
1433 ✗ len := listLength(exp :: es);
1434 ✗ then
1435 (cache,Values.INTEGER(len));
1436
1437 // For expressions with value binding that can not determine type
1438 // e.g. size(x,2) when Real x[:,:]=fill(0.0,0,2); empty array with second dimension == 2, no way of
1439 // knowing that from the value. Must investigate the expression itself.
1440 case (cache, env, exp, dimExp, impl, msg)
1441 algorithm
1442 75 (cache,val) := ceval(cache,env,exp,impl,msg,numIter+1);
1443 ✗ (cache,Values.INTEGER(dimv)) := ceval(cache,env,dimExp,impl,msg,numIter+1);
1444 v2 := match val
1445 ✗ case Values.ARRAY({},adims) then Values.INTEGER(listGet(adims,dimv));
1446 ✗ else cevalBuiltinSize2(val, dimv);
1447 end match;
1448 ✗ then
1449 (cache,v2);
1450
1451 case (_, _, exp, _, _, Absyn.MSG())
1452 algorithm
1453
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 true := Flags.isSet(Flags.FAILTRACE);
1454 ✗ Print.printErrorBuf("#-- Ceval.cevalBuiltinSize failed: ");
1455 ✗ expstr := ExpressionBasics.printExpStr(exp);
1456 ✗ Print.printErrorBuf(expstr);
1457 ✗ Print.printErrorBuf("\n");
1458 ✗ then
1459 fail();
1460
1461 end matchcontinue;
1462 end cevalBuiltinSize;
1463
1464 protected function cevalBuiltinSize2 "Helper function to cevalBuiltinSize"
1465 input Values.Value inValue;
1466 input Integer inInteger;
1467 output Values.Value outValue;
1468 algorithm
1469 outValue := matchcontinue (inValue,inInteger)
1470 local
1471 Integer dim,ind_1,ind;
1472 list<Values.Value> lst;
1473 Values.Value l;
1474 Values.Value dimVal;
1475
1476 case (Values.ARRAY(valueLst = lst),1)
1477 algorithm
1478 35 dim := listLength(lst);
1479 35 then
1480 Values.INTEGER(dim);
1481
1482 case (Values.ARRAY(valueLst = (l :: _)),ind)
1483 algorithm
1484 ✗ ind_1 := ind - 1;
1485 ✗ dimVal := cevalBuiltinSize2(l, ind_1);
1486 then
1487 dimVal;
1488
1489 else
1490 algorithm
1491 ✗ true := Flags.isSet(Flags.FAILTRACE);
1492 ✗ Debug.trace("- Ceval.cevalBuiltinSize2 failed\n");
1493 ✗ then
1494 fail();
1495 end matchcontinue;
1496 end cevalBuiltinSize2;
1497
1498 protected function cevalBuiltinSize3 "author: PA
1499 Helper function to cevalBuiltinSize.
1500 Used when recursive definition (attribute modifiers using size) is used."
1501 input DAE.Dimensions inDims;
1502 input Integer inIndex;
1503 output Values.Value outValue;
1504 protected
1505 Integer v;
1506 algorithm
1507 ✗ DAE.DIM_INTEGER(v) := listGet(inDims, inIndex);
1508 ✗ outValue := Values.INTEGER(v);
1509 end cevalBuiltinSize3;
1510
1511 protected function cevalBuiltinAbs "author: LP
1512 Evaluates the abs operator."
1513 input FCore.Cache inCache;
1514 input FCore.Graph inEnv;
1515 input list<DAE.Exp> inExpExpLst;
1516 input Boolean inBoolean;
1517 input Absyn.Msg inMsg;
1518 input Integer numIter;
1519 output FCore.Cache outCache;
1520 output Values.Value outValue;
1521 algorithm
1522 (outCache,outValue):=
1523 matchcontinue (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1524 local
1525 Real rv,rv_1;
1526 FCore.Graph env;
1527 DAE.Exp exp;
1528 Boolean impl;
1529 Absyn.Msg msg;
1530 Integer iv;
1531 FCore.Cache cache;
1532 case (cache, env, {exp}, impl, msg)
1533 algorithm
1534
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 194 times.
200 (cache,Values.REAL(rv)) := ceval(cache,env,exp,impl,msg,numIter+1);
1535 194 rv_1 := realAbs(rv);
1536 194 then
1537 (cache,Values.REAL(rv_1));
1538 case (cache, env, {exp}, impl, msg)
1539 algorithm
1540
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
6 (cache,Values.INTEGER(iv)) := ceval(cache,env,exp,impl,msg,numIter+1);
1541 2 iv := intAbs(iv);
1542 2 then
1543 (cache,Values.INTEGER(iv));
1544 end matchcontinue;
1545 end cevalBuiltinAbs;
1546
1547 protected function cevalBuiltinSign "author: PA
1548 Evaluates the sign operator."
1549 input FCore.Cache inCache;
1550 input FCore.Graph inEnv;
1551 input list<DAE.Exp> inExpExpLst;
1552 input Boolean inBoolean;
1553 input Absyn.Msg inMsg;
1554 input Integer numIter;
1555 output FCore.Cache outCache;
1556 output Values.Value outValue;
1557 algorithm
1558 (outCache,outValue):=
1559 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1560 local
1561 Real rv;
1562 Boolean b1,b2,b3,impl;
1563 FCore.Graph env;
1564 DAE.Exp exp;
1565 Absyn.Msg msg;
1566 Integer iv,iv_1;
1567 FCore.Cache cache;
1568 Values.Value v;
1569
1570 case (cache, env, {exp}, impl, msg)
1571 algorithm
1572 2 (cache,v) := ceval(cache,env,exp,impl,msg,numIter+1);
1573 (b1, b2, b3) := match v
1574 2 case Values.REAL(rv) then ((rv > 0.0), (rv < 0.0), (rv == 0.0));
1575 ✗ case Values.INTEGER(iv) then ((iv > 0), (iv < 0), (iv == 0));
1576 end match;
1577
7/10
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
8 {(_,iv_1)} := List.select({(b1,1),(b2,-1),(b3,0)}, Util.tuple21);
1578 2 then
1579 (cache,Values.INTEGER(iv_1));
1580
1581 end match;
1582 end cevalBuiltinSign;
1583
1584 protected function cevalBuiltinExp "author: PA
1585 Evaluates the exp function"
1586 input FCore.Cache inCache;
1587 input FCore.Graph inEnv;
1588 input list<DAE.Exp> inExpExpLst;
1589 input Boolean inBoolean;
1590 input Absyn.Msg inMsg;
1591 input Integer numIter;
1592 output FCore.Cache outCache;
1593 output Values.Value outValue;
1594 algorithm
1595 (outCache,outValue):=
1596 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1597 local
1598 Real rv,rv_1;
1599 FCore.Graph env;
1600 DAE.Exp exp;
1601 Boolean impl;
1602 Absyn.Msg msg;
1603 FCore.Cache cache;
1604 case (cache, env, {exp}, impl, msg)
1605 algorithm
1606
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
236 (cache,Values.REAL(rv)) := ceval(cache,env,exp,impl,msg,numIter+1);
1607 233 rv_1 := .exp(rv);
1608 233 then
1609 (cache,Values.REAL(rv_1));
1610 end match;
1611 end cevalBuiltinExp;
1612
1613 protected function cevalBuiltinNoevent "author: PA
1614 Evaluates the noEvent operator. During constant evaluation events are not
1615 considered, so evaluation will simply remove the operator and evaluate the
1616 operand."
1617 input FCore.Cache inCache;
1618 input FCore.Graph inEnv;
1619 input list<DAE.Exp> inExpExpLst;
1620 input Boolean inBoolean;
1621 input Absyn.Msg inMsg;
1622 input Integer numIter;
1623 output FCore.Cache outCache;
1624 output Values.Value outValue;
1625 algorithm
1626 (outCache,outValue):=
1627 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1628 local
1629 Values.Value v;
1630 FCore.Graph env;
1631 DAE.Exp exp;
1632 Boolean impl;
1633 Absyn.Msg msg;
1634 FCore.Cache cache;
1635 case (cache, env, {exp}, impl, msg)
1636 algorithm
1637 ✗ (cache,v) := ceval(cache,env,exp,impl,msg,numIter+1);
1638 then
1639 (cache,v);
1640 end match;
1641 end cevalBuiltinNoevent;
1642
1643 protected function cevalBuiltinCat "author: PA
1644 Evaluates the cat operator, for matrix concatenation."
1645 input FCore.Cache inCache;
1646 input FCore.Graph inEnv;
1647 input list<DAE.Exp> inExpExpLst;
1648 input Boolean inBoolean;
1649 input Absyn.Msg inMsg;
1650 input Integer numIter;
1651 output FCore.Cache outCache;
1652 output Values.Value outValue;
1653 algorithm
1654 (outCache,outValue):=
1655 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1656 local
1657 Integer dim_int;
1658 list<Values.Value> mat_lst;
1659 Values.Value v;
1660 FCore.Graph env;
1661 DAE.Exp dim;
1662 list<DAE.Exp> matrices;
1663 Boolean impl;
1664 Absyn.Msg msg;
1665 FCore.Cache cache;
1666
1667 case (cache, env, (dim :: matrices), impl, msg)
1668 algorithm
1669
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
21 (cache,Values.INTEGER(dim_int)) := ceval(cache,env,dim,impl,msg,numIter+1);
1670 21 (cache,mat_lst) := cevalList(cache,env, matrices, impl, msg,numIter);
1671 20 v := cevalCat(mat_lst, dim_int);
1672 then
1673 (cache,v);
1674
1675 end match;
1676 end cevalBuiltinCat;
1677
1678 protected function cevalBuiltinIdentity "author: PA
1679 Evaluates the identity operator."
1680 input FCore.Cache inCache;
1681 input FCore.Graph inEnv;
1682 input list<DAE.Exp> inExpExpLst;
1683 input Boolean inBoolean;
1684 input Absyn.Msg inMsg;
1685 input Integer numIter;
1686 output FCore.Cache outCache;
1687 output Values.Value outValue;
1688 algorithm
1689 (outCache,outValue):=
1690 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1691 local
1692 Integer dimension;
1693 FCore.Graph env;
1694 DAE.Exp dim;
1695 Boolean impl;
1696 Absyn.Msg msg;
1697 FCore.Cache cache;
1698 Values.Value res;
1699
1700 case (cache, env, {dim}, impl, msg)
1701 algorithm
1702
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache,Values.INTEGER(dimension)) := ceval(cache,env,dim,impl,msg,numIter+1);
1703
6/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
14 res := Values.ARRAY(list(Values.ARRAY(list(if i==j then Values.INTEGER(1) else Values.INTEGER(0) for i in 1:dimension),{dimension}) for j in 1:dimension), {dimension,dimension});
1704 then
1705 (cache,res);
1706
1707 end match;
1708 end cevalBuiltinIdentity;
1709
1710 protected function cevalBuiltinPromote "author: PA
1711 Evaluates the internal promote operator, for promotion of arrays"
1712 input FCore.Cache inCache;
1713 input FCore.Graph inEnv;
1714 input list<DAE.Exp> inExpExpLst;
1715 input Boolean inBoolean;
1716 input Absyn.Msg inMsg;
1717 input Integer numIter;
1718 output FCore.Cache outCache;
1719 output Values.Value outValue;
1720 algorithm
1721 (outCache,outValue):=
1722 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1723 local
1724 Values.Value arr_val,res;
1725 Integer dim_val;
1726 FCore.Graph env;
1727 DAE.Exp arr,dim;
1728 Boolean impl;
1729 Absyn.Msg msg;
1730 FCore.Cache cache;
1731 list<Integer> dims;
1732
1733 case (cache, env, {arr,dim}, impl, msg)
1734 algorithm
1735
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
24 (cache,arr_val as Values.ARRAY(dimLst=dims)) := ceval(cache,env, arr, impl, msg,numIter+1);
1736
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
24 (cache,Values.INTEGER(dim_val)) := ceval(cache,env, dim, impl, msg,numIter+1);
1737 24 res := cevalBuiltinPromote2(arr_val, dim_val - listLength(dims));
1738 then
1739 (cache,res);
1740 end match;
1741 end cevalBuiltinPromote;
1742
1743 protected function cevalBuiltinPromote2 "Helper function to cevalBuiltinPromote"
1744 input Values.Value inValue;
1745 input Integer inInteger;
1746 output Values.Value outValue;
1747 algorithm
1748 outValue:=
1749 matchcontinue (inValue,inInteger)
1750 local
1751 Values.Value v;
1752 Integer n_1,n,i;
1753 list<Values.Value> vs_1,vs;
1754 list<Integer> il;
1755 64 case (v,0) then Values.ARRAY({v},{1});
1756 case (Values.ARRAY(valueLst = vs, dimLst = i::_),n)
1757 algorithm
1758 24 n_1 := n - 1;
1759
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 21 times.
24 if listEmpty(vs) then
1760 vs_1 := vs;
1761 3 il := listRest(inValue.dimLst);
1762 3 il := listAppend(List.fill(0, n-listLength(il)), il);
1763 else
1764
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
21 vs_1 as (Values.ARRAY(dimLst = il)::_) := List.map1(vs, cevalBuiltinPromote2, n_1);
1765 end if;
1766 24 then Values.ARRAY(vs_1,i::il);
1767 case (v,n)
1768 algorithm
1769 ✗ failure(Values.ARRAY() := v);
1770 ✗ n_1 := n - 1;
1771 ✗ v as Values.ARRAY(dimLst = il) := cevalBuiltinPromote2(v, n_1);
1772 ✗ then Values.ARRAY({v},1::il);
1773 else
1774 algorithm
1775 ✗ true := Flags.isSet(Flags.FAILTRACE);
1776 ✗ Debug.trace("- Ceval.cevalBuiltinPromote2 failed\n");
1777 ✗ then fail();
1778 end matchcontinue;
1779 end cevalBuiltinPromote2;
1780
1781 protected function cevalBuiltinSubstring "
1782 author: PA
1783 Evaluates the String operator String(r), String(i), String(b), String(e).
1784 TODO: Also evaluate String(r, significantDigits=d), and String(r, format=s)."
1785 input FCore.Cache inCache;
1786 input FCore.Graph inEnv;
1787 input list<DAE.Exp> inExpExpLst;
1788 input Boolean inBoolean;
1789 input Absyn.Msg inMsg;
1790 input Integer numIter;
1791 output FCore.Cache outCache;
1792 output Values.Value outValue;
1793 algorithm
1794 (outCache,outValue):=
1795 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1796 local
1797 FCore.Graph env;
1798 DAE.Exp str_exp, start_exp, stop_exp;
1799 Boolean impl;
1800 Absyn.Msg msg;
1801 FCore.Cache cache;
1802 String str;
1803 Integer start, stop;
1804
1805 case (cache, env, {str_exp, start_exp, stop_exp}, impl, msg)
1806 algorithm
1807 ✗ (cache,Values.STRING(str)) := ceval(cache,env, str_exp, impl, msg,numIter+1);
1808 ✗ (cache,Values.INTEGER(start)) := ceval(cache,env, start_exp, impl, msg,numIter+1);
1809 ✗ (cache,Values.INTEGER(stop)) := ceval(cache,env, stop_exp, impl, msg,numIter+1);
1810 ✗ str := substring(str, start, stop);
1811 ✗ then
1812 (cache,Values.STRING(str));
1813 end match;
1814 end cevalBuiltinSubstring;
1815
1816 protected function cevalBuiltinString "
1817 author: PA
1818 Evaluates the String operator String(r), String(i), String(b), String(e).
1819 TODO: Also evaluate String(r, significantDigits=d), and String(r, format=s)."
1820 input FCore.Cache inCache;
1821 input FCore.Graph inEnv;
1822 input list<DAE.Exp> inExpExpLst;
1823 input Boolean inBoolean;
1824 input Absyn.Msg inMsg;
1825 input Integer numIter;
1826 output FCore.Cache outCache;
1827 output Values.Value outValue;
1828 algorithm
1829 (outCache,outValue):=
1830 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1831 local
1832 FCore.Graph env;
1833 DAE.Exp exp, len_exp, justified_exp, sig_dig;
1834 Boolean impl;
1835 Absyn.Msg msg;
1836 FCore.Cache cache;
1837 String str,format;
1838 Integer i,len,sig; Real r; Boolean b, left_just;
1839 Absyn.Path p;
1840 Values.Value v;
1841
1842 case (cache, env, {exp, len_exp, justified_exp}, impl, msg)
1843 algorithm
1844 661 (cache,v) := ceval(cache, env, exp, impl, msg, numIter+1);
1845 str := match v
1846 573 case Values.INTEGER(i) then intString(i);
1847 ✗ case Values.BOOL(b) then boolString(b);
1848 ✗ case Values.ENUM_LITERAL(name = p) then AbsynUtil.pathLastIdent(p);
1849 end match;
1850 573 (cache, str) := cevalBuiltinStringFormat(cache, env, str, len_exp, justified_exp, impl, msg, numIter+1);
1851 573 then
1852 (cache,Values.STRING(str));
1853
1854 case (cache, env, {exp, sig_dig, len_exp, justified_exp}, impl, msg)
1855 algorithm
1856
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 (cache,Values.REAL(r)) := ceval(cache,env, exp, impl, msg,numIter+1);
1857
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 (cache,Values.INTEGER(len)) := ceval(cache,env, len_exp, impl, msg,numIter+1);
1858
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 (cache,Values.BOOL(left_just)) := ceval(cache,env, justified_exp, impl, msg,numIter+1);
1859
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 (cache,Values.INTEGER(sig)) := ceval(cache,env, sig_dig, impl, msg,numIter+1);
1860
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 format := "%" + (if left_just then "-" else "") + intString(len) + "." + intString(sig) + "g";
1861 28 str := System.snprintff(format,len+20,r);
1862 28 then
1863 (cache,Values.STRING(str));
1864
1865 end match;
1866 end cevalBuiltinString;
1867
1868 protected function cevalBuiltinStringFormat
1869 "This function formats a string by using the minimumLength and leftJustified
1870 arguments to the String function."
1871 input FCore.Cache inCache;
1872 input FCore.Graph inEnv;
1873 input String inString;
1874 input DAE.Exp lengthExp;
1875 input DAE.Exp justifiedExp;
1876 input Boolean inBoolean;
1877 input Absyn.Msg inMsg;
1878 input Integer numIter;
1879 output FCore.Cache outCache;
1880 output String outString;
1881 algorithm
1882 (outCache, outString) := match inCache
1883 local
1884 FCore.Cache cache;
1885 Integer min_length;
1886 Boolean left_justified;
1887 String str;
1888 case cache
1889 algorithm
1890
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 573 times.
573 (cache, Values.INTEGER(integer = min_length)) :=
1891 ceval(cache, inEnv, lengthExp, inBoolean, inMsg,numIter+1);
1892
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 573 times.
573 (cache, Values.BOOL(boolean = left_justified)) :=
1893 ceval(cache, inEnv, justifiedExp, inBoolean, inMsg,numIter+1);
1894 573 str := ExpressionSimplify.cevalBuiltinStringFormat(inString, stringLength(inString), min_length, left_justified);
1895 then
1896 (cache, str);
1897 end match;
1898 end cevalBuiltinStringFormat;
1899
1900 protected function cevalBuiltinPrint
1901 "Prints a String to stdout"
1902 input FCore.Cache inCache;
1903 input FCore.Graph inEnv;
1904 input list<DAE.Exp> inExpExpLst;
1905 input Boolean inBoolean;
1906 input Absyn.Msg inMsg;
1907 input Integer numIter;
1908 output FCore.Cache outCache;
1909 output Values.Value outValue;
1910 algorithm
1911 (outCache,outValue):=
1912 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1913 local
1914 FCore.Graph env;
1915 DAE.Exp exp;
1916 Boolean impl;
1917 Absyn.Msg msg;
1918 FCore.Cache cache;
1919 String str;
1920 case (cache, env, {exp}, impl, msg)
1921 algorithm
1922 ✗ (cache,Values.STRING(str)) := ceval(cache,env, exp, impl, msg,numIter+1);
1923 ✗ print(str);
1924 then
1925 (cache,Values.NORETCALL());
1926 end match;
1927 end cevalBuiltinPrint;
1928
1929 protected function cevalIntString
1930 input FCore.Cache inCache;
1931 input FCore.Graph inEnv;
1932 input list<DAE.Exp> inExpExpLst;
1933 input Boolean inBoolean;
1934 input Absyn.Msg inMsg;
1935 input Integer numIter;
1936 output FCore.Cache outCache;
1937 output Values.Value outValue;
1938 algorithm
1939 (outCache,outValue):=
1940 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1941 local
1942 FCore.Graph env;
1943 DAE.Exp exp;
1944 Boolean impl;
1945 Absyn.Msg msg;
1946 FCore.Cache cache;
1947 String str;
1948 Integer i;
1949 case (cache, env, {exp}, impl, msg)
1950 algorithm
1951
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
3 (cache,Values.INTEGER(i)) := ceval(cache,env, exp, impl, msg,numIter+1);
1952 ✗ str := intString(i);
1953 ✗ then
1954 (cache,Values.STRING(str));
1955 end match;
1956 end cevalIntString;
1957
1958 protected function cevalRealString
1959 input FCore.Cache inCache;
1960 input FCore.Graph inEnv;
1961 input list<DAE.Exp> inExpExpLst;
1962 input Boolean inBoolean;
1963 input Absyn.Msg inMsg;
1964 input Integer numIter;
1965 output FCore.Cache outCache;
1966 output Values.Value outValue;
1967 algorithm
1968 (outCache,outValue):=
1969 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
1970 local
1971 FCore.Graph env;
1972 DAE.Exp exp;
1973 Boolean impl;
1974 Absyn.Msg msg;
1975 FCore.Cache cache;
1976 String str;
1977 Real r;
1978 Values.Value v;
1979 case (cache, env, {exp}, impl, msg)
1980 algorithm
1981 24 (cache,v) := ceval(cache,env, exp, impl, msg,numIter+1);
1982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 Values.REAL(r) := v;
1983 20 str := realString(r);
1984 20 then
1985 (cache,Values.STRING(str));
1986 end match;
1987 end cevalRealString;
1988
1989 protected function cevalStringCharInt
1990 input FCore.Cache inCache;
1991 input FCore.Graph inEnv;
1992 input list<DAE.Exp> inExpExpLst;
1993 input Boolean inBoolean;
1994 input Absyn.Msg inMsg;
1995 input Integer numIter;
1996 output FCore.Cache outCache;
1997 output Values.Value outValue;
1998 algorithm
1999 (outCache,outValue):=
2000 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2001 local
2002 FCore.Graph env;
2003 DAE.Exp exp;
2004 Boolean impl;
2005 Absyn.Msg msg;
2006 FCore.Cache cache;
2007 String str;
2008 Integer i;
2009 case (cache, env, {exp}, impl, msg)
2010 algorithm
2011 ✗ (cache,Values.STRING(str)) := ceval(cache,env, exp, impl, msg,numIter+1);
2012 ✗ i := stringCharInt(str);
2013 ✗ then
2014 (cache,Values.INTEGER(i));
2015 end match;
2016 end cevalStringCharInt;
2017
2018 protected function cevalIntStringChar
2019 input FCore.Cache inCache;
2020 input FCore.Graph inEnv;
2021 input list<DAE.Exp> inExpExpLst;
2022 input Boolean inBoolean;
2023 input Absyn.Msg inMsg;
2024 input Integer numIter;
2025 output FCore.Cache outCache;
2026 output Values.Value outValue;
2027 algorithm
2028 (outCache,outValue):=
2029 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2030 local
2031 FCore.Graph env;
2032 DAE.Exp exp;
2033 Boolean impl;
2034 Absyn.Msg msg;
2035 FCore.Cache cache;
2036 String str;
2037 Integer i;
2038 case (cache, env, {exp}, impl, msg)
2039 algorithm
2040 ✗ (cache,Values.INTEGER(i)) := ceval(cache,env, exp, impl, msg,numIter+1);
2041 ✗ str := intStringChar(i);
2042 ✗ then
2043 (cache,Values.STRING(str));
2044 end match;
2045 end cevalIntStringChar;
2046
2047 protected function cevalStringInt
2048 input FCore.Cache inCache;
2049 input FCore.Graph inEnv;
2050 input list<DAE.Exp> inExpExpLst;
2051 input Boolean inBoolean;
2052 input Absyn.Msg inMsg;
2053 input Integer numIter;
2054 output FCore.Cache outCache;
2055 output Values.Value outValue;
2056 algorithm
2057 (outCache,outValue):=
2058 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2059 local
2060 FCore.Graph env;
2061 DAE.Exp exp;
2062 Boolean impl;
2063 Absyn.Msg msg;
2064 FCore.Cache cache;
2065 String str;
2066 Integer i;
2067 case (cache, env, {exp}, impl, msg)
2068 algorithm
2069 ✗ (cache,Values.STRING(str)) := ceval(cache,env, exp, impl, msg,numIter+1);
2070 ✗ i := stringInt(str);
2071 ✗ then
2072 (cache,Values.INTEGER(i));
2073 end match;
2074 end cevalStringInt;
2075
2076
2077 protected function cevalStringLength
2078 input FCore.Cache inCache;
2079 input FCore.Graph inEnv;
2080 input list<DAE.Exp> inExpExpLst;
2081 input Boolean inBoolean;
2082 input Absyn.Msg inMsg;
2083 input Integer numIter;
2084 output FCore.Cache outCache;
2085 output Values.Value outValue;
2086 algorithm
2087 (outCache,outValue):=
2088 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2089 local
2090 FCore.Graph env;
2091 DAE.Exp exp;
2092 Boolean impl;
2093 Absyn.Msg msg;
2094 FCore.Cache cache;
2095 String str;
2096 Integer i;
2097 case (cache, env, {exp}, impl, msg)
2098 algorithm
2099 ✗ (cache,Values.STRING(str)) := ceval(cache,env, exp, impl, msg,numIter+1);
2100 ✗ i := stringLength(str);
2101 ✗ then
2102 (cache,Values.INTEGER(i));
2103 end match;
2104 end cevalStringLength;
2105
2106 protected function cevalStringListStringChar
2107 input FCore.Cache inCache;
2108 input FCore.Graph inEnv;
2109 input list<DAE.Exp> inExpExpLst;
2110 input Boolean inBoolean;
2111 input Absyn.Msg inMsg;
2112 input Integer numIter;
2113 output FCore.Cache outCache;
2114 output Values.Value outValue;
2115 algorithm
2116 (outCache,outValue):=
2117 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2118 local
2119 FCore.Graph env;
2120 DAE.Exp exp;
2121 Boolean impl;
2122 Absyn.Msg msg;
2123 FCore.Cache cache;
2124 String str;
2125 list<String> chList;
2126 list<Values.Value> valList;
2127 case (cache, env, {exp}, impl, msg)
2128 algorithm
2129 ✗ (cache,Values.STRING(str)) := ceval(cache,env, exp, impl, msg,numIter+1);
2130 ✗ chList := stringListStringChar(str);
2131 ✗ valList := List.map(chList, generateValueString);
2132 ✗ then
2133 (cache,Values.LIST(valList));
2134 end match;
2135 end cevalStringListStringChar;
2136
2137 protected function generateValueString
2138 input String str;
2139 output Values.Value val;
2140 annotation(__OpenModelica_EarlyInline = true);
2141 algorithm
2142 ✗ val := Values.STRING(str);
2143 end generateValueString;
2144
2145 protected function cevalListStringCharString
2146 input FCore.Cache inCache;
2147 input FCore.Graph inEnv;
2148 input list<DAE.Exp> inExpExpLst;
2149 input Boolean inBoolean;
2150 input Absyn.Msg inMsg;
2151 input Integer numIter;
2152 output FCore.Cache outCache;
2153 output Values.Value outValue;
2154 algorithm
2155 (outCache,outValue):=
2156 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2157 local
2158 FCore.Graph env;
2159 DAE.Exp exp;
2160 Boolean impl;
2161 Absyn.Msg msg;
2162 FCore.Cache cache;
2163 String str;
2164 list<String> chList;
2165 list<Values.Value> valList;
2166 case (cache, env, {exp}, impl, msg)
2167 algorithm
2168 ✗ (cache,Values.LIST(valList)) := ceval(cache,env, exp, impl,msg,numIter+1);
2169 // Note that the RML version of the function has a weird name, but is also not implemented yet!
2170 // The work-around is to check that each String has length 1 and append all the Strings together
2171 // WARNING: This can be very, very slow for long lists - it grows as O(n^2)
2172 // TODO: When implemented, use listStringCharString (OMC name) or stringCharListString (RML name) directly
2173 ✗ chList := List.map(valList, extractValueStringChar);
2174 ✗ str := stringAppendList(chList);
2175 ✗ then
2176 (cache,Values.STRING(str));
2177 end match;
2178 end cevalListStringCharString;
2179
2180 protected function cevalStringAppendList
2181 input FCore.Cache inCache;
2182 input FCore.Graph inEnv;
2183 input list<DAE.Exp> inExpExpLst;
2184 input Boolean inBoolean;
2185 input Absyn.Msg inMsg;
2186 input Integer numIter;
2187 output FCore.Cache outCache;
2188 output Values.Value outValue;
2189 algorithm
2190 (outCache,outValue):=
2191 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2192 local
2193 FCore.Graph env;
2194 DAE.Exp exp;
2195 Boolean impl;
2196 Absyn.Msg msg;
2197 FCore.Cache cache;
2198 String str;
2199 list<String> chList;
2200 list<Values.Value> valList;
2201 case (cache, env, {exp}, impl, msg)
2202 algorithm
2203 ✗ (cache,Values.LIST(valList)) := ceval(cache,env, exp, impl, msg,numIter+1);
2204 ✗ chList := List.map(valList, ValuesUtil.extractValueString);
2205 ✗ str := stringAppendList(chList);
2206 ✗ then
2207 (cache,Values.STRING(str));
2208 end match;
2209 end cevalStringAppendList;
2210
2211 protected function cevalStringDelimitList
2212 input FCore.Cache inCache;
2213 input FCore.Graph inEnv;
2214 input list<DAE.Exp> inExpExpLst;
2215 input Boolean inBoolean;
2216 input Absyn.Msg inMsg;
2217 input Integer numIter;
2218 output FCore.Cache outCache;
2219 output Values.Value outValue;
2220 algorithm
2221 (outCache,outValue):=
2222 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2223 local
2224 FCore.Graph env;
2225 DAE.Exp exp1,exp2;
2226 Boolean impl;
2227 Absyn.Msg msg;
2228 FCore.Cache cache;
2229 String str;
2230 list<String> chList;
2231 list<Values.Value> valList;
2232 case (cache, env, {exp1,exp2}, impl, msg)
2233 algorithm
2234 ✗ (cache,Values.LIST(valList)) := ceval(cache,env, exp1, impl, msg,numIter+1);
2235 ✗ (cache,Values.STRING(str)) := ceval(cache,env, exp2, impl, msg,numIter+1);
2236 ✗ chList := List.map(valList, ValuesUtil.extractValueString);
2237 ✗ str := stringDelimitList(chList,str);
2238 ✗ then
2239 (cache,Values.STRING(str));
2240 end match;
2241 end cevalStringDelimitList;
2242
2243 protected function cevalListLength
2244 input FCore.Cache inCache;
2245 input FCore.Graph inEnv;
2246 input list<DAE.Exp> inExpExpLst;
2247 input Boolean inBoolean;
2248 input Absyn.Msg inMsg;
2249 input Integer numIter;
2250 output FCore.Cache outCache;
2251 output Values.Value outValue;
2252 algorithm
2253 (outCache,outValue):=
2254 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2255 local
2256 FCore.Graph env;
2257 DAE.Exp exp;
2258 Boolean impl;
2259 Absyn.Msg msg;
2260 FCore.Cache cache;
2261 Integer i;
2262 list<Values.Value> valList;
2263 case (cache, env, {exp}, impl, msg)
2264 algorithm
2265
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 (cache,Values.LIST(valList)) := ceval(cache,env, exp, impl, msg,numIter+1);
2266 4 i := listLength(valList);
2267 4 then
2268 (cache,Values.INTEGER(i));
2269 end match;
2270 end cevalListLength;
2271
2272 protected function cevalListAppend
2273 input FCore.Cache inCache;
2274 input FCore.Graph inEnv;
2275 input list<DAE.Exp> inExpExpLst;
2276 input Boolean inBoolean;
2277 input Absyn.Msg inMsg;
2278 input Integer numIter;
2279 output FCore.Cache outCache;
2280 output Values.Value outValue;
2281 algorithm
2282 (outCache,outValue):=
2283 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2284 local
2285 FCore.Graph env;
2286 DAE.Exp exp1,exp2;
2287 Boolean impl;
2288 Absyn.Msg msg;
2289 FCore.Cache cache;
2290 list<Values.Value> valList,valList1,valList2;
2291 case (cache, env, {exp1,exp2}, impl, msg)
2292 algorithm
2293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 (cache,Values.LIST(valList1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
2294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 (cache,Values.LIST(valList2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
2295 7 valList := listAppend(valList1, valList2);
2296 7 then
2297 (cache,Values.LIST(valList));
2298 end match;
2299 end cevalListAppend;
2300
2301 protected function cevalListReverse
2302 input FCore.Cache inCache;
2303 input FCore.Graph inEnv;
2304 input list<DAE.Exp> inExpExpLst;
2305 input Boolean inBoolean;
2306 input Absyn.Msg inMsg;
2307 input Integer numIter;
2308 output FCore.Cache outCache;
2309 output Values.Value outValue;
2310 algorithm
2311 (outCache,outValue):=
2312 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2313 local
2314 FCore.Graph env;
2315 DAE.Exp exp1;
2316 Boolean impl;
2317 Absyn.Msg msg;
2318 FCore.Cache cache;
2319 list<Values.Value> valList,valList1;
2320 case (cache, env, {exp1}, impl, msg)
2321 algorithm
2322
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 (cache,Values.LIST(valList1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
2323 4 valList := listReverse(valList1);
2324 4 then
2325 (cache,Values.LIST(valList));
2326 end match;
2327 end cevalListReverse;
2328
2329 protected function cevalListRest
2330 input FCore.Cache inCache;
2331 input FCore.Graph inEnv;
2332 input list<DAE.Exp> inExpExpLst;
2333 input Boolean inBoolean;
2334 input Absyn.Msg inMsg;
2335 input Integer numIter;
2336 output FCore.Cache outCache;
2337 output Values.Value outValue;
2338 algorithm
2339 (outCache,outValue):=
2340 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2341 local
2342 FCore.Graph env;
2343 DAE.Exp exp1;
2344 Boolean impl;
2345 Absyn.Msg msg;
2346 FCore.Cache cache;
2347 list<Values.Value> valList1;
2348 case (cache, env, {exp1}, impl, msg)
2349 algorithm
2350
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 (cache,Values.LIST(_::valList1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
2351 ✗ then
2352 (cache,Values.LIST(valList1));
2353 end match;
2354 end cevalListRest;
2355
2356 protected function cevalListMember
2357 input FCore.Cache inCache;
2358 input FCore.Graph inEnv;
2359 input list<DAE.Exp> inExpExpLst;
2360 input Boolean inBoolean;
2361 input Absyn.Msg inMsg;
2362 input Integer numIter;
2363 output FCore.Cache outCache;
2364 output Values.Value outValue;
2365 algorithm
2366 (outCache,outValue):=
2367 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2368 local
2369 FCore.Graph env;
2370 DAE.Exp exp1,exp2;
2371 Boolean impl;
2372 Absyn.Msg msg;
2373 FCore.Cache cache;
2374 list<Values.Value> vals;
2375 Values.Value val;
2376 Boolean b;
2377 case (cache, env, {exp1,exp2}, impl, msg)
2378 algorithm
2379 4 (cache,val) := ceval(cache,env,exp1,impl,msg,numIter+1);
2380
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 (cache,Values.LIST(vals)) := ceval(cache,env,exp2,impl,msg,numIter+1);
2381 4 b := listMember(val,vals);
2382
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
6 then
2383 (cache,Values.BOOL(b));
2384 end match;
2385 end cevalListMember;
2386
2387 protected function cevalListArrayLiteral
2388 input FCore.Cache inCache;
2389 input FCore.Graph inEnv;
2390 input list<DAE.Exp> inExpExpLst;
2391 input Boolean inBoolean;
2392 input Absyn.Msg inMsg;
2393 input Integer numIter;
2394 output FCore.Cache outCache;
2395 output Values.Value outValue;
2396 algorithm
2397 (outCache,outValue):=
2398 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2399 local
2400 FCore.Graph env;
2401 DAE.Exp exp;
2402 Boolean impl;
2403 Absyn.Msg msg;
2404 FCore.Cache cache;
2405 list<Values.Value> vals;
2406 case (cache, env, {exp}, impl, msg)
2407 algorithm
2408 ✗ (cache,Values.LIST(vals)) := ceval(cache,env,exp,impl,msg,numIter+1);
2409 ✗ then
2410 (cache,Values.META_ARRAY(vals));
2411 end match;
2412 end cevalListArrayLiteral;
2413
2414 protected function cevalAnyString
2415 input FCore.Cache inCache;
2416 input FCore.Graph inEnv;
2417 input list<DAE.Exp> inExpExpLst;
2418 input Boolean inBoolean;
2419 input Absyn.Msg inMsg;
2420 input Integer numIter;
2421 output FCore.Cache outCache;
2422 output Values.Value outValue;
2423 algorithm
2424 (outCache,outValue):=
2425 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2426 local
2427 FCore.Graph env;
2428 DAE.Exp exp1;
2429 Boolean impl;
2430 Absyn.Msg msg;
2431 FCore.Cache cache;
2432 Values.Value v;
2433 String s;
2434 case (cache, env, {exp1}, impl, msg)
2435 algorithm
2436 24 (cache,v) := ceval(cache,env, exp1, impl, msg,numIter+1);
2437 24 s := ValuesDump.valString(v);
2438 24 then
2439 (cache,Values.STRING(s));
2440 end match;
2441 end cevalAnyString;
2442
2443 protected function cevalNumBits
2444 input FCore.Cache inCache;
2445 input FCore.Graph inEnv;
2446 input list<DAE.Exp> inExpExpLst;
2447 input Boolean inBoolean;
2448 input Absyn.Msg inMsg;
2449 input Integer numIter;
2450 output FCore.Cache outCache;
2451 output Values.Value outValue;
2452 algorithm
2453 (outCache,outValue) := match inExpExpLst
2454 local
2455 Integer i;
2456 case {}
2457 algorithm
2458 ✗ i := System.numBits();
2459 ✗ then
2460 (inCache,Values.INTEGER(i));
2461 end match;
2462 end cevalNumBits;
2463
2464 protected function cevalIntegerMax
2465 input FCore.Cache inCache;
2466 input FCore.Graph inEnv;
2467 input list<DAE.Exp> inExpExpLst;
2468 input Boolean inBoolean;
2469 input Absyn.Msg inMsg;
2470 input Integer numIter;
2471 output FCore.Cache outCache;
2472 output Values.Value outValue;
2473 algorithm
2474 (outCache,outValue) := match inExpExpLst
2475 local
2476 Integer i;
2477 case {}
2478 algorithm
2479 ✗ i := System.intMaxLit();
2480 ✗ then
2481 (inCache,Values.INTEGER(i));
2482 end match;
2483 end cevalIntegerMax;
2484
2485 function cevalIntBitAnd
2486 input output FCore.Cache cache;
2487 input FCore.Graph env;
2488 input list<DAE.Exp> args;
2489 input Boolean impl;
2490 input Absyn.Msg msg;
2491 input Integer numIter;
2492 output Values.Value result;
2493 protected
2494 DAE.Exp e1, e2;
2495 Integer i1, i2;
2496 algorithm
2497 ✗ e1 :: e2 :: _ := args;
2498 ✗ (cache, Values.INTEGER(i1)) := ceval(cache, env, e1, impl, msg, numIter + 1);
2499 ✗ (cache, Values.INTEGER(i2)) := ceval(cache, env, e2, impl, msg, numIter + 1);
2500 ✗ result := Values.INTEGER(intBitAnd(i1, i2));
2501 end cevalIntBitAnd;
2502
2503 function cevalIntBitOr
2504 input output FCore.Cache cache;
2505 input FCore.Graph env;
2506 input list<DAE.Exp> args;
2507 input Boolean impl;
2508 input Absyn.Msg msg;
2509 input Integer numIter;
2510 output Values.Value result;
2511 protected
2512 DAE.Exp e1, e2;
2513 Integer i1, i2;
2514 algorithm
2515 ✗ e1 :: e2 :: _ := args;
2516 ✗ (cache, Values.INTEGER(i1)) := ceval(cache, env, e1, impl, msg, numIter + 1);
2517 ✗ (cache, Values.INTEGER(i2)) := ceval(cache, env, e2, impl, msg, numIter + 1);
2518 ✗ result := Values.INTEGER(intBitOr(i1, i2));
2519 end cevalIntBitOr;
2520
2521 function cevalIntBitXor
2522 input output FCore.Cache cache;
2523 input FCore.Graph env;
2524 input list<DAE.Exp> args;
2525 input Boolean impl;
2526 input Absyn.Msg msg;
2527 input Integer numIter;
2528 output Values.Value result;
2529 protected
2530 DAE.Exp e1, e2;
2531 Integer i1, i2;
2532 algorithm
2533 ✗ e1 :: e2 :: _ := args;
2534 ✗ (cache, Values.INTEGER(i1)) := ceval(cache, env, e1, impl, msg, numIter + 1);
2535 ✗ (cache, Values.INTEGER(i2)) := ceval(cache, env, e2, impl, msg, numIter + 1);
2536 ✗ result := Values.INTEGER(intBitXor(i1, i2));
2537 end cevalIntBitXor;
2538
2539 function cevalIntBitLShift
2540 input output FCore.Cache cache;
2541 input FCore.Graph env;
2542 input list<DAE.Exp> args;
2543 input Boolean impl;
2544 input Absyn.Msg msg;
2545 input Integer numIter;
2546 output Values.Value result;
2547 protected
2548 DAE.Exp e1, e2;
2549 Integer i, s;
2550 algorithm
2551 ✗ e1 :: e2 :: _ := args;
2552 ✗ (cache, Values.INTEGER(i)) := ceval(cache, env, e1, impl, msg, numIter + 1);
2553 ✗ (cache, Values.INTEGER(s)) := ceval(cache, env, e2, impl, msg, numIter + 1);
2554 ✗ result := Values.INTEGER(intBitLShift(i, s));
2555 end cevalIntBitLShift;
2556
2557 function cevalIntBitRShift
2558 input output FCore.Cache cache;
2559 input FCore.Graph env;
2560 input list<DAE.Exp> args;
2561 input Boolean impl;
2562 input Absyn.Msg msg;
2563 input Integer numIter;
2564 output Values.Value result;
2565 protected
2566 DAE.Exp e1, e2;
2567 Integer i, s;
2568 algorithm
2569 ✗ e1 :: e2 :: _ := args;
2570 ✗ (cache, Values.INTEGER(i)) := ceval(cache, env, e1, impl, msg, numIter + 1);
2571 ✗ (cache, Values.INTEGER(s)) := ceval(cache, env, e2, impl, msg, numIter + 1);
2572 ✗ result := Values.INTEGER(intBitRShift(i, s));
2573 end cevalIntBitRShift;
2574
2575 protected function makeLoadLibrariesEntry "Needed to be able to resolve modelica:// during runtime, etc.
2576 Should not be part of CevalScript since ModelicaServices needs this feature and the frontend needs to take care of it."
2577 input SCode.Element cl;
2578 input list<Values.Value> acc;
2579 output list<Values.Value> out;
2580 algorithm
2581 out := match cl
2582 local
2583 String name,fileName,dir;
2584 Values.Value v;
2585 Boolean b;
2586 case SCode.CLASS(info=SOURCEINFO(fileName="<interactive>")) then acc;
2587 case SCode.CLASS(name=name,info=SOURCEINFO(fileName=fileName))
2588 algorithm
2589 ✗ dir := System.dirname(fileName);
2590 ✗ fileName := System.basename(fileName);
2591 ✗ v := ValuesMake.makeArray({Values.STRING(name),Values.STRING(dir)});
2592 ✗ b := stringEq(fileName,"ModelicaBuiltin.mo") or stringEq(fileName,"MetaModelicaBuiltin.mo") or stringEq(dir,".");
2593 ✗ then List.consOnTrue(not b,v,acc);
2594 end match;
2595 end makeLoadLibrariesEntry;
2596
2597 protected function cevalListFirst
2598 input FCore.Cache inCache;
2599 input FCore.Graph inEnv;
2600 input list<DAE.Exp> inExpExpLst;
2601 input Boolean inBoolean;
2602 input Absyn.Msg inMsg;
2603 input Integer numIter;
2604 output FCore.Cache outCache;
2605 output Values.Value outValue;
2606 algorithm
2607 (outCache,outValue):=
2608 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2609 local
2610 FCore.Graph env;
2611 DAE.Exp exp1;
2612 Boolean impl;
2613 Absyn.Msg msg;
2614 FCore.Cache cache;
2615 Values.Value v;
2616 case (cache, env, {exp1}, impl, msg)
2617 algorithm
2618
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 (cache,Values.LIST(v::_)) := ceval(cache,env, exp1, impl, msg,numIter+1);
2619 ✗ then
2620 (cache,ValuesUtil.boxIfUnboxedVal(v));
2621 end match;
2622 end cevalListFirst;
2623
2624 protected function extractValueStringChar
2625 input Values.Value val;
2626 output String str;
2627 algorithm
2628 str := match val
2629 ✗ case Values.STRING(str) algorithm 1 := stringLength(str); then str;
2630 end match;
2631 end extractValueStringChar;
2632
2633 protected function cevalCat "evaluates the cat operator given a list of
2634 array values and a concatenation dimension."
2635 input list<Values.Value> v_lst;
2636 input Integer dim;
2637 output Values.Value outValue;
2638 protected
2639 list<Values.Value> v_lst_1;
2640 algorithm
2641 20 v_lst_1 := catDimension(v_lst, dim);
2642 20 outValue := ValuesMake.makeArray(v_lst_1);
2643 end cevalCat;
2644
2645 protected function catDimension "Helper function to cevalCat, concatenates a list
2646 arrays as Values, given a dimension as integer."
2647 input list<Values.Value> inValuesValueLst;
2648 input Integer inInteger;
2649 output list<Values.Value> outValuesValueLst;
2650 algorithm
2651 outValuesValueLst:=
2652 matchcontinue (inValuesValueLst,inInteger)
2653 local
2654 list<list<Values.Value>> vlst_lst,v_lst_lst,v_lst_lst_1;
2655 list<Values.Value> v_lst_1,vlst;
2656 Integer dim_1,dim,i1,i2;
2657 list<Integer> il;
2658 case (vlst,1) /* base case for first dimension */
2659 algorithm
2660 22 vlst_lst := List.map(vlst, ValuesUtil.arrayValues);
2661 22 v_lst_1 := List.flatten(vlst_lst);
2662 then
2663 v_lst_1;
2664 case (vlst,dim)
2665 algorithm
2666 1 v_lst_lst := List.map(vlst, ValuesUtil.arrayValues);
2667 1 dim_1 := dim - 1;
2668 1 v_lst_lst_1 := catDimension2(v_lst_lst, dim_1);
2669 1 v_lst_1 := List.map(v_lst_lst_1, ValuesMake.makeArray);
2670
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
1 Values.ARRAY(dimLst = i2::il) :: _ := v_lst_1;
2671 1 i1 := listLength(v_lst_1);
2672 1 v_lst_1 := cevalBuiltinTranspose2(v_lst_1, 1, i2::i1::il);
2673 then
2674 v_lst_1;
2675 end matchcontinue;
2676 end catDimension;
2677
2678 protected function catDimension2 "author: PA
2679 Helper function to catDimension."
2680 input list<list<Values.Value>> inValuesValueLstLst;
2681 input Integer inInteger;
2682 output list<list<Values.Value>> outValuesValueLstLst;
2683 algorithm
2684 outValuesValueLstLst:=
2685 matchcontinue (inValuesValueLstLst,inInteger)
2686 local
2687 list<Values.Value> l_lst,first_lst,first_lst_1;
2688 list<list<Values.Value>> first_lst_2,lst,rest,rest_1,res;
2689 Integer dim;
2690 case (lst,dim)
2691 algorithm
2692 3 l_lst := listHead(lst);
2693
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
3 1 := listLength(l_lst);
2694 1 first_lst := List.map(lst, listHead);
2695 1 first_lst_1 := catDimension(first_lst, dim);
2696 1 first_lst_2 := List.map(first_lst_1, List.create);
2697 then
2698 first_lst_2;
2699 case (lst,dim)
2700 algorithm
2701 2 first_lst := List.map(lst, listHead);
2702 2 rest := List.map(lst, listRest);
2703 2 first_lst_1 := catDimension(first_lst, dim);
2704 2 rest_1 := catDimension2(rest, dim);
2705 2 res := List.threadMap(rest_1, first_lst_1, List.consr);
2706 then
2707 res;
2708 end matchcontinue;
2709 end catDimension2;
2710
2711 protected function cevalBuiltinFloor "author: LP
2712 evaluates the floor operator."
2713 input FCore.Cache inCache;
2714 input FCore.Graph inEnv;
2715 input list<DAE.Exp> inExpExpLst;
2716 input Boolean inBoolean;
2717 input Absyn.Msg inMsg;
2718 input Integer numIter;
2719 output FCore.Cache outCache;
2720 output Values.Value outValue;
2721 algorithm
2722 (outCache,outValue):=
2723 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2724 local
2725 Real rv,rv_1;
2726 FCore.Graph env;
2727 DAE.Exp exp;
2728 Boolean impl;
2729 Absyn.Msg msg;
2730 FCore.Cache cache;
2731 case (cache, env, {exp}, impl, msg)
2732 algorithm
2733
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
65 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
2734 65 rv_1 := floor(rv);
2735 65 then
2736 (cache,Values.REAL(rv_1));
2737 end match;
2738 end cevalBuiltinFloor;
2739
2740 protected function cevalBuiltinCeil "author: LP
2741 evaluates the ceil operator."
2742 input FCore.Cache inCache;
2743 input FCore.Graph inEnv;
2744 input list<DAE.Exp> inExpExpLst;
2745 input Boolean inBoolean;
2746 input Absyn.Msg inMsg;
2747 input Integer numIter;
2748 output FCore.Cache outCache;
2749 output Values.Value outValue;
2750 algorithm
2751 (outCache,outValue):=
2752 match(inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2753 local
2754 Real rv,rv_1,rvt,realRet;
2755 Integer ri,ri_1;
2756 FCore.Graph env;
2757 DAE.Exp exp;
2758 Boolean impl;
2759 Absyn.Msg msg;
2760 FCore.Cache cache;
2761 Values.Value v;
2762
2763 case (cache, env, {exp}, impl, msg)
2764 algorithm
2765
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 (cache,Values.REAL(rv)) := ceval(cache, env, exp, impl, msg, numIter+1);
2766
2767 2 rv_1 := floor(rv);
2768 2 ri := realInt(rv_1);
2769 2 rvt := intReal(ri);
2770 2 ri_1 := ri + 1;
2771 2 realRet := intReal(ri_1);
2772
2773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 v := if (rvt == rv) then Values.REAL(rvt) else Values.REAL(realRet);
2774 then
2775 (cache,v);
2776
2777 end match;
2778 end cevalBuiltinCeil;
2779
2780 protected function cevalBuiltinSqrt "author: LP
2781 Evaluates the builtin sqrt operator."
2782 input FCore.Cache inCache;
2783 input FCore.Graph inEnv;
2784 input list<DAE.Exp> inExpExpLst;
2785 input Boolean inBoolean;
2786 input Absyn.Msg inMsg;
2787 input Integer numIter;
2788 output FCore.Cache outCache;
2789 output Values.Value outValue;
2790 algorithm
2791 (outCache,outValue):=
2792 match(inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2793 local
2794 Real rv,rv_1;
2795 FCore.Graph env;
2796 DAE.Exp exp;
2797 Boolean impl;
2798 Absyn.Msg msg;
2799 FCore.Cache cache;
2800 SourceInfo info;
2801
2802 case (cache, env, {exp}, impl, msg)
2803 algorithm
2804
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 6210 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6210 times.
6214 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
2805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6210 times.
6210 if (rv < 0.0)
2806 then
2807 ✗ Absyn.MSG(info = info) := msg;
2808 ✗ Error.addSourceMessage(Error.NEGATIVE_SQRT, {}, info);
2809 ✗ fail();
2810 else
2811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6210 times.
6210 rv_1 := sqrt(rv);
2812 end if;
2813 6210 then
2814 (cache,Values.REAL(rv_1));
2815
2816 end match;
2817 end cevalBuiltinSqrt;
2818
2819 protected function cevalBuiltinNthRoot
2820 "Evaluates the builtin nthRoot operator."
2821 input output FCore.Cache cache;
2822 input FCore.Graph env;
2823 input list<DAE.Exp> args;
2824 input Boolean impl;
2825 input Absyn.Msg msg;
2826 input Integer numIter;
2827 output Values.Value outValue;
2828 protected
2829 DAE.Exp v_exp, n_exp;
2830 Real v;
2831 Integer n;
2832 SourceInfo info;
2833 algorithm
2834
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
1 {v_exp, n_exp} := args;
2835
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache, Values.REAL(v)) := ceval(cache, env, v_exp, impl, msg, numIter + 1);
2836
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache, Values.INTEGER(n)) := ceval(cache, env, n_exp, impl, msg, numIter + 1);
2837
2838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if n <= 0 then
2839 ✗ Absyn.MSG(info = info) := msg;
2840 ✗ Error.addSourceMessage(Error.NON_POSITIVE_NTH_ROOT, {String(v), String(n)}, info);
2841 ✗ fail();
2842 end if;
2843
2844
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 if intMod(n, 2) == 0 and v < 0 then
2845
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 Absyn.MSG(info = info) := msg;
2846 ✗ Error.addSourceMessage(Error.NEGATIVE_NTH_ROOT, {String(v), String(n)}, info);
2847 ✗ fail();
2848 end if;
2849
2850 ✗ outValue := Values.REAL(v ^ (1/n));
2851 end cevalBuiltinNthRoot;
2852
2853 protected function cevalBuiltinSin "author: LP
2854 Evaluates the builtin sin function."
2855 input FCore.Cache inCache;
2856 input FCore.Graph inEnv;
2857 input list<DAE.Exp> inExpExpLst;
2858 input Boolean inBoolean;
2859 input Absyn.Msg inMsg;
2860 input Integer numIter;
2861 output FCore.Cache outCache;
2862 output Values.Value outValue;
2863 algorithm
2864 (outCache,outValue):=
2865 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2866 local
2867 Real rv,rv_1;
2868 FCore.Graph env;
2869 DAE.Exp exp;
2870 Boolean impl;
2871 Absyn.Msg msg;
2872 FCore.Cache cache;
2873 case (cache, env, {exp}, impl, msg)
2874 algorithm
2875
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11210 times.
11216 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl, msg, numIter+1);
2876 11210 rv_1 := sin(rv);
2877 11210 then
2878 (cache,Values.REAL(rv_1));
2879 end match;
2880 end cevalBuiltinSin;
2881
2882 protected function cevalBuiltinSinh "author: PA
2883 Evaluates the builtin sinh function."
2884 input FCore.Cache inCache;
2885 input FCore.Graph inEnv;
2886 input list<DAE.Exp> inExpExpLst;
2887 input Boolean inBoolean;
2888 input Absyn.Msg inMsg;
2889 input Integer numIter;
2890 output FCore.Cache outCache;
2891 output Values.Value outValue;
2892 algorithm
2893 (outCache,outValue):=
2894 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2895 local
2896 Real rv,rv_1;
2897 FCore.Graph env;
2898 DAE.Exp exp;
2899 Boolean impl;
2900 Absyn.Msg msg;
2901 FCore.Cache cache;
2902 case (cache, env, {exp}, impl, msg)
2903 algorithm
2904
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
2905 1 rv_1 := sinh(rv);
2906 1 then
2907 (cache,Values.REAL(rv_1));
2908 end match;
2909 end cevalBuiltinSinh;
2910
2911 protected function cevalBuiltinCos "author: LP
2912 Evaluates the builtin cos function."
2913 input FCore.Cache inCache;
2914 input FCore.Graph inEnv;
2915 input list<DAE.Exp> inExpExpLst;
2916 input Boolean inBoolean;
2917 input Absyn.Msg inMsg;
2918 input Integer numIter;
2919 output FCore.Cache outCache;
2920 output Values.Value outValue;
2921 algorithm
2922 (outCache,outValue):=
2923 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2924 local
2925 Real rv,rv_1;
2926 FCore.Graph env;
2927 DAE.Exp exp;
2928 Boolean impl;
2929 Absyn.Msg msg;
2930 FCore.Cache cache;
2931 case (cache, env, {exp}, impl, msg)
2932 algorithm
2933
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8476 times.
8482 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
2934 8476 rv_1 := cos(rv);
2935 8476 then
2936 (cache,Values.REAL(rv_1));
2937 end match;
2938 end cevalBuiltinCos;
2939
2940 protected function cevalBuiltinCosh "author: PA
2941 Evaluates the builtin cosh function."
2942 input FCore.Cache inCache;
2943 input FCore.Graph inEnv;
2944 input list<DAE.Exp> inExpExpLst;
2945 input Boolean inBoolean;
2946 input Absyn.Msg inMsg;
2947 input Integer numIter;
2948 output FCore.Cache outCache;
2949 output Values.Value outValue;
2950 algorithm
2951 (outCache,outValue):=
2952 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2953 local
2954 Real rv,rv_1;
2955 FCore.Graph env;
2956 DAE.Exp exp;
2957 Boolean impl;
2958 Absyn.Msg msg;
2959 FCore.Cache cache;
2960 case (cache, env, {exp}, impl, msg)
2961 algorithm
2962
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
2963 2 rv_1 := cosh(rv);
2964 2 then
2965 (cache,Values.REAL(rv_1));
2966 end match;
2967 end cevalBuiltinCosh;
2968
2969 protected function cevalBuiltinLog "author: LP
2970 Evaluates the builtin Log function."
2971 input FCore.Cache inCache;
2972 input FCore.Graph inEnv;
2973 input list<DAE.Exp> inExpExpLst;
2974 input Boolean inBoolean;
2975 input Absyn.Msg inMsg;
2976 input Integer numIter;
2977 output FCore.Cache outCache;
2978 output Values.Value outValue;
2979 algorithm
2980 (outCache,outValue):=
2981 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
2982 local
2983 Real rv,rv_1;
2984 FCore.Graph env;
2985 DAE.Exp exp;
2986 Boolean impl;
2987 Absyn.Msg msg;
2988 FCore.Cache cache;
2989 case (cache, env, {exp}, impl, msg)
2990 algorithm
2991
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 557 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 557 times.
557 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl, msg,numIter+1);
2992
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 557 times.
557 true := rv > 0; // TODO: Print error-message?
2993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 557 times.
557 rv_1 := log(rv);
2994 557 then
2995 (cache,Values.REAL(rv_1));
2996 end match;
2997 end cevalBuiltinLog;
2998
2999 protected function cevalBuiltinLog10
3000 input FCore.Cache inCache;
3001 input FCore.Graph inEnv;
3002 input list<DAE.Exp> inExpExpLst;
3003 input Boolean inBoolean;
3004 input Absyn.Msg inMsg;
3005 input Integer numIter;
3006 output FCore.Cache outCache;
3007 output Values.Value outValue;
3008 algorithm
3009 (outCache,outValue):=
3010 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3011 local
3012 Real rv,rv_1;
3013 FCore.Graph env;
3014 DAE.Exp exp;
3015 Boolean impl;
3016 Absyn.Msg msg;
3017 FCore.Cache cache;
3018 case (cache, env, {exp}, impl, msg)
3019 algorithm
3020
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
1 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
3021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 true := rv > 0; // TODO: Print error-message?
3022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 rv_1 := log10(rv);
3023 1 then
3024 (cache,Values.REAL(rv_1));
3025 end match;
3026 end cevalBuiltinLog10;
3027
3028 protected function cevalBuiltinTan "author: LP
3029 Evaluates the builtin tan function."
3030 input FCore.Cache inCache;
3031 input FCore.Graph inEnv;
3032 input list<DAE.Exp> inExpExpLst;
3033 input Boolean impl;
3034 input Absyn.Msg msg;
3035 input Integer numIter;
3036 output FCore.Cache outCache;
3037 output Values.Value outValue;
3038 algorithm
3039 (outCache,outValue):=
3040 match (inCache,inEnv,inExpExpLst)
3041 local
3042 Real rv,rv_1;
3043 FCore.Graph env;
3044 DAE.Exp exp;
3045 FCore.Cache cache;
3046 case (cache,env,{exp})
3047 algorithm
3048
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl, msg,numIter+1);
3049 5 rv_1 := tan(rv);
3050 5 then
3051 (cache,Values.REAL(rv_1));
3052 end match;
3053 end cevalBuiltinTan;
3054
3055 protected function cevalBuiltinTanh "author: PA
3056 Evaluates the builtin tanh function."
3057 input FCore.Cache inCache;
3058 input FCore.Graph inEnv;
3059 input list<DAE.Exp> inExpExpLst;
3060 input Boolean inBoolean;
3061 input Absyn.Msg inMsg;
3062 input Integer numIter;
3063 output FCore.Cache outCache;
3064 output Values.Value outValue;
3065 algorithm
3066 (outCache,outValue):=
3067 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3068 local
3069 Real rv,rv_1;
3070 FCore.Graph env;
3071 DAE.Exp exp;
3072 Boolean impl;
3073 Absyn.Msg msg;
3074 FCore.Cache cache;
3075 case (cache, env, {exp}, impl, msg)
3076 algorithm
3077
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
3078 1 rv_1 := tanh(rv);
3079 1 then
3080 (cache,Values.REAL(rv_1));
3081 end match;
3082 end cevalBuiltinTanh;
3083
3084 protected function cevalBuiltinAsin "author: PA
3085 Evaluates the builtin asin function."
3086 input FCore.Cache inCache;
3087 input FCore.Graph inEnv;
3088 input list<DAE.Exp> inExpExpLst;
3089 input Boolean inBoolean;
3090 input Absyn.Msg inMsg;
3091 input Integer numIter;
3092 output FCore.Cache outCache;
3093 output Values.Value outValue;
3094 algorithm
3095 (outCache,outValue):=
3096 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3097 local
3098 Real rv,rv_1;
3099 FCore.Graph env;
3100 DAE.Exp exp;
3101 Boolean impl;
3102 Absyn.Msg msg;
3103 FCore.Cache cache;
3104 case (cache, env, {exp}, impl, msg)
3105 algorithm
3106
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✗ Branch 4 not taken.
84 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
3107
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
84 true := rv >= -1.0 and rv <= 1.0;
3108 84 rv_1 := asin(rv);
3109 84 then
3110 (cache,Values.REAL(rv_1));
3111 end match;
3112 end cevalBuiltinAsin;
3113
3114 protected function cevalBuiltinAcos "author: PA
3115 Evaluates the builtin acos function."
3116 input FCore.Cache inCache;
3117 input FCore.Graph inEnv;
3118 input list<DAE.Exp> inExpExpLst;
3119 input Boolean inBoolean;
3120 input Absyn.Msg inMsg;
3121 input Integer numIter;
3122 output FCore.Cache outCache;
3123 output Values.Value outValue;
3124 algorithm
3125 (outCache,outValue):=
3126 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3127 local
3128 Real rv,rv_1;
3129 FCore.Graph env;
3130 DAE.Exp exp;
3131 Boolean impl;
3132 Absyn.Msg msg;
3133 FCore.Cache cache;
3134 case (cache, env, {exp}, impl, msg)
3135 algorithm
3136
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
3137
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 true := rv >= -1.0 and rv <= 1.0;
3138 3 rv_1 := acos(rv);
3139 3 then
3140 (cache,Values.REAL(rv_1));
3141 end match;
3142 end cevalBuiltinAcos;
3143
3144 protected function cevalBuiltinAtan "author: PA
3145 Evaluates the builtin atan function."
3146 input FCore.Cache inCache;
3147 input FCore.Graph inEnv;
3148 input list<DAE.Exp> inExpExpLst;
3149 input Boolean inBoolean;
3150 input Absyn.Msg inMsg;
3151 input Integer numIter;
3152 output FCore.Cache outCache;
3153 output Values.Value outValue;
3154 algorithm
3155 (outCache,outValue):=
3156 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3157 local
3158 Real rv,rv_1;
3159 FCore.Graph env;
3160 DAE.Exp exp;
3161 Boolean impl;
3162 Absyn.Msg msg;
3163 FCore.Cache cache;
3164 case (cache, env, {exp}, impl, msg) /* atan is not implemented in MetaModelica Compiler (MMC) for some strange reason. */
3165 algorithm
3166
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 (cache,Values.REAL(rv)) := ceval(cache,env, exp, impl,msg,numIter+1);
3167 3 rv_1 := atan(rv);
3168 3 then
3169 (cache,Values.REAL(rv_1));
3170 end match;
3171 end cevalBuiltinAtan;
3172
3173 protected function cevalBuiltinAtan2
3174 input FCore.Cache inCache;
3175 input FCore.Graph inEnv;
3176 input list<DAE.Exp> inExpExpLst;
3177 input Boolean inBoolean;
3178 input Absyn.Msg inMsg;
3179 input Integer numIter;
3180 output FCore.Cache outCache;
3181 output Values.Value outValue;
3182 algorithm
3183 (outCache,outValue):=
3184 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3185 local
3186 Real rv,rv_1,rv_2;
3187 FCore.Graph env;
3188 DAE.Exp exp1,exp2;
3189 Boolean impl;
3190 Absyn.Msg msg;
3191 FCore.Cache cache;
3192 case (cache, env, {exp1,exp2}, impl, msg)
3193 algorithm
3194
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 (cache,Values.REAL(rv_1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3195
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 (cache,Values.REAL(rv_2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3196 9 rv := atan2(rv_1,rv_2);
3197 9 then
3198 (cache,Values.REAL(rv));
3199 end match;
3200 end cevalBuiltinAtan2;
3201
3202 protected function cevalBuiltinDiv "author: LP
3203 Evaluates the builtin div operator."
3204 input FCore.Cache inCache;
3205 input FCore.Graph inEnv;
3206 input list<DAE.Exp> inExpExpLst;
3207 input Boolean inBoolean;
3208 input Absyn.Msg inMsg;
3209 input Integer numIter;
3210 output FCore.Cache outCache;
3211 output Values.Value outValue;
3212 algorithm
3213 (outCache,outValue):=
3214 matchcontinue (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3215 local
3216 Real rv1,rv2,rv_1,rv_2;
3217 Integer ri,ri_1,ri1,ri2;
3218 FCore.Graph env;
3219 DAE.Exp exp1,exp2;
3220 Boolean impl;
3221 Absyn.Msg msg;
3222 String exp1_str,exp2_str,lh_str,rh_str;
3223 FCore.Cache cache; Boolean b;
3224 SourceInfo info;
3225
3226 case (cache, env, {exp1,exp2}, impl, msg)
3227 algorithm
3228
2/2
✓ Branch 1 taken 3404 times.
✓ Branch 2 taken 802 times.
4206 (cache,Values.REAL(rv1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3229
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 802 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 802 times.
802 (cache,Values.REAL(rv2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 802 times.
802 rv_1 := rv1 / rv2;
3231 b := rv_1 < 0.0;
3232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 802 times.
802 rv_2 := if b then ceil(rv_1) else floor(rv_1);
3233 802 then
3234 (cache,Values.REAL(rv_2));
3235 case (cache, env, {exp1,exp2}, impl, msg)
3236 algorithm
3237
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3404 times.
6808 (cache,Values.INTEGER(ri)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3238 3404 rv1 := intReal(ri);
3239
1/2
✓ Branch 1 taken 3404 times.
✗ Branch 2 not taken.
3404 (cache,Values.REAL(rv2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3240 ✗ Error.addInternalError("cevalBuiltinDiv got Integer and Real (type error)\n", sourceInfo());
3241 ✗ rv_1 := rv1 / rv2;
3242 b := rv_1 < 0.0;
3243 ✗ rv_2 := if b then ceil(rv_1) else floor(rv_1);
3244 ✗ then
3245 (cache,Values.REAL(rv_2));
3246 case (cache, env, {exp1,exp2}, impl, msg)
3247 algorithm
3248
1/2
✓ Branch 1 taken 3404 times.
✗ Branch 2 not taken.
3404 (cache,Values.REAL(rv1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3249 ✗ (cache,Values.INTEGER(ri)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3250 ✗ Error.addInternalError("cevalBuiltinDiv got Real and Integer (type error)\n", sourceInfo());
3251 ✗ rv2 := intReal(ri);
3252 ✗ rv_1 := rv1 / rv2;
3253 b := rv_1 < 0.0;
3254 ✗ rv_2 := if b then ceil(rv_1) else floor(rv_1);
3255 ✗ then
3256 (cache,Values.REAL(rv_2));
3257 case (cache, env, {exp1,exp2}, impl, msg)
3258 algorithm
3259
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3404 times.
3404 (cache,Values.INTEGER(ri1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3260
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3404 times.
3404 (cache,Values.INTEGER(ri2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3404 times.
3404 ri_1 := intDiv(ri1,ri2);
3262 3404 then
3263 (cache,Values.INTEGER(ri_1));
3264 case (cache, env, {exp1,exp2}, impl, Absyn.MSG(info = info))
3265 algorithm
3266 ✗ (_,Values.REAL(rv2)) := ceval(cache,env, exp2, impl, inMsg,numIter+1);
3267 ✗ true := (rv2 == 0.0);
3268 ✗ exp1_str := ExpressionBasics.printExpStr(exp1);
3269 ✗ exp2_str := ExpressionBasics.printExpStr(exp2);
3270 ✗ Error.addSourceMessage(Error.DIVISION_BY_ZERO, {exp1_str,exp2_str}, info);
3271 ✗ then
3272 fail();
3273 case (cache, env, {_,exp2}, impl, Absyn.NO_MSG())
3274 algorithm
3275 ✗ (_,Values.REAL(rv2)) := ceval(cache,env, exp2, impl, Absyn.NO_MSG(),numIter+1);
3276 true := (rv2 == 0.0);
3277 ✗ then
3278 fail();
3279 case (cache, env, {exp1,exp2}, impl, Absyn.MSG(info = info))
3280 algorithm
3281 ✗ (_,Values.INTEGER(ri2)) := ceval(cache,env, exp2, impl, inMsg,numIter+1);
3282 ✗ true := (ri2 == 0);
3283 ✗ lh_str := ExpressionBasics.printExpStr(exp1);
3284 ✗ rh_str := ExpressionBasics.printExpStr(exp2);
3285 ✗ Error.addSourceMessage(Error.DIVISION_BY_ZERO, {lh_str,rh_str}, info);
3286 ✗ then
3287 fail();
3288 case (cache, env, {_,exp2}, impl, Absyn.NO_MSG())
3289 algorithm
3290 ✗ (_,Values.INTEGER(ri2)) := ceval(cache,env, exp2, impl, Absyn.NO_MSG(),numIter+1);
3291 true := (ri2 == 0);
3292 ✗ then
3293 fail();
3294 end matchcontinue;
3295 end cevalBuiltinDiv;
3296
3297 protected function cevalBuiltinMod "author: LP
3298 Evaluates the builtin mod operator."
3299 input FCore.Cache inCache;
3300 input FCore.Graph inEnv;
3301 input list<DAE.Exp> inExpExpLst;
3302 input Boolean impl;
3303 input Absyn.Msg msg;
3304 input Integer numIter;
3305 output FCore.Cache cache = inCache;
3306 output Values.Value outValue;
3307 protected
3308 Values.Value v1, v2;
3309 DAE.Exp exp1,exp2;
3310 algorithm
3311
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 26 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 26 times.
26 {exp1,exp2} := inExpExpLst;
3312 26 (cache,v1) := ceval(cache,inEnv, exp1, impl, msg,numIter+1);
3313 24 (cache,v2) := ceval(cache,inEnv, exp2, impl, msg,numIter+1);
3314 outValue := match (v1,v2,msg)
3315 local
3316 Real rv1,rv2;
3317 Integer ri,ri1,ri2;
3318 String lhs_str,rhs_str;
3319 SourceInfo info;
3320
3321 case (Values.REAL(rv1),Values.REAL(rv2),_)
3322 4 then (Values.REAL(mod(rv1,rv2)));
3323 case (Values.INTEGER(ri),Values.REAL(rv2),_)
3324 ✗ then (Values.REAL(mod(ri,rv2)));
3325 case (Values.REAL(rv1),Values.INTEGER(ri),_)
3326 ✗ then (Values.REAL(mod(rv1,ri)));
3327 case (Values.INTEGER(ri1),Values.INTEGER(ri2),_)
3328 20 then (Values.INTEGER(mod(ri1,ri2)));
3329 case (_,Values.REAL(rv2),Absyn.MSG(info = info))
3330 guard rv2 == 0.0
3331 algorithm
3332 ✗ lhs_str := ExpressionBasics.printExpStr(exp1);
3333 ✗ rhs_str := ExpressionBasics.printExpStr(exp2);
3334 ✗ Error.addSourceMessage(Error.MODULO_BY_ZERO, {lhs_str,rhs_str}, info);
3335 ✗ then fail();
3336 case (_,Values.INTEGER(0),Absyn.MSG(info = info))
3337 algorithm
3338 ✗ lhs_str := ExpressionBasics.printExpStr(exp1);
3339 ✗ rhs_str := ExpressionBasics.printExpStr(exp2);
3340 ✗ Error.addSourceMessage(Error.MODULO_BY_ZERO, {lhs_str,rhs_str}, info);
3341 ✗ then
3342 fail();
3343 end match;
3344 end cevalBuiltinMod;
3345
3346 protected function cevalBuiltinSum "Evaluates the builtin sum function."
3347 input FCore.Cache inCache;
3348 input FCore.Graph inEnv;
3349 input list<DAE.Exp> inExpExpLst;
3350 input Boolean inBoolean;
3351 input Absyn.Msg inMsg;
3352 input Integer numIter;
3353 output FCore.Cache outCache;
3354 output Values.Value outValue;
3355 algorithm
3356 (outCache,outValue):=
3357 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3358 local
3359 Values.Value v;
3360 list<Values.Value> vals;
3361 FCore.Graph env;
3362 DAE.Exp arr;
3363 Boolean impl;
3364 Absyn.Msg msg;
3365 FCore.Cache cache;
3366 case (cache, env, {arr}, impl, msg)
3367 algorithm
3368
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 (cache, Values.ARRAY(valueLst = vals)) := ceval(cache,env, arr, impl, msg, numIter+1);
3369
2/2
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 3 times.
8 if Types.isInteger(Expression.typeof(Expression.unboxExp(arr))) then
3370
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
5 if listEmpty(vals) then
3371 v := Values.INTEGER(0);
3372 else
3373
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 v as Values.INTEGER() := ValuesUtil.sumArrayelt(vals);
3374 end if;
3375 else
3376
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 if listEmpty(vals) then
3377 v := Values.REAL(0.0);
3378 else
3379
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 v as Values.REAL() := ValuesUtil.sumArrayelt(vals);
3380 end if;
3381 end if;
3382 then (cache,v);
3383 end match;
3384 end cevalBuiltinSum;
3385
3386 protected function cevalBuiltinMax "author: LP
3387 Evaluates the builtin max function."
3388 input FCore.Cache inCache;
3389 input FCore.Graph inEnv;
3390 input list<DAE.Exp> inExpExpLst;
3391 input Boolean inBoolean;
3392 input Absyn.Msg inMsg;
3393 input Integer numIter;
3394 output FCore.Cache outCache;
3395 output Values.Value outValue;
3396 algorithm
3397 (outCache,outValue):=
3398 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3399 local
3400 Values.Value v,v1,v2,v_1;
3401 FCore.Graph env;
3402 DAE.Exp arr,s1,s2;
3403 Boolean impl;
3404 Absyn.Msg msg;
3405 FCore.Cache cache;
3406 case (cache, env, {arr}, impl, msg)
3407 algorithm
3408 8 (cache,v) := ceval(cache,env, arr, impl, msg,numIter+1);
3409 8 v_1 := cevalBuiltinMaxArr(v);
3410 then
3411 (cache,v_1);
3412 case (cache, env, {s1,s2}, impl, msg)
3413 algorithm
3414 265 (cache,v1) := ceval(cache,env, s1, impl, msg,numIter+1);
3415 259 (cache,v2) := ceval(cache,env, s2, impl, msg,numIter+1);
3416 258 v := cevalBuiltinMax2(v1,v2);
3417 then
3418 (cache,v);
3419 end match;
3420 end cevalBuiltinMax;
3421
3422 protected function cevalBuiltinMax2
3423 input Values.Value v1;
3424 input Values.Value v2;
3425 output Values.Value outValue;
3426 algorithm
3427 outValue := match (v1,v2)
3428 local
3429 Integer i1, i2;
3430 Real r1, r2;
3431 Boolean b1, b2;
3432 String s1, s2;
3433
3434 17 case (Values.INTEGER(i1), Values.INTEGER(i2)) then Values.INTEGER(max(i1, i2));
3435 257 case (Values.REAL(r1), Values.REAL(r2)) then Values.REAL(max(r1, r2));
3436 ✗ case (Values.BOOL(b1), Values.BOOL(b2)) then Values.BOOL(b1 or b2);
3437 case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL())
3438 ✗ then if v1.index > v2.index then v1 else v2;
3439 else
3440 algorithm
3441 ✗ true := Flags.isSet(Flags.FAILTRACE);
3442 ✗ s1 := ValuesDump.valString(v1);
3443 ✗ s2 := ValuesDump.valString(v2);
3444 ✗ Debug.traceln("- Ceval.cevalBuiltinMin2 failed: min(" + s1 + ", " + s2 + ")");
3445 ✗ then
3446 fail();
3447 end match;
3448 end cevalBuiltinMax2;
3449
3450 protected function cevalBuiltinMaxArr "Helper function to cevalBuiltinMax."
3451 input Values.Value inValue;
3452 output Values.Value outValue;
3453 protected
3454 list<Values.Value> vals;
3455 algorithm
3456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 Values.ARRAY(valueLst = vals) := inValue;
3457
7/8
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 16 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
32 outValue := cevalBuiltinMax2(v for v in vals);
3458 end cevalBuiltinMaxArr;
3459
3460 protected function cevalBuiltinMin "author: PA
3461 Constant evaluation of builtin min function."
3462 input FCore.Cache inCache;
3463 input FCore.Graph inEnv;
3464 input list<DAE.Exp> inExpExpLst;
3465 input Boolean inBoolean;
3466 input Absyn.Msg inMsg;
3467 input Integer numIter;
3468 output FCore.Cache outCache;
3469 output Values.Value outValue;
3470 algorithm
3471 (outCache,outValue):=
3472 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3473 local
3474 Values.Value v,v1,v2,v_1;
3475 FCore.Graph env;
3476 DAE.Exp arr,s1,s2;
3477 Boolean impl;
3478 Absyn.Msg msg;
3479 FCore.Cache cache;
3480 case (cache, env, {arr}, impl, msg)
3481 algorithm
3482 4 (cache,v) := ceval(cache,env, arr, impl, msg,numIter+1);
3483 4 v_1 := cevalBuiltinMinArr(v);
3484 then
3485 (cache,v_1);
3486 case (cache, env, {s1,s2}, impl, msg)
3487 algorithm
3488 847 (cache,v1) := ceval(cache,env, s1, impl, msg,numIter+1);
3489 846 (cache,v2) := ceval(cache,env, s2, impl, msg,numIter+1);
3490 846 v := cevalBuiltinMin2(v1, v2);
3491 then
3492 (cache,v);
3493 end match;
3494 end cevalBuiltinMin;
3495
3496 protected function cevalBuiltinMin2
3497 input Values.Value v1;
3498 input Values.Value v2;
3499 output Values.Value outValue;
3500 algorithm
3501 outValue := match (v1, v2)
3502 local
3503 Integer i1, i2;
3504 Real r1, r2;
3505 Boolean b1, b2;
3506 String s1, s2;
3507
3508 6 case (Values.INTEGER(i1), Values.INTEGER(i2)) then Values.INTEGER(min(i1, i2));
3509 848 case (Values.REAL(r1), Values.REAL(r2)) then Values.REAL(min(r1, r2));
3510 ✗ case (Values.BOOL(b1), Values.BOOL(b2)) then Values.BOOL(b1 and b2);
3511 case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL())
3512 ✗ then if v1.index < v2.index then v1 else v2;
3513 else
3514 algorithm
3515 ✗ true := Flags.isSet(Flags.FAILTRACE);
3516 ✗ s1 := ValuesDump.valString(v1);
3517 ✗ s2 := ValuesDump.valString(v2);
3518 ✗ Debug.traceln("- Ceval.cevalBuiltinMin2 failed: min(" + s1 + ", " + s2 + ")");
3519 ✗ then
3520 fail();
3521
3522 end match;
3523 end cevalBuiltinMin2;
3524
3525 protected function cevalBuiltinMinArr "Helper function to cevalBuiltinMin."
3526 input Values.Value inValue;
3527 output Values.Value outValue;
3528 protected
3529 list<Values.Value> vals;
3530 algorithm
3531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 Values.ARRAY(valueLst = vals) := inValue;
3532
7/8
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
16 outValue := cevalBuiltinMin2(v for v in vals);
3533 end cevalBuiltinMinArr;
3534
3535 protected function cevalBuiltinRem "author: LP
3536 Evaluates the builtin rem operator"
3537 input FCore.Cache inCache;
3538 input FCore.Graph inEnv;
3539 input list<DAE.Exp> inExpExpLst;
3540 input Boolean inBoolean;
3541 input Absyn.Msg inMsg;
3542 input Integer numIter;
3543 output FCore.Cache outCache;
3544 output Values.Value outValue;
3545 algorithm
3546 (outCache,outValue):=
3547 matchcontinue (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3548 local
3549 Real rv1,rv2,rvd,dr;
3550 Integer ri,ri1,ri2,ri_1,di;
3551 FCore.Graph env;
3552 DAE.Exp exp1,exp2;
3553 Boolean impl;
3554 Absyn.Msg msg;
3555 String exp1_str,exp2_str;
3556 FCore.Cache cache;
3557 SourceInfo info;
3558
3559 case (cache, env, {exp1,exp2}, impl, msg)
3560 algorithm
3561 ✗ (cache,Values.REAL(rv1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3562 ✗ (cache,Values.REAL(rv2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3563 ✗ (cache,Values.REAL(dr)) := cevalBuiltinDiv(cache,env,{exp1,exp2},impl,msg,numIter+1);
3564 ✗ rvd := rv1 - rv2 * dr;
3565 ✗ then
3566 (cache,Values.REAL(rvd));
3567 case (cache, env, {exp1,exp2}, impl, msg)
3568 algorithm
3569 ✗ (cache,Values.INTEGER(ri)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3570 ✗ rv1 := intReal(ri);
3571 ✗ (cache,Values.REAL(rv2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3572 ✗ (cache,Values.REAL(dr)) := cevalBuiltinDiv(cache,env,{exp1,exp2},impl,msg,numIter+1);
3573 ✗ rvd := rv1 - rv2 * dr;
3574 ✗ then
3575 (cache,Values.REAL(rvd));
3576 case (cache, env, {exp1,exp2}, impl, msg)
3577 algorithm
3578 ✗ (cache,Values.REAL(rv1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3579 ✗ (cache,Values.INTEGER(ri)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3580 ✗ rv2 := intReal(ri);
3581 ✗ (cache,Values.REAL(dr)) := cevalBuiltinDiv(cache,env,{exp1,exp2},impl,msg,numIter+1);
3582 ✗ rvd := rv1 - rv2 * dr;
3583 ✗ then
3584 (cache,Values.REAL(rvd));
3585 case (cache, env, {exp1,exp2}, impl, msg)
3586 algorithm
3587 ✗ (cache,Values.INTEGER(ri1)) := ceval(cache,env, exp1, impl, msg,numIter+1);
3588 ✗ (cache,Values.INTEGER(ri2)) := ceval(cache,env, exp2, impl, msg,numIter+1);
3589 ✗ (cache,Values.INTEGER(di)) := cevalBuiltinDiv(cache,env,{exp1,exp2},impl,msg,numIter+1);
3590 ✗ ri_1 := ri1 - ri2 * di;
3591 ✗ then
3592 (cache,Values.INTEGER(ri_1));
3593 case (cache, env, {exp1,exp2}, impl, Absyn.MSG(info = info))
3594 algorithm
3595 ✗ (_,Values.REAL(rv2)) := ceval(cache,env,exp2,impl,inMsg,numIter+1);
3596 ✗ true := (rv2 == 0.0);
3597 ✗ exp1_str := ExpressionBasics.printExpStr(exp1);
3598 ✗ exp2_str := ExpressionBasics.printExpStr(exp2);
3599 ✗ Error.addSourceMessage(Error.REM_ARG_ZERO, {exp1_str,exp2_str}, info);
3600 ✗ then
3601 fail();
3602 case (cache, env, {exp1,exp2}, impl, Absyn.MSG(info = info))
3603 algorithm
3604 ✗ (_,Values.INTEGER(ri2)) := ceval(cache,env, exp2, impl, inMsg,numIter+1);
3605 ✗ true := (ri2 == 0);
3606 ✗ exp1_str := ExpressionBasics.printExpStr(exp1);
3607 ✗ exp2_str := ExpressionBasics.printExpStr(exp2);
3608 ✗ Error.addSourceMessage(Error.REM_ARG_ZERO, {exp1_str,exp2_str}, info);
3609 ✗ then
3610 fail();
3611 end matchcontinue;
3612 end cevalBuiltinRem;
3613
3614 protected function cevalBuiltinInteger "author: LP
3615 Evaluates the builtin integer operator"
3616 input FCore.Cache inCache;
3617 input FCore.Graph inEnv;
3618 input list<DAE.Exp> inExpExpLst;
3619 input Boolean inBoolean;
3620 input Absyn.Msg inMsg;
3621 input Integer numIter;
3622 output FCore.Cache outCache;
3623 output Values.Value outValue;
3624 algorithm
3625 (outCache,outValue):=
3626 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3627 local
3628 Real rv;
3629 Integer ri;
3630 FCore.Graph env;
3631 DAE.Exp exp;
3632 Boolean impl;
3633 Absyn.Msg msg;
3634 FCore.Cache cache;
3635 case (cache, env, {exp}, impl, msg)
3636 algorithm
3637
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1020 times.
1049 (cache,Values.REAL(rv)) := ceval(cache,env,exp,impl,msg,numIter+1);
3638 1020 ri := realInt(rv);
3639 1020 then
3640 (cache,Values.INTEGER(ri));
3641 end match;
3642 end cevalBuiltinInteger;
3643
3644 protected function cevalBuiltinBoolean " @author: adrpo
3645 Evaluates the builtin boolean operator"
3646 input FCore.Cache inCache;
3647 input FCore.Graph inEnv;
3648 input list<DAE.Exp> inExpExpLst;
3649 input Boolean inBoolean;
3650 input Absyn.Msg inMsg;
3651 input Integer numIter;
3652 output FCore.Cache outCache;
3653 output Values.Value outValue;
3654 algorithm
3655 (outCache,outValue):=
3656 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3657 local
3658 Real rv;
3659 Integer iv;
3660 Boolean bv;
3661 FCore.Graph env;
3662 DAE.Exp exp;
3663 Boolean impl;
3664 Absyn.Msg msg;
3665 FCore.Cache cache;
3666 Boolean b;
3667 Values.Value v;
3668
3669 // real/integer/bool -> bool
3670 case (cache, env, {exp}, impl, msg)
3671 algorithm
3672 ✗ (cache,v) := ceval(cache, env, exp, impl, msg, numIter+1);
3673 b := match v
3674 ✗ case Values.REAL(rv) then not realEq(rv, 0.0);
3675 ✗ case Values.INTEGER(iv) then not intEq(iv, 0);
3676 case Values.BOOL(bv) then bv;
3677 end match;
3678 ✗ then
3679 (cache,Values.BOOL(b));
3680
3681 end match;
3682 end cevalBuiltinBoolean;
3683
3684 protected function cevalBuiltinRooted
3685 "author: adrpo
3686 Evaluates the builtin rooted operator from MultiBody"
3687 input FCore.Cache inCache;
3688 input FCore.Graph inEnv;
3689 input list<DAE.Exp> inExpExpLst;
3690 input Boolean inBoolean;
3691 input Absyn.Msg inMsg;
3692 input Integer numIter;
3693 output FCore.Cache outCache;
3694 output Values.Value outValue;
3695 algorithm
3696 (outCache,outValue):=
3697 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3698 local
3699 FCore.Graph env;
3700 DAE.Exp exp;
3701 Boolean impl;
3702 Absyn.Msg msg;
3703 FCore.Cache cache;
3704 case (cache, env, {exp}, impl, msg)
3705 algorithm
3706 ✗ (cache,_) := ceval(cache,env,exp,impl,msg,numIter+1);
3707 then
3708 (cache,Values.BOOL(true));
3709 end match;
3710 end cevalBuiltinRooted;
3711
3712 protected function cevalBuiltinIntegerEnumeration "author: LP
3713 Evaluates the builtin Integer operator"
3714 input FCore.Cache inCache;
3715 input FCore.Graph inEnv;
3716 input list<DAE.Exp> inExpExpLst;
3717 input Boolean inBoolean;
3718 input Absyn.Msg inMsg;
3719 input Integer numIter;
3720 output FCore.Cache outCache;
3721 output Values.Value outValue;
3722 algorithm
3723 (outCache,outValue):=
3724 match (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3725 local
3726 Integer ri;
3727 FCore.Graph env;
3728 DAE.Exp exp;
3729 Boolean impl;
3730 Absyn.Msg msg;
3731 FCore.Cache cache;
3732 case (cache, env, {exp}, impl, msg)
3733 algorithm
3734
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 (cache,Values.ENUM_LITERAL(index = ri)) := ceval(cache,env,exp,impl,msg,numIter+1);
3735 1 then
3736 (cache,Values.INTEGER(ri));
3737 end match;
3738 end cevalBuiltinIntegerEnumeration;
3739
3740 protected function cevalBuiltinDiagonal "This function generates a matrix{n,n} (A) of the vector {a,b,...,n}
3741 where the diagonal of A is the vector {a,b,...,n}
3742 ie A{1,1} == a, A{2,2} == b ..."
3743 input FCore.Cache inCache;
3744 input FCore.Graph inEnv;
3745 input list<DAE.Exp> inExpExpLst;
3746 input Boolean inBoolean;
3747 input Absyn.Msg inMsg;
3748 input Integer numIter;
3749 output FCore.Cache outCache;
3750 output Values.Value outValue;
3751 algorithm
3752 (outCache,outValue):=
3753 matchcontinue (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3754 local
3755 list<Values.Value> vals;
3756 Integer dimension;
3757 FCore.Graph env;
3758 DAE.Exp exp;
3759 Boolean impl;
3760 Absyn.Msg msg;
3761 FCore.Cache cache;
3762 Values.Value res;
3763 SourceInfo info;
3764 Values.Value zero;
3765 DAE.Type ty;
3766
3767 case (cache, env, {exp}, impl, msg)
3768 algorithm
3769
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 135 times.
135 DAE.T_ARRAY(ty=ty) := Expression.typeof(exp);
3770
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 135 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 135 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 135 times.
135 (cache,Values.ARRAY(vals,{dimension})) := ceval(cache,env,exp,impl,msg,numIter+1);
3771 135 zero := ValuesMake.makeZero(ty);
3772
6/6
✓ Branch 0 taken 402 times.
✓ Branch 1 taken 135 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 402 times.
✓ Branch 4 taken 402 times.
✓ Branch 5 taken 804 times.
1878 res := Values.ARRAY(list(Values.ARRAY(list(if i==j then listGet(vals,i) else zero for i in 1:dimension),{dimension}) for j in 1:dimension), {dimension,dimension});
3773 then
3774 (cache,res);
3775 case (_, _, _, _, Absyn.MSG(info = info))
3776 algorithm
3777 ✗ Error.addSourceMessage(Error.COMPILER_ERROR,
3778 {"Could not evaluate diagonal. Ceval.cevalBuiltinDiagonal failed."}, info);
3779 ✗ then
3780 fail();
3781 end matchcontinue;
3782 end cevalBuiltinDiagonal;
3783
3784 protected function cevalBuiltinCross "
3785 x,y => {x[2]*y[3]-x[3]*y[2],x[3]*y[1]-x[1]*y[3],x[1]*y[2]-x[2]*y[1]}"
3786 input FCore.Cache inCache;
3787 input FCore.Graph inEnv;
3788 input list<DAE.Exp> inExpExpLst;
3789 input Boolean inBoolean;
3790 input Absyn.Msg inMsg;
3791 input Integer numIter;
3792 output FCore.Cache outCache;
3793 output Values.Value outValue;
3794 algorithm
3795 (outCache,outValue):=
3796 matchcontinue (inCache, inEnv, inExpExpLst, inBoolean, inMsg)
3797 local
3798 list<Values.Value> xv,yv;
3799 Values.Value res;
3800 FCore.Graph env;
3801 DAE.Exp xe,ye;
3802 Boolean impl;
3803 Absyn.Msg msg;
3804 FCore.Cache cache;
3805 String str;
3806 SourceInfo info;
3807
3808 case (cache, env, {xe,ye}, impl, msg)
3809 algorithm
3810
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
4 (cache,Values.ARRAY(xv,{3})) := ceval(cache,env,xe,impl,msg,numIter+1);
3811
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
4 (cache,Values.ARRAY(yv,{3})) := ceval(cache,env,ye,impl,msg,numIter+1);
3812 4 res := ValuesUtil.crossProduct(xv,yv);
3813 then
3814 (cache,res);
3815 case (_, _, _, _, Absyn.MSG(info = info))
3816 algorithm
3817 ✗ str := "cross" + ExpressionBasics.printExpStr(DAE.TUPLE(inExpExpLst));
3818 ✗ Error.addSourceMessage(Error.FAILED_TO_EVALUATE_EXPRESSION, {str}, info);
3819 ✗ then
3820 fail();
3821 end matchcontinue;
3822 end cevalBuiltinCross;
3823
3824 protected function cevalBuiltinTranspose2 "author: PA
3825 Helper function to cevalBuiltinTranspose"
3826 input list<Values.Value> inValuesValueLst1;
3827 input Integer inInteger2 "index";
3828 input list<Integer> inDims "dimension";
3829 output list<Values.Value> outValuesValueLst;
3830 algorithm
3831 outValuesValueLst:=
3832 matchcontinue (inValuesValueLst1,inInteger2,inDims)
3833 local
3834 list<Values.Value> transposed_row,rest,vlst;
3835 Integer indx_1,indx,dim1;
3836 case (vlst,indx,(dim1::_)) guard indx <= dim1
3837 algorithm
3838 3 transposed_row := List.map1(vlst, ValuesUtil.nthArrayelt, indx);
3839 3 indx_1 := indx + 1;
3840 3 rest := cevalBuiltinTranspose2(vlst, indx_1, inDims);
3841 3 then
3842 (Values.ARRAY(transposed_row,inDims) :: rest);
3843 else {};
3844 end matchcontinue;
3845 end cevalBuiltinTranspose2;
3846
3847 protected function cevalBuiltinSizeMatrix "Helper function for cevalBuiltinSize, for size(A) where A is a matrix."
3848 input FCore.Cache inCache;
3849 input FCore.Graph inEnv;
3850 input DAE.Exp inExp;
3851 input Boolean inBoolean;
3852 input Absyn.Msg inMsg;
3853 input Integer numIter;
3854 output FCore.Cache outCache;
3855 output Values.Value outValue;
3856 algorithm
3857 (outCache,outValue) :=
3858 matchcontinue (inCache, inEnv, inExp, inBoolean, inMsg)
3859 local
3860 DAE.Type tp;
3861 list<Integer> sizelst;
3862 Values.Value v;
3863 FCore.Graph env;
3864 DAE.ComponentRef cr;
3865 Boolean impl;
3866 Absyn.Msg msg;
3867 FCore.Cache cache;
3868 DAE.Exp exp;
3869 DAE.Dimensions dims;
3870
3871 // size(cr)
3872 case (cache, env, DAE.CREF(componentRef = cr), _, _)
3873 algorithm
3874 ✗ (cache,_,tp,_,_,_,_,_,_) := Lookup.lookupVar(cache,env, cr);
3875 ✗ sizelst := Types.getDimensionSizes(tp);
3876 ✗ v := ValuesUtil.intlistToValue(sizelst);
3877 then
3878 (cache,v);
3879
3880 // For matrix expressions: [1,2;3,4]
3881 case (cache, _, DAE.MATRIX(ty = DAE.T_ARRAY(dims = dims)), _, _)
3882 algorithm
3883 ✗ sizelst := List.map(dims, Expression.dimensionSize);
3884 ✗ v := ValuesUtil.intlistToValue(sizelst);
3885 then
3886 (cache, v);
3887
3888 // For other matrix expressions e.g. on array form: {{1,2},{3,4}}
3889 case (cache, env, exp, impl, msg)
3890 algorithm
3891 ✗ (cache,Values.ARRAY(dimLst=sizelst)) := ceval(cache,env, exp, impl, msg,numIter+1);
3892 ✗ v := ValuesUtil.intlistToValue(sizelst);
3893 then
3894 (cache,v);
3895 end matchcontinue;
3896 end cevalBuiltinSizeMatrix;
3897
3898 protected function cevalBuiltinFail
3899 "This function constant evaluates calls to the fail() function."
3900 input FCore.Cache inCache;
3901 input FCore.Graph inEnv;
3902 input list<DAE.Exp> inExpl;
3903 input Boolean inImpl;
3904 input Absyn.Msg inMsg;
3905 input Integer numIter;
3906 output FCore.Cache outCache;
3907 output Values.Value outValue;
3908 algorithm
3909 outCache := inCache;
3910 outValue := Values.META_FAIL();
3911 end cevalBuiltinFail;
3912
3913 protected function cevalBuiltinFill
3914 "This function constant evaluates calls to the fill function."
3915 input FCore.Cache inCache;
3916 input FCore.Graph inEnv;
3917 input list<DAE.Exp> inExpl;
3918 input Boolean inImpl;
3919 input Absyn.Msg inMsg;
3920 input Integer numIter;
3921 output FCore.Cache outCache;
3922 output Values.Value outValue;
3923 algorithm
3924 (outCache, outValue) :=
3925 match (inCache, inExpl)
3926 local
3927 DAE.Exp fill_exp;
3928 list<DAE.Exp> dims;
3929 Values.Value fill_val;
3930 FCore.Cache cache;
3931 case (cache, fill_exp :: dims)
3932 algorithm
3933 5 (cache, fill_val) := ceval(cache, inEnv, fill_exp, inImpl, inMsg, numIter+1);
3934 5 (cache, fill_val) := cevalBuiltinFill2(cache, inEnv, fill_val, dims, inImpl, inMsg, numIter);
3935 then
3936 (cache, fill_val);
3937 end match;
3938 end cevalBuiltinFill;
3939
3940 protected function cevalBuiltinFill2
3941 input FCore.Cache inCache;
3942 input FCore.Graph inEnv;
3943 input Values.Value inFillValue;
3944 input list<DAE.Exp> inDims;
3945 input Boolean inImpl;
3946 input Absyn.Msg inMsg;
3947 input Integer numIter;
3948 output FCore.Cache outCache;
3949 output Values.Value outValue;
3950 algorithm
3951 (outCache, outValue) :=
3952 match (inCache, inDims)
3953 local
3954 DAE.Exp dim;
3955 list<DAE.Exp> rest_dims;
3956 Integer int_dim;
3957 list<Integer> array_dims;
3958 Values.Value fill_value;
3959 list<Values.Value> fill_vals;
3960 FCore.Cache cache;
3961
3962 case (cache, {}) then (cache, inFillValue);
3963
3964 case (cache, dim :: rest_dims)
3965 algorithm
3966 7 (cache, fill_value) := cevalBuiltinFill2(cache, inEnv, inFillValue,
3967 rest_dims, inImpl, inMsg, numIter);
3968
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 (cache, Values.INTEGER(int_dim)) := ceval(cache, inEnv, dim, inImpl, inMsg, numIter+1);
3969 7 fill_vals := List.fill(fill_value, int_dim);
3970 7 array_dims := ValuesUtil.valueDimensions(fill_value);
3971 array_dims := int_dim :: array_dims;
3972 7 then
3973 (cache, Values.ARRAY(fill_vals, array_dims));
3974 end match;
3975 end cevalBuiltinFill2;
3976
3977 protected function cevalRelation
3978 "Performs the arithmetic relation check and gives a boolean result."
3979 input Values.Value inValue1;
3980 input DAE.Operator inOperator;
3981 input Values.Value inValue2;
3982 output Values.Value outValue;
3983 protected
3984 Boolean result;
3985 algorithm
3986 result := matchcontinue inOperator
3987 2544 case DAE.GREATER() then cevalRelationLess(inValue2, inValue1);
3988 4455 case DAE.LESS() then cevalRelationLess(inValue1, inValue2);
3989 592 case DAE.LESSEQ() then cevalRelationLessEq(inValue1, inValue2);
3990 1709 case DAE.GREATEREQ() then cevalRelationGreaterEq(inValue1, inValue2);
3991 15807 case DAE.EQUAL() then cevalRelationEqual(inValue1, inValue2);
3992 3228 case DAE.NEQUAL() then cevalRelationNotEqual(inValue1, inValue2);
3993
3994 else
3995 algorithm
3996 ✗ true := Flags.isSet(Flags.FAILTRACE);
3997 ✗ Debug.traceln("- Ceval.cevalRelation failed on: " +
3998 ValuesDump.printValStr(inValue1) +
3999 ExpressionDump.relopSymbol(inOperator) +
4000 ValuesDump.printValStr(inValue2));
4001 ✗ then
4002 fail();
4003 end matchcontinue;
4004
4005
2/2
✓ Branch 0 taken 16752 times.
✓ Branch 1 taken 11583 times.
45087 outValue := Values.BOOL(result);
4006 end cevalRelation;
4007
4008 protected function cevalRelationLess
4009 "Returns whether the first value is less than the second value."
4010 input Values.Value inValue1;
4011 input Values.Value inValue2;
4012 output Boolean result;
4013 algorithm
4014 result := match(inValue1, inValue2)
4015 ✗ case (Values.STRING(), Values.STRING()) then (stringCompare(inValue1.string, inValue2.string) < 0);
4016 ✗ case (Values.BOOL(), Values.BOOL()) then (inValue1.boolean < inValue2.boolean);
4017 119 case (Values.INTEGER(), Values.INTEGER()) then (inValue1.integer < inValue2.integer);
4018 6624 case (Values.REAL(), Values.REAL()) then (inValue1.real < inValue2.real);
4019 ✗ case (Values.INTEGER(), Values.REAL()) then (intReal(inValue1.integer) < inValue2.real);
4020 256 case (Values.REAL(), Values.INTEGER()) then (inValue1.real < intReal(inValue2.integer));
4021 ✗ case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL()) then (inValue1.index < inValue2.index);
4022 ✗ case (Values.ENUM_LITERAL(), Values.INTEGER()) then (inValue1.index < inValue2.integer);
4023 ✗ case (Values.INTEGER(), Values.ENUM_LITERAL()) then (inValue1.integer < inValue2.index);
4024 end match;
4025 end cevalRelationLess;
4026
4027 protected function cevalRelationLessEq
4028 "Returns whether the first value is less than or equal to the second value."
4029 input Values.Value inValue1;
4030 input Values.Value inValue2;
4031 output Boolean result;
4032 algorithm
4033 result := match(inValue1, inValue2)
4034 ✗ case (Values.STRING(), Values.STRING()) then (stringCompare(inValue1.string, inValue2.string) <= 0);
4035 ✗ case (Values.BOOL(), Values.BOOL()) then (inValue1.boolean <= inValue2.boolean);
4036 22 case (Values.INTEGER(), Values.INTEGER()) then (inValue1.integer <= inValue2.integer);
4037 570 case (Values.REAL(), Values.REAL()) then (inValue1.real <= inValue2.real);
4038 ✗ case (Values.INTEGER(), Values.REAL()) then (intReal(inValue1.integer) <= inValue2.real);
4039 ✗ case (Values.REAL(), Values.INTEGER()) then (inValue1.real <= intReal(inValue2.integer));
4040 ✗ case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL()) then (inValue1.index <= inValue2.index);
4041 ✗ case (Values.ENUM_LITERAL(), Values.INTEGER()) then (inValue1.index <= inValue2.integer);
4042 ✗ case (Values.INTEGER(), Values.ENUM_LITERAL()) then (inValue1.integer <= inValue2.index);
4043 end match;
4044 end cevalRelationLessEq;
4045
4046 protected function cevalRelationGreaterEq
4047 "Returns whether the first value is greater than or equal to the second value."
4048 input Values.Value inValue1;
4049 input Values.Value inValue2;
4050 output Boolean result;
4051 algorithm
4052 result := match(inValue1, inValue2)
4053 ✗ case (Values.STRING(), Values.STRING()) then (stringCompare(inValue1.string, inValue2.string) >= 0);
4054 ✗ case (Values.BOOL(), Values.BOOL()) then (inValue1.boolean >= inValue2.boolean);
4055 17 case (Values.INTEGER(), Values.INTEGER()) then (inValue1.integer >= inValue2.integer);
4056 1677 case (Values.REAL(), Values.REAL()) then (inValue1.real >= inValue2.real);
4057 ✗ case (Values.INTEGER(), Values.REAL()) then (intReal(inValue1.integer) >= inValue2.real);
4058 ✗ case (Values.REAL(), Values.INTEGER()) then (inValue1.real >= intReal(inValue2.integer));
4059 15 case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL()) then (inValue1.index >= inValue2.index);
4060 ✗ case (Values.ENUM_LITERAL(), Values.INTEGER()) then (inValue1.index >= inValue2.integer);
4061 ✗ case (Values.INTEGER(), Values.ENUM_LITERAL()) then (inValue1.integer >= inValue2.index);
4062 end match;
4063 end cevalRelationGreaterEq;
4064
4065 protected function cevalRelationEqual
4066 "Returns whether the first value is equal to the second value."
4067 input Values.Value inValue1;
4068 input Values.Value inValue2;
4069 output Boolean result;
4070 algorithm
4071 result := match(inValue1, inValue2)
4072 706 case (Values.STRING(), Values.STRING()) then (stringCompare(inValue1.string, inValue2.string) == 0);
4073 ✗ case (Values.BOOL(), Values.BOOL()) then (inValue1.boolean == inValue2.boolean);
4074 12523 case (Values.INTEGER(), Values.INTEGER()) then (inValue1.integer == inValue2.integer);
4075 46 case (Values.REAL(), Values.REAL()) then (inValue1.real == inValue2.real);
4076 ✗ case (Values.INTEGER(), Values.REAL()) then (intReal(inValue1.integer) == inValue2.real);
4077 ✗ case (Values.REAL(), Values.INTEGER()) then (inValue1.real == intReal(inValue2.integer));
4078 2532 case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL()) then (inValue1.index == inValue2.index);
4079 ✗ case (Values.ENUM_LITERAL(), Values.INTEGER()) then (inValue1.index == inValue2.integer);
4080 ✗ case (Values.INTEGER(), Values.ENUM_LITERAL()) then (inValue1.integer == inValue2.index);
4081 end match;
4082 end cevalRelationEqual;
4083
4084 protected function cevalRelationNotEqual
4085 "Returns whether the first value is not equal to the second value."
4086 input Values.Value inValue1;
4087 input Values.Value inValue2;
4088 output Boolean result;
4089 algorithm
4090 result := match(inValue1, inValue2)
4091 985 case (Values.STRING(), Values.STRING()) then (stringCompare(inValue1.string, inValue2.string) <> 0);
4092 ✗ case (Values.BOOL(), Values.BOOL()) then (inValue1.boolean <> inValue2.boolean);
4093 1817 case (Values.INTEGER(), Values.INTEGER()) then (inValue1.integer <> inValue2.integer);
4094 4 case (Values.REAL(), Values.REAL()) then (inValue1.real <> inValue2.real);
4095 ✗ case (Values.INTEGER(), Values.REAL()) then (intReal(inValue1.integer) <> inValue2.real);
4096 ✗ case (Values.REAL(), Values.INTEGER()) then (inValue1.real <> intReal(inValue2.integer));
4097 422 case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL()) then (inValue1.index <> inValue2.index);
4098 ✗ case (Values.ENUM_LITERAL(), Values.INTEGER()) then (inValue1.index <> inValue2.integer);
4099 ✗ case (Values.INTEGER(), Values.ENUM_LITERAL()) then (inValue1.integer <> inValue2.index);
4100 end match;
4101 end cevalRelationNotEqual;
4102
4103 function cevalRange
4104 input FCore.Cache cache;
4105 input FCore.Graph env;
4106 input DAE.Exp rangeExp;
4107 input Boolean impl;
4108 input Absyn.Msg msg;
4109 input Integer numIter;
4110 output FCore.Cache outCache;
4111 output Values.Value outValue;
4112 protected
4113 DAE.Exp start;
4114 Option<DAE.Exp> step;
4115 DAE.Exp stop;
4116 DAE.Type range_ty;
4117 Values.Value vstart, vstop;
4118 Integer istep;
4119 Real rstep;
4120 list<Values.Value> arr;
4121 algorithm
4122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2808 times.
2808 DAE.RANGE(ty = range_ty, start = start, step = step, stop = stop) := rangeExp;
4123 2808 (outCache, vstart) := ceval(cache, env, start, impl, msg, numIter + 1);
4124 2798 (outCache, vstop) := ceval(outCache, env, stop, impl, msg, numIter + 1);
4125
4126 arr := match (vstart, vstop)
4127 case (Values.BOOL(), Values.BOOL())
4128
4/4
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 5 times.
11 then list(ValuesMake.makeBoolean(b) for b in
4129 ExpressionSimplify.simplifyRangeBool(vstart.boolean, vstop.boolean));
4130
4131 case (Values.INTEGER(), Values.INTEGER())
4132 algorithm
4133
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2764 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 2743 times.
2764 if isSome(step) then
4134
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
21 (outCache, Values.INTEGER(istep)) := ceval(outCache, env, Util.getOption(step), impl, msg, numIter + 1);
4135 else
4136 istep := 1;
4137 end if;
4138
4/4
✓ Branch 1 taken 15597 times.
✓ Branch 2 taken 2764 times.
✓ Branch 3 taken 15597 times.
✓ Branch 4 taken 2764 times.
18361 then
4139 list(ValuesMake.makeInteger(i) for i in
4140 ExpressionSimplify.simplifyRange(vstart.integer, istep, vstop.integer));
4141
4142 case (Values.ENUM_LITERAL(), Values.ENUM_LITERAL())
4143 8 then cevalRangeEnum(vstart.index, vstop.index, Types.arrayElementType(range_ty));
4144
4145 case (Values.REAL(), Values.REAL())
4146 algorithm
4147
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
5 if isSome(step) then
4148
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 (outCache, Values.REAL(rstep)) := ceval(outCache, env, Util.getOption(step), impl, msg, numIter + 1);
4149 else
4150 rstep := 1.0;
4151 end if;
4152
4/4
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 107 times.
✓ Branch 4 taken 5 times.
112 then
4153 list(ValuesMake.makeReal(r) for r in
4154 ExpressionSimplify.simplifyRangeReal(vstart.real, rstep, vstop.real));
4155
4156 end match;
4157
4158 2782 outValue := ValuesMake.makeArray(arr);
4159 end cevalRange;
4160
4161 public function cevalRangeEnum
4162 "Evaluates a range expression on the form enum.lit1 : enum.lit2"
4163 input Integer startIndex;
4164 input Integer stopIndex;
4165 input DAE.Type enumType;
4166 output list<Values.Value> enumValList;
4167 algorithm
4168 enumValList := match enumType
4169 local
4170 Absyn.Path enum_type;
4171 list<String> enum_names;
4172 list<Absyn.Path> enum_paths;
4173 list<Values.Value> enum_values;
4174 case DAE.T_ENUMERATION(path = enum_type, names = enum_names) guard startIndex <= stopIndex
4175 algorithm
4176 8 enum_names := List.sublist(enum_names, startIndex, (stopIndex - startIndex) + 1);
4177 8 enum_paths := List.map(enum_names, AbsynUtil.makeIdentPathFromString);
4178 8 enum_paths := List.map1r(enum_paths, AbsynUtil.joinPaths, enum_type);
4179 8 (enum_values, _) := List.mapFold(enum_paths, makeEnumValue, startIndex);
4180 then
4181 enum_values;
4182 end match;
4183 end cevalRangeEnum;
4184
4185 protected function makeEnumValue
4186 input Absyn.Path name;
4187 input Integer index;
4188 output Values.Value enumValue;
4189 output Integer newIndex;
4190 algorithm
4191 22 enumValue := Values.ENUM_LITERAL(name, index);
4192
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 newIndex := index + 1;
4193 end makeEnumValue;
4194
4195 public function cevalList "This function does constant
4196 evaluation on a list of expressions."
4197 input FCore.Cache inCache;
4198 input FCore.Graph inEnv;
4199 input list<DAE.Exp> inExpExpLst;
4200 input Boolean inBoolean;
4201 input Absyn.Msg inMsg;
4202 input Integer numIter;
4203 output FCore.Cache outCache = inCache;
4204 output list<Values.Value> outValuesValueLst = {};
4205 protected
4206 list<DAE.Exp> expLstNew = inExpExpLst;
4207 Values.Value v;
4208 algorithm
4209
2/2
✓ Branch 0 taken 2065985 times.
✓ Branch 1 taken 518013 times.
2583998 for exp in expLstNew loop
4210 2065985 (outCache, v) := ceval(outCache, inEnv, exp, inBoolean, inMsg, numIter+1);
4211 2064719 outValuesValueLst := v :: outValuesValueLst;
4212 end for;
4213 518013 outValuesValueLst := listReverseInPlace(outValuesValueLst);
4214 end cevalList;
4215
4216 public function cevalCref "Evaluates ComponentRef, i.e. variables, by
4217 looking up variables in the environment."
4218 input FCore.Cache inCache;
4219 input FCore.Graph inEnv;
4220 input DAE.ComponentRef inComponentRef;
4221 input Boolean inBoolean "impl";
4222 input Absyn.Msg inMsg;
4223 input Integer numIter;
4224 output FCore.Cache outCache;
4225 output Values.Value outValue;
4226 algorithm
4227 (outCache,outValue) :=
4228 matchcontinue (inCache, inEnv, inComponentRef, inBoolean, inMsg)
4229 local
4230 DAE.Binding binding;
4231 Values.Value v;
4232 FCore.Graph env, classEnv, componentEnv;
4233 DAE.ComponentRef c;
4234 Boolean impl;
4235 Absyn.Msg msg;
4236 String scope_str,str, name;
4237 FCore.Cache cache;
4238 Option<DAE.Const> const_for_range;
4239 DAE.Type ty;
4240 DAE.Attributes attr;
4241 InstTypes.SplicedExpData splicedExpData;
4242 SourceInfo info;
4243
4244 // Try to lookup the variables binding and constant evaluate it.
4245 case (cache, env, c, impl, msg)
4246 algorithm
4247 462567 (cache,attr,ty,binding,const_for_range,splicedExpData,classEnv,componentEnv,name) := Lookup.lookupVar(cache, env, c);
4248 // send the entire shebang to cevalCref2 so we don't have to do lookup var again!
4249 453521 (cache, v) := cevalCref_dispatch(cache, env, c, attr, ty, binding, const_for_range, splicedExpData, classEnv, componentEnv, name, impl,msg,numIter);
4250 then
4251 (cache, v);
4252
4253 // failure in lookup and we have the MSG go-ahead to print the error
4254 case (cache, env, c, (false), Absyn.MSG(info = info))
4255 algorithm
4256
2/2
✓ Branch 0 taken 2942 times.
✓ Branch 1 taken 76 times.
3018 failure(Lookup.lookupVar(cache,env, c));
4257 76 scope_str := FGraph.printGraphPathStr(env);
4258 76 str := ComponentReferenceBasics.printComponentRefStr(c);
4259 76 Error.addSourceMessage(Error.LOOKUP_VARIABLE_ERROR, {str,scope_str}, info);
4260 76 then
4261 fail();
4262
4263 // failure in lookup but NO_MSG, silently fail and move along
4264 /*case (cache,env,c,(impl as false),Absyn.NO_MSG(),_)
4265 algorithm
4266 failure((_,_,_,_,_,_,_,_,_) = Lookup.lookupVar(cache,env, c));
4267 then
4268 fail();*/
4269 end matchcontinue;
4270 end cevalCref;
4271
4272 public function cevalCref_dispatch
4273 "Helper function to cevalCref"
4274 input FCore.Cache inCache;
4275 input FCore.Graph inEnv;
4276 input DAE.ComponentRef inCref;
4277 input DAE.Attributes inAttr;
4278 input DAE.Type inType;
4279 input DAE.Binding inBinding;
4280 input Option<DAE.Const> constForRange;
4281 input InstTypes.SplicedExpData inSplicedExpData;
4282 input FCore.Graph inClassEnv;
4283 input FCore.Graph inComponentEnv;
4284 input String inFQName;
4285 input Boolean inImpl;
4286 input Absyn.Msg inMsg;
4287 input Integer numIter;
4288 output FCore.Cache outCache;
4289 output Values.Value outValue;
4290 algorithm
4291 (outCache, outValue) := match (inAttr, inBinding, constForRange, inImpl, inMsg)
4292 local
4293 FCore.Cache cache;
4294 Values.Value v;
4295 String str, scope_str, s1, s2, s3;
4296 SCode.Variability variability;
4297
4298 // A variable with no binding and SOME for range constness -> a for iterator
4299 3638 case (_, DAE.UNBOUND(), SOME(_), _, _) then fail();
4300
4301 // A variable without a binding -> error in a simulation model
4302 // and we can only check that at the DAE level!
4303 case (_, DAE.UNBOUND(), NONE(), false, Absyn.MSG())
4304 algorithm
4305 1371 str := ComponentReferenceBasics.printComponentRefStr(inCref);
4306 1371 scope_str := FGraph.printGraphPathStr(inEnv);
4307 // Error.addSourceMessage(Error.NO_CONSTANT_BINDING, {str, scope_str}, info);
4308
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1371 times.
1371 if Flags.isSet(Flags.CEVAL) then
4309 ✗ Debug.traceln("- Ceval.cevalCref on: " + str + " failed with no constant binding in scope: " + scope_str);
4310 end if;
4311 // build a default binding for it!
4312 1371 s1 := FGraph.printGraphPathStr(inEnv);
4313 1371 s2 := ComponentReferenceBasics.printComponentRefStr(inCref);
4314 1371 s3 := TypesDump.printTypeStr(inType);
4315 1371 v := Types.typeToValue(inType);
4316 1371 v := Values.EMPTY(s1, s2, v, s3);
4317 // i would really like to have SourceInfo to put in Values.EMPTY here!
4318 // to easier report errors later on and also to have DAE.ComponentRef and DAE.Type
4319 // but unfortunately DAE depends on Values and they should probably be merged !
4320 // Actually, at a second thought we SHOULD NOT HAVE VALUES AT ALL, WE SHOULD HAVE
4321 // JUST ONE DAE.Exp.CONSTANT_EXPRESSION(exp, constantness, type)!
4322 then
4323 (inCache, v);
4324
4325 // A variable with a binding -> constant evaluate the binding
4326 case (DAE.ATTR(variability=variability), _, _, _, _)
4327 algorithm
4328 // We might try to ceval variables in reduction scope... but it can't be helped since we do things in a ***** way in Inst/Static
4329
6/6
✓ Branch 1 taken 392584 times.
✓ Branch 2 taken 55928 times.
✓ Branch 3 taken 1797 times.
✓ Branch 4 taken 390787 times.
✓ Branch 6 taken 1026 times.
✓ Branch 7 taken 771 times.
448512 true := SCodeUtil.isParameterOrConst(variability) or inImpl or FGraph.inForLoopScope(inEnv);
4330
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 447486 times.
447486 false := crefEqualValue(inCref, inBinding);
4331 447486 (cache, v) := cevalCrefBinding(inCache, inEnv, inCref, inBinding, inImpl, inMsg, numIter);
4332 // print("Eval cref: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\n in scope " + FGraph.printGraphPathStr(inEnv) + "\n");
4333 446532 cache := FCore.addEvaluatedCref(cache,variability,ComponentReferenceBasics.crefStripLastSubs(inCref));
4334 446532 then
4335 (cache, v);
4336 end match;
4337 end cevalCref_dispatch;
4338
4339 public function cevalCrefBinding "Helper function to cevalCref.
4340 Evaluates variables by evaluating their bindings."
4341 input FCore.Cache inCache;
4342 input FCore.Graph inEnv;
4343 input DAE.ComponentRef inComponentRef;
4344 input DAE.Binding inBinding;
4345 input Boolean inBoolean "impl";
4346 input Absyn.Msg inMsg;
4347 input Integer numIter;
4348 output FCore.Cache outCache;
4349 output Values.Value outValue;
4350 algorithm
4351 (outCache,outValue) := matchcontinue (inCache, inEnv, inComponentRef, inBinding, inBoolean, inMsg)
4352 local
4353 DAE.ComponentRef cr,e1;
4354 list<DAE.Subscript> subsc;
4355 Values.Value res,v,e_val;
4356 FCore.Graph env;
4357 Boolean impl;
4358 Absyn.Msg msg;
4359 String expstr,s1,s2,str;
4360 DAE.Exp exp;
4361 FCore.Cache cache;
4362 list<DAE.Var> vl;
4363 Absyn.Path tpath;
4364 DAE.Type ty;
4365 SourceInfo info;
4366 DAE.Binding binding;
4367
4368 /*
4369 case (cache,env,cr,_,impl,msg)
4370 algorithm
4371 print("Ceval: " +
4372 ComponentReferenceBasics.printComponentRefStr(cr) + " | " +
4373 FGraph.printGraphPathStr(env) + " | " +
4374 DAEUtil.printBindingExpStr(inBinding) +
4375 "\n");
4376 then
4377 fail();*/
4378
4379 case (cache, env, cr, DAE.VALBOUND(valBound = v), impl, msg)
4380 algorithm
4381 411680 subsc := ComponentReference.crefLastSubs(cr);
4382 411680 (cache,res) := cevalSubscriptValue(cache, env, subsc, v, impl,msg,numIter+1);
4383 then
4384 (cache,res);
4385
4386 // take the bindings form the cref type if is a record that has bindings for everything!
4387 case (cache, env, DAE.CREF_IDENT(_, ty, {}), DAE.UNBOUND(), _, Absyn.MSG(info))
4388 algorithm
4389
4/4
✓ Branch 1 taken 1394 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
1406 DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path = tpath),
4390 varLst = vl) := Types.arrayElementType(ty);
4391
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 true := Types.allHaveBindings(vl);
4392 ✗ binding := InstBinding.makeRecordBinding(cache, env, tpath, ty, vl, {}, info);
4393 ✗ (cache, res) := cevalCrefBinding(cache, env, inComponentRef, binding, inBoolean, inMsg, numIter+1);
4394 then
4395 (cache, res);
4396
4397 case (_, _, _, DAE.UNBOUND(), (false), Absyn.MSG(_)) then fail();
4398
4399 case (_, _, _, DAE.UNBOUND(), (true), Absyn.MSG(_))
4400 algorithm
4401
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 true := Flags.isSet(Flags.CEVAL);
4402 ✗ Debug.trace("#- Ceval.cevalCrefBinding: Ignoring unbound when implicit\n");
4403 ✗ then
4404 fail();
4405
4406 // REDUCTION bindings
4407 case (cache, env, cr, DAE.EQBOUND(exp = exp,constant_ = DAE.C_CONST()), impl, msg)
4408 algorithm
4409
1/8
✓ Branch 0 taken 61109 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
61109 DAE.REDUCTION(reductionInfo=DAE.REDUCTIONINFO(path = Absyn.IDENT()), iterators = {DAE.REDUCTIONITER()}) := exp;
4410 ✗ (cache,v) := ceval(cache, env, exp, impl,msg,numIter+1);
4411 ✗ subsc := ComponentReference.crefLastSubs(cr);
4412 ✗ (cache,res) := cevalSubscriptValue(cache, env, subsc, v, impl,msg,numIter+1);
4413 then
4414 (cache,res);
4415
4416 // arbitrary expressions, value exists.
4417 case (cache, env, cr, DAE.EQBOUND(evaluatedExp = SOME(e_val)), impl, msg)
4418 algorithm
4419 90051 subsc := ComponentReference.crefLastSubs(cr);
4420 90051 (cache,res) := cevalSubscriptValue(cache,env, subsc, e_val, impl,msg,numIter+1);
4421 then
4422 (cache,res);
4423
4424 // arbitrary expressions. When binding has optional value.
4425 case (cache, env, cr, DAE.EQBOUND(exp = exp,constant_ = DAE.C_CONST()), impl, msg)
4426 algorithm
4427 684 (cache,v) := ceval(cache, env, exp, impl, msg, numIter+1);
4428 678 subsc := ComponentReference.crefLastSubs(cr);
4429 678 (cache,res) := cevalSubscriptValue(cache,env, subsc, v, impl,msg,numIter+1);
4430 then
4431 (cache,res);
4432
4433 // arbitrary expressions. When binding has optional value.
4434 case (cache, env, cr, DAE.EQBOUND(exp = exp,constant_ = DAE.C_PARAM()), impl, msg)
4435 algorithm
4436 // TODO: Ugly hack to prevent infinite recursion. If we have a binding r = r that
4437 // can for instance come from a modifier, this can cause an infinite loop here if r has no value.
4438
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 61 times.
65 false := isRecursiveBinding(cr,exp);
4439
4440 61 (cache,v) := ceval(cache, env, exp, impl, msg, numIter+1);
4441 1 subsc := ComponentReference.crefLastSubs(cr);
4442 1 (cache,res) := cevalSubscriptValue(cache, env, subsc, v, impl,msg,numIter+1);
4443 then
4444 (cache,res);
4445
4446 // if the binding has constant-ness DAE.C_VAR we cannot constant evaluate.
4447 case (_, _, _, DAE.EQBOUND(exp = exp,constant_ = DAE.C_VAR()), _, Absyn.MSG(_))
4448 algorithm
4449
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 true := Flags.isSet(Flags.CEVAL);
4450 ✗ Debug.trace("#- Ceval.cevalCrefBinding failed (nonconstant EQBOUND(");
4451 ✗ expstr := ExpressionBasics.printExpStr(exp);
4452 ✗ Debug.trace(expstr);
4453 ✗ Debug.traceln("))");
4454 ✗ then
4455 fail();
4456
4457 case (_, env, e1, _, _, _)
4458 algorithm
4459
1/2
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 true := Flags.isSet(Flags.CEVAL);
4460 ✗ s1 := ComponentReferenceBasics.printComponentRefStr(e1);
4461 ✗ s2 := TypesDump.printBindingStr(inBinding);
4462 ✗ str := FGraph.printGraphPathStr(env);
4463 ✗ str := stringAppendList({"- Ceval.cevalCrefBinding: ",
4464 s1, " = [", s2, "] in env:", str, " failed"});
4465 ✗ Debug.traceln(str);
4466 //print("ENV: " + FGraph.printGraphStr(inEnv) + "\n");
4467 ✗ then
4468 fail();
4469 end matchcontinue;
4470 end cevalCrefBinding;
4471
4472 protected function isRecursiveBinding " help function to cevalCrefBinding"
4473 input DAE.ComponentRef cr;
4474 input DAE.Exp exp;
4475 output Boolean res;
4476 algorithm
4477 res := matchcontinue exp
4478 case _ algorithm
4479 65 res := List.any(Expression.extractCrefsFromExp(exp), function ComponentReferenceBasics.crefEqual(inComponentRef2 = cr));
4480 then res;
4481 else false;
4482 end matchcontinue;
4483 end isRecursiveBinding;
4484
4485
4486 public function cevalSubscriptValue "Helper function to cevalCrefBinding. It applies
4487 subscripts to array values to extract array elements."
4488 input FCore.Cache inCache;
4489 input FCore.Graph inEnv;
4490 input list<DAE.Subscript> inExpSubscriptLst "subscripts to extract";
4491 input Values.Value inValue;
4492 input Boolean inBoolean "impl";
4493 input Absyn.Msg inMsg;
4494 input Integer numIter;
4495 output FCore.Cache outCache;
4496 output Values.Value outValue;
4497 algorithm
4498 (outCache,outValue) := match (inCache, inEnv, inExpSubscriptLst, inValue, inBoolean, inMsg)
4499 local
4500 Integer n;
4501 Values.Value subval,res,v;
4502 FCore.Graph env;
4503 DAE.Exp exp;
4504 list<DAE.Subscript> subs;
4505 list<Values.Value> lst,sliceLst,subvals;
4506 list<Integer> slice;
4507 Boolean impl;
4508 Absyn.Msg msg;
4509 FCore.Cache cache;
4510
4511 // we have a subscript which is an index or an enumeration literal scalar, try to constant evaluate it
4512 case (cache, env, (DAE.INDEX(exp = exp) :: subs), Values.ARRAY(valueLst = lst), impl, msg)
4513 algorithm
4514 268742 (cache,v) := ceval(cache, env, exp, impl, msg,numIter+1);
4515 n := match v
4516 case Values.INTEGER(n) then n;
4517 case Values.ENUM_LITERAL(index = n) then n;
4518 end match;
4519 268066 subval := listGet(lst, n);
4520 268066 (cache,res) := cevalSubscriptValue(cache, env, subs, subval, impl,msg,numIter+1);
4521 then
4522 (cache,res);
4523
4524 // slices
4525 case (cache, env, (DAE.SLICE(exp = exp) :: subs), Values.ARRAY(valueLst = lst), impl, msg)
4526 algorithm
4527
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 (cache,Values.ARRAY(valueLst = sliceLst)) := ceval(cache, env, exp, impl,msg,numIter+1);
4528 10 slice := List.map(sliceLst, ValuesUtil.valueInteger);
4529 10 subvals := List.map1r(slice, listGet, lst);
4530 10 (cache,lst) := cevalSubscriptValueList(cache,env, subs, subvals, impl,msg,numIter);
4531 10 res := ValuesMake.makeArray(lst);
4532 then
4533 (cache,res);
4534
4535 // we have a wholedim, apply the rest of the subscripts to each element of the array.
4536 case (cache, env, (DAE.WHOLEDIM() :: subs), subval as Values.ARRAY(), impl, msg)
4537 algorithm
4538 ✗ if listEmpty(subs) then
4539 // If the wholedim is the last subscript we can just return the value as it is.
4540 res := subval;
4541 else
4542 ✗ (cache,lst) := cevalSubscriptValueList(cache, env, subs, subval.valueLst, impl, msg, numIter+1);
4543 ✗ res := ValuesMake.makeArray(lst);
4544 end if;
4545 then
4546 (cache, res);
4547
4548 // we have no subscripts but we have a value, return it
4549 case (cache, _, {}, v, _, _) then (cache,v);
4550
4551 /*// failtrace
4552 case (cache, env, subs, inValue, dims, _, _, _)
4553 algorithm
4554 true = Flags.isSet(Flags.FAILTRACE);
4555 Debug.traceln("- Ceval.cevalSubscriptValue failed on:" +
4556 "\n env: " + FGraph.printGraphPathStr(env) +
4557 "\n subs: " + stringDelimitList(List.map(subs, ExpressionBasics.printSubscriptStr), ", ") +
4558 "\n value: " + ValuesDump.printValStr(inValue) +
4559 "\n dim sizes: " + stringDelimitList(List.map(dims, intString), ", ")
4560 );
4561 then
4562 fail();*/
4563 end match;
4564 end cevalSubscriptValue;
4565
4566 protected function cevalSubscriptValueList "Applies subscripts to array values to extract array elements."
4567 input FCore.Cache inCache;
4568 input FCore.Graph inEnv;
4569 input list<DAE.Subscript> inExpSubscriptLst "subscripts to extract";
4570 input list<Values.Value> inValue;
4571 input Boolean inBoolean "impl";
4572 input Absyn.Msg inMsg;
4573 input Integer numIter;
4574 output FCore.Cache outCache;
4575 output list<Values.Value> outValue;
4576 algorithm
4577 (outCache,outValue) :=
4578 match (inCache, inEnv, inExpSubscriptLst, inValue, inBoolean, inMsg)
4579 local
4580 Values.Value subval,res;
4581 FCore.Graph env;
4582 list<Values.Value> lst,subvals;
4583 Boolean impl;
4584 Absyn.Msg msg;
4585 list<DAE.Subscript> subs;
4586 FCore.Cache cache;
4587 case (cache, _, _, {}, _, _) then (cache,{});
4588 case (cache, env, subs, subval::subvals, impl, msg)
4589 algorithm
4590 53 (cache,res) := cevalSubscriptValue(cache,env, subs, subval, impl,msg,numIter+1);
4591 53 (cache,lst) := cevalSubscriptValueList(cache,env, subs, subvals, impl,msg,numIter);
4592 53 then
4593 (cache,res::lst);
4594 end match;
4595 end cevalSubscriptValueList;
4596
4597 public function cevalSubscripts "This function relates a list of subscripts to their canonical
4598 forms, which is when all expressions are evaluated to constant
4599 values. For instance
4600 the subscript list {1,p,q} (as in x[1,p,q]) where p and q have constant values 2,3 respectively will become
4601 {1,2,3} (resulting in x[1,2,3]).
4602 adrpo: do not fail if you cannot evaluate one, just move to the next one!"
4603 input FCore.Cache inCache;
4604 input FCore.Graph inEnv;
4605 input list<DAE.Subscript> inExpSubscriptLst;
4606 input list<Integer> inIntegerLst;
4607 input Boolean inBoolean "impl";
4608 input Absyn.Msg inMsg;
4609 input Integer numIter;
4610 output FCore.Cache outCache;
4611 output list<DAE.Subscript> outExpSubscriptLst;
4612 algorithm
4613 (outCache,outExpSubscriptLst) :=
4614 matchcontinue (inCache, inEnv, inExpSubscriptLst, inIntegerLst, inBoolean, inMsg)
4615 local
4616 DAE.Subscript sub_1,sub;
4617 list<DAE.Subscript> subs_1,subs;
4618 FCore.Graph env;
4619 Integer dim;
4620 list<Integer> dims;
4621 Boolean impl;
4622 Absyn.Msg msg;
4623 FCore.Cache cache;
4624
4625 // empty case
4626 case (cache, _, {}, _, _, _) then (cache,{});
4627
4628 // we have subscripts and we can evaluate the first
4629 case (cache, env, (sub :: subs), (dim :: dims), impl, msg)
4630 algorithm
4631 6998 (cache,sub_1) := cevalSubscript(cache, env, sub, dim, impl,msg,numIter+1);
4632 6864 (cache,subs_1) := cevalSubscripts(cache, env, subs, dims, impl,msg,numIter);
4633 6864 then
4634 (cache,sub_1 :: subs_1);
4635
4636 // we have subscripts and we CANNOT evaluate the first, move to next
4637 case (cache, env, (sub :: subs), (dim :: dims), impl, msg)
4638 algorithm
4639
2/2
✓ Branch 0 taken 134 times.
✓ Branch 1 taken 134 times.
268 failure(cevalSubscript(cache, env, sub, dim, impl,msg,numIter+1));
4640 134 (cache,subs_1) := cevalSubscripts(cache, env, subs, dims, impl,msg,numIter);
4641 134 then
4642 (cache,sub :: subs_1);
4643 end matchcontinue;
4644 end cevalSubscripts;
4645
4646 public function cevalSubscript "This function relates a subscript to its canonical forms, which
4647 is when all expressions are evaluated to constant values."
4648 input FCore.Cache inCache;
4649 input FCore.Graph inEnv;
4650 input DAE.Subscript inSubscript;
4651 input Integer inInteger;
4652 input Boolean inBoolean "impl";
4653 input Absyn.Msg inMsg;
4654 input Integer numIter;
4655 output FCore.Cache outCache;
4656 output DAE.Subscript outSubscript;
4657 algorithm
4658 (outCache,outSubscript) :=
4659 matchcontinue (inCache, inEnv, inSubscript, inBoolean, inMsg)
4660 local
4661 FCore.Graph env;
4662 Values.Value v1;
4663 DAE.Exp e1_1,e1;
4664 Boolean impl;
4665 Absyn.Msg msg;
4666 FCore.Cache cache;
4667
4668 // the entire dimension, nothing to do
4669 case (cache, _, DAE.WHOLEDIM(), _, _) then (cache,DAE.WHOLEDIM());
4670
4671 // An enumeration literal is already constant
4672 case (cache, _, DAE.INDEX(exp = DAE.ENUM_LITERAL()), _, _)
4673 then (cache, inSubscript);
4674
4675 // an expression index that can be constant evaluated, indexing using enum or bool
4676 case (cache, env, DAE.INDEX(exp = e1), impl, msg)
4677 algorithm
4678 84140 (cache,v1) := ceval(cache, env, e1, impl, msg, numIter+1);
4679 e1_1 := match v1
4680 83855 case Values.INTEGER(_) then ValuesUtil.valueExp(v1);
4681 39 case Values.ENUM_LITERAL() then ValuesUtil.valueExp(v1);
4682 ✗ case Values.BOOL(_) then ValuesUtil.valueExp(v1);
4683 end match;
4684 83894 then
4685 (cache,DAE.INDEX(e1_1));
4686
4687 // an expression slice that can be constant evaluated
4688 case (cache, env, DAE.SLICE(exp = e1), impl, msg)
4689 algorithm
4690 992 (cache,v1) := ceval(cache,env, e1, impl,msg,numIter+1);
4691 970 e1_1 := ValuesUtil.valueExp(v1, SOME(e1));
4692 970 then
4693 (cache,DAE.SLICE(e1_1));
4694
4695 end matchcontinue;
4696 end cevalSubscript;
4697
4698 protected function crefEqualValue ""
4699 input DAE.ComponentRef c;
4700 input DAE.Binding v;
4701 output Boolean outBoolean;
4702 algorithm
4703 outBoolean := match v
4704 local
4705 DAE.ComponentRef cr;
4706
4707 case DAE.EQBOUND(DAE.CREF(cr,_),NONE(),_,_)
4708 13 then ComponentReferenceBasics.crefEqual(c,cr);
4709
4710 else false;
4711
4712 end match;
4713 end crefEqualValue;
4714
4715 protected function dimensionSliceInRange "
4716 Checks that the values of a dimension slice is all in the range 1 to dim size
4717 if so returns true, else returns false"
4718 input Values.Value arr;
4719 input Integer dimSize;
4720 output Boolean inRange;
4721 algorithm
4722 inRange := matchcontinue arr
4723 local
4724 Integer indx,dim;
4725 list<Values.Value> vlst;
4726 list<Integer> dims;
4727
4728 case Values.ARRAY(valueLst = {}) then true;
4729
4730 case Values.ARRAY(valueLst = Values.INTEGER(indx)::vlst, dimLst = dim::dims)
4731 algorithm
4732 ✗ dim := dim-1;
4733 dims := dim::dims;
4734 ✗ true := indx <= dimSize;
4735 ✗ true := dimensionSliceInRange(Values.ARRAY(vlst,dims),dimSize);
4736 then true;
4737
4738 else false;
4739
4740 end matchcontinue;
4741 end dimensionSliceInRange;
4742
4743 protected function cevalReduction
4744 "Help function to ceval. Evaluates reductions calls, such as
4745 'sum(i for i in 1:5)'"
4746 input FCore.Cache inCache;
4747 input FCore.Graph inEnv;
4748 input Absyn.Path opPath;
4749 input Option<Values.Value> inCurValue;
4750 input DAE.Exp exp;
4751 input DAE.Type exprType;
4752 input String foldName;
4753 input String resultName;
4754 input Option<DAE.Exp> foldExp;
4755 input list<String> iteratorNames;
4756 input list<list<Values.Value>> inValueMatrix;
4757 input list<DAE.Type> iterTypes;
4758 input Boolean impl;
4759 input Absyn.Msg msg;
4760 input Integer numIter;
4761 output FCore.Cache newCache;
4762 output Option<Values.Value> result;
4763 algorithm
4764 (newCache, result) := match (inCache, inEnv, opPath, inCurValue, inValueMatrix)
4765 local
4766 list<Values.Value> vals;
4767 FCore.Graph new_env,env;
4768 FCore.Cache cache;
4769 list<Integer> dims;
4770 list<list<Values.Value>> valueMatrix;
4771 Option<Values.Value> curValue;
4772
4773 case (cache, _, Absyn.IDENT("list"), SOME(Values.LIST(vals)), {})
4774 algorithm
4775 6 vals := listReverse(vals);
4776 6 then (cache, SOME(Values.LIST(vals)));
4777 case (cache, _, Absyn.IDENT("listReverse"), SOME(Values.LIST(_)), {})
4778 then (cache, inCurValue);
4779 case (cache, _, Absyn.IDENT("array"), SOME(Values.ARRAY(vals,dims)), {})
4780 algorithm
4781 71 vals := listReverse(vals);
4782 71 then (cache, SOME(Values.ARRAY(vals,dims)));
4783
4784 case (cache, _, _, curValue, {})
4785 then (cache, curValue);
4786
4787 case (cache, env, _, curValue, vals :: valueMatrix)
4788 algorithm
4789 // Bind the iterator
4790 // print("iterators: " + stringDelimitList(list(ValuesDump.valString(v) for v in vals), ",") + "\n");
4791 790 new_env := extendFrameForIterators(env, iteratorNames, vals, iterTypes);
4792 // Calculate var1 of the folding function
4793 790 (cache, curValue) := cevalReductionEvalAndFold(cache, new_env, opPath, curValue, exp, exprType, foldName, resultName, foldExp, impl, msg,numIter+1);
4794 // Fold the rest of the reduction
4795 790 (cache, curValue) := cevalReduction(cache, env, opPath, curValue, exp, exprType, foldName, resultName, foldExp, iteratorNames, valueMatrix, iterTypes, impl, msg,numIter);
4796 then (cache, curValue);
4797 end match;
4798 end cevalReduction;
4799
4800 protected function cevalReductionEvalAndFold "Evaluate the reduction body and fold"
4801 input FCore.Cache inCache;
4802 input FCore.Graph inEnv;
4803 input Absyn.Path opPath;
4804 input Option<Values.Value> inCurValue;
4805 input DAE.Exp exp;
4806 input DAE.Type exprType;
4807 input String foldName;
4808 input String resultName;
4809 input Option<DAE.Exp> foldExp;
4810 input Boolean impl;
4811 input Absyn.Msg msg;
4812 input Integer numIter;
4813 output FCore.Cache newCache;
4814 output Option<Values.Value> result;
4815 algorithm
4816 (newCache,result) := match (inCache, inEnv, inCurValue)
4817 local
4818 Values.Value value;
4819 Option<Values.Value> curValue;
4820 FCore.Cache cache;
4821 FCore.Graph env;
4822
4823 case (cache, env, curValue)
4824 algorithm
4825 790 (cache, value) := ceval(cache, env, exp, impl, msg,numIter+1);
4826 // print("cevalReductionEval: " + ExpressionBasics.printExpStr(exp) + " => " + ValuesDump.valString(value) + "\n");
4827 790 (cache, result) := cevalReductionFold(cache, env, opPath, curValue, value, foldName, resultName, foldExp, exprType, impl, msg,numIter);
4828 // print("cevalReductionEval => " + Util.applyOptionOrDefault(result, ValuesDump.valString, "") + "\n");
4829 then (cache, result);
4830 end match;
4831 end cevalReductionEvalAndFold;
4832
4833 protected function cevalReductionFold "Fold the reduction body"
4834 input FCore.Cache inCache;
4835 input FCore.Graph inEnv;
4836 input Absyn.Path opPath;
4837 input Option<Values.Value> inCurValue;
4838 input Values.Value inValue;
4839 input String foldName;
4840 input String resultName;
4841 input Option<DAE.Exp> foldExp;
4842 input DAE.Type exprType;
4843 input Boolean impl;
4844 input Absyn.Msg msg;
4845 input Integer numIter;
4846 output FCore.Cache newCache;
4847 output Option<Values.Value> result;
4848 algorithm
4849 (newCache,result) := match (inCache,opPath,inCurValue,foldExp)
4850 local
4851 DAE.Exp exp;
4852 Values.Value value;
4853 FCore.Cache cache;
4854 FCore.Graph env;
4855
4856 case (cache,Absyn.IDENT("array"),SOME(value),_)
4857 algorithm
4858 599 value := valueArrayCons(ValuesUtil.unboxIfBoxedVal(inValue),value);
4859 then (cache,SOME(value));
4860 case (cache,Absyn.IDENT("list"),SOME(value),_)
4861 algorithm
4862 18 value := valueCons(ValuesUtil.unboxIfBoxedVal(inValue),value);
4863 then (cache,SOME(value));
4864 case (cache,Absyn.IDENT("listReverse"),SOME(value),_)
4865 algorithm
4866 12 value := valueCons(ValuesUtil.unboxIfBoxedVal(inValue),value);
4867 then (cache,SOME(value));
4868 case (cache,_,NONE(),_)
4869 then (cache,SOME(inValue));
4870
4871 case (cache,_,SOME(value),SOME(exp))
4872 algorithm
4873 // print("cevalReductionFold " + ExpressionBasics.printExpStr(exp) + ", " + ValuesDump.valString(inValue) + ", " + ValuesUtil.valString(value) + "\n");
4874 /* TODO: Store the actual types somewhere... */
4875 153 env := FGraph.addForIterator(inEnv, foldName, exprType, DAE.VALBOUND(inValue, DAE.BINDING_FROM_DEFAULT_VALUE()), SCode.VAR(), SOME(DAE.C_CONST()));
4876 153 env := FGraph.addForIterator(env, resultName, exprType, DAE.VALBOUND(value, DAE.BINDING_FROM_DEFAULT_VALUE()), SCode.VAR(), SOME(DAE.C_CONST()));
4877 153 (cache, value) := ceval(cache, env, exp, impl, msg,numIter+1);
4878 153 then (cache, SOME(value));
4879 end match;
4880 end cevalReductionFold;
4881
4882 protected function valueArrayCons
4883 "Returns the cons of two values. Used by cevalReduction for array reductions."
4884 input Values.Value v1;
4885 input Values.Value v2;
4886 output Values.Value res;
4887 algorithm
4888 res := match v2
4889 local
4890 list<Values.Value> vals;
4891 Integer dim_size;
4892 list<Integer> rest_dims;
4893
4894 case Values.ARRAY(valueLst = vals, dimLst = dim_size :: rest_dims)
4895 algorithm
4896 599 dim_size := dim_size + 1;
4897 599 then
4898 Values.ARRAY(v1 :: vals, dim_size :: rest_dims);
4899
4900 ✗ else Values.ARRAY({v1, v2}, {2});
4901 end match;
4902 end valueArrayCons;
4903
4904 protected function valueCons
4905 "Returns the cons of two values. Used by cevalReduction for list reductions."
4906 input Values.Value inV1;
4907 input Values.Value inV2;
4908 output Values.Value res;
4909 algorithm
4910 res := match(inV1, inV2)
4911 local
4912 list<Values.Value> vals;
4913 Values.Value v1;
4914
4915 ✗ case (Values.META_BOX(v1), Values.LIST(vals)) then Values.LIST(v1::vals);
4916 30 case (v1, Values.LIST(vals)) then Values.LIST(v1::vals);
4917 end match;
4918 end valueCons;
4919
4920 protected function cevalReductionIterators
4921 input FCore.Cache inCache;
4922 input FCore.Graph inEnv;
4923 input list<DAE.ReductionIterator> inIterators;
4924 input Boolean impl;
4925 input Absyn.Msg msg;
4926 input Integer numIter;
4927 output FCore.Cache outCache = inCache;
4928 output list<list<Values.Value>> vals = {};
4929 output list<String> names = {};
4930 output list<Integer> dims = {};
4931 output list<DAE.Type> tys = {};
4932 protected
4933 Values.Value val;
4934 list<Values.Value> iterVals;
4935 DAE.Type ty;
4936 String id;
4937 DAE.Exp exp;
4938 Option<DAE.Exp> guardExp;
4939 algorithm
4940
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 135 times.
287 for iter in inIterators loop
4941 152 DAE.REDUCTIONITER(id, exp, guardExp, ty) := iter;
4942 152 (outCache, val) := ceval(outCache, inEnv, exp, impl, msg, numIter+1);
4943 150 iterVals := ValuesUtil.arrayOrListVals(val, true);
4944 150 (outCache, iterVals) := filterReductionIterator(outCache, inEnv, id, ty, iterVals, guardExp, impl, msg, numIter);
4945
4946 150 vals := iterVals :: vals;
4947 names := id :: names;
4948 150 dims := listLength(iterVals) :: dims;
4949 tys := ty :: tys;
4950 end for;
4951 end cevalReductionIterators;
4952
4953 protected function filterReductionIterator
4954 input FCore.Cache inCache;
4955 input FCore.Graph inEnv;
4956 input String id;
4957 input DAE.Type ty;
4958 input list<Values.Value> inVals;
4959 input Option<DAE.Exp> guardExp;
4960 input Boolean impl;
4961 input Absyn.Msg msg;
4962 input Integer numIter;
4963 output FCore.Cache outCache;
4964 output list<Values.Value> outVals;
4965 algorithm
4966 (outCache,outVals) := match (inCache, inEnv, inVals, guardExp)
4967 local
4968 DAE.Exp exp;
4969 Values.Value val;
4970 Boolean b;
4971 FCore.Graph new_env,env;
4972 FCore.Cache cache;
4973 list<Values.Value> vals;
4974
4975 case (cache, _, {}, _) then (cache,{});
4976 case (cache, env, val::vals, SOME(exp))
4977 algorithm
4978 48 new_env := FGraph.addForIterator(env, id, ty, DAE.VALBOUND(val, DAE.BINDING_FROM_DEFAULT_VALUE()), SCode.VAR(), SOME(DAE.C_CONST()));
4979
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 (cache,Values.BOOL(b)) := ceval(cache,new_env,exp,impl,msg,numIter+1);
4980 48 (cache,vals) := filterReductionIterator(cache,env,id,ty,vals,guardExp,impl,msg,numIter);
4981
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 28 times.
48 vals := if b then val::vals else vals;
4982 then (cache,vals);
4983 case (cache, _, vals, NONE()) then (cache,vals);
4984 end match;
4985 end filterReductionIterator;
4986
4987 protected function extendFrameForIterators
4988 input FCore.Graph inEnv;
4989 input list<String> inNames;
4990 input list<Values.Value> inVals;
4991 input list<DAE.Type> inTys;
4992 output FCore.Graph outEnv;
4993 algorithm
4994 outEnv := match (inEnv,inNames,inVals,inTys)
4995 local
4996 String name;
4997 Values.Value val;
4998 DAE.Type ty;
4999 FCore.Graph env;
5000 list<String> names;
5001 list<Values.Value> vals;
5002 list<DAE.Type> tys;
5003
5004 case (env,{},{},{}) then env;
5005 case (env,name::names,val::vals,ty::tys)
5006 algorithm
5007 1046 env := FGraph.addForIterator(env, name, ty, DAE.VALBOUND(val, DAE.BINDING_FROM_DEFAULT_VALUE()), SCode.VAR(), SOME(DAE.C_CONST()));
5008 1046 env := extendFrameForIterators(env,names,vals,tys);
5009 then env;
5010 end match;
5011 end extendFrameForIterators;
5012
5013 protected function backpatchArrayReduction
5014 input Absyn.Path path;
5015 input Absyn.ReductionIterType iterType;
5016 input Values.Value inValue;
5017 input list<Integer> dims;
5018 output Values.Value outValue;
5019 algorithm
5020 outValue := match (path,iterType,inValue,dims)
5021 local
5022 list<Values.Value> vals;
5023 Values.Value value;
5024 case (_,_,value,{_}) then value;
5025 case (Absyn.IDENT("array"),Absyn.COMBINE(),Values.ARRAY(valueLst=vals),_)
5026 algorithm
5027 8 value := backpatchArrayReduction3(vals,listReverse(dims),ValuesMake.makeArray);
5028 // print(ValuesDump.valString(value));print("\n");
5029 then value;
5030 case (Absyn.IDENT("list"),Absyn.COMBINE(),Values.LIST(vals),_)
5031 algorithm
5032 ✗ value := backpatchArrayReduction3(vals,listReverse(dims),ValuesMake.makeList);
5033 // print(ValuesDump.valString(value));print("\n");
5034 then value;
5035 case (Absyn.IDENT("listReverse"),Absyn.COMBINE(),Values.LIST(vals),_)
5036 algorithm
5037 ✗ value := backpatchArrayReduction3(vals,listReverse(dims),ValuesMake.makeList);
5038 // print(ValuesDump.valString(value));print("\n");
5039 then value;
5040 else inValue;
5041 end match;
5042 end backpatchArrayReduction;
5043
5044 protected function backpatchArrayReduction3
5045 input list<Values.Value> inVals;
5046 input list<Integer> inDims;
5047 input Func makeSequence;
5048 output Values.Value outValue;
5049 partial function Func
5050 input list<Values.Value> inVals;
5051 output Values.Value outVal;
5052 end Func;
5053 algorithm
5054 outValue := match (inVals, inDims)
5055 local
5056 Integer dim;
5057 list<list<Values.Value>> valMatrix;
5058 Values.Value value;
5059 list<Values.Value> vals;
5060 list<Integer> dims;
5061
5062 case (vals, {_})
5063 algorithm
5064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 value := makeSequence(vals);
5065 then value;
5066 case (vals, dim::dims)
5067 algorithm
5068 // Split into the smallest of the arrays
5069 // print("into sublists of length: " + intString(dim) + " from length=" + intString(listLength(vals)) + "\n");
5070 10 valMatrix := List.partition(vals,dim);
5071 // print("output has length=" + intString(listLength(valMatrix)) + "\n");
5072 10 vals := List.map(valMatrix,makeSequence);
5073 10 value := backpatchArrayReduction3(vals,dims,makeSequence);
5074 then value;
5075 end match;
5076 end backpatchArrayReduction3;
5077
5078 public function cevalSimple
5079 "A simple expression does not need cache, etc"
5080 input DAE.Exp exp;
5081 output Values.Value val;
5082 algorithm
5083 21649 (_,val) := ceval(FCore.emptyCache(),FGraph.empty(),exp,false,Absyn.MSG(Absyn.dummyInfo),0);
5084 end cevalSimple;
5085
5086 public function cevalSimpleWithFunctionTreeReturnExp
5087 "A simple expression does not need cache, etc"
5088 input DAE.Exp exp;
5089 input AvlTreePathFunction.Tree functions;
5090 output DAE.Exp oexp;
5091 protected
5092 Values.Value val;
5093 FCore.Cache cache;
5094 FCore.StructuralParameters structuralParameters;
5095 Mutable<AvlTreePathFunction.Tree> functionTree;
5096 algorithm
5097 structuralParameters := (AvlSetCR.EMPTY(),{});
5098 1619 functionTree := Mutable.create(functions);
5099 1619 cache := FCore.CACHE(NONE(), functionTree, structuralParameters, Absyn.IDENT(""));
5100 1619 (_,val) := ceval(cache, FGraph.empty(), exp, false, Absyn.MSG(Absyn.dummyInfo),0);
5101 1619 oexp := ValuesUtil.valueExp(val, SOME(exp));
5102 end cevalSimpleWithFunctionTreeReturnExp;
5103
5104 public function cevalAstExp
5105 "Part of meta-programming using CODE.
5106 This function evaluates a piece of Expression AST, replacing Eval(variable)
5107 with the value of the variable, given that it is of type \"Expression\".
5108
5109 Example: y = Code(1 + x)
5110 2 + 5 ( x + Eval(y) ) => 2 + 5 ( x + 1 + x )"
5111 input FCore.Cache inCache;
5112 input FCore.Graph inEnv;
5113 input Absyn.Exp inExp;
5114 input Boolean inBoolean;
5115 input Absyn.Msg inMsg;
5116 input SourceInfo info;
5117 output FCore.Cache outCache;
5118 output Absyn.Exp outExp;
5119 algorithm
5120 (outCache,outExp) :=
5121 matchcontinue (inCache, inEnv, inExp, inBoolean, inMsg)
5122 local
5123 Absyn.Exp e,e1_1,e2_1,e1,e2,e_1,cond_1,then_1,else_1,cond,then_,else_,exp,e3_1,e3;
5124 FCore.Graph env;
5125 Absyn.Operator op;
5126 Boolean impl;
5127 Absyn.Msg msg;
5128 list<tuple<Absyn.Exp, Absyn.Exp>> nest_1,nest;
5129 list<Absyn.Exp> expl_1,expl;
5130 FCore.Cache cache;
5131 DAE.Exp daeExp;
5132 list<list<Absyn.Exp>> lstExpl_1,lstExpl;
5133
5134 case (cache, _, (e as Absyn.INTEGER()), _, _) then (cache,e);
5135 case (cache, _, (e as Absyn.REAL()), _, _) then (cache,e);
5136 case (cache, _, (e as Absyn.CREF()), _, _) then (cache,e);
5137 case (cache, _, (e as Absyn.STRING()), _, _) then (cache,e);
5138 case (cache, _, (e as Absyn.BOOL()), _, _) then (cache,e);
5139
5140 case (cache, env, Absyn.BINARY(exp1 = e1,op = op,exp2 = e2), impl, msg)
5141 algorithm
5142 ✗ (cache,e1_1) := cevalAstExp(cache,env, e1, impl, msg, info);
5143 ✗ (cache,e2_1) := cevalAstExp(cache,env, e2, impl, msg, info);
5144 ✗ then
5145 (cache,Absyn.BINARY(e1_1,op,e2_1));
5146
5147 case (cache, env, Absyn.UNARY(op = op,exp = e), impl, msg)
5148 algorithm
5149 ✗ (cache,e_1) := cevalAstExp(cache,env, e, impl, msg, info);
5150 ✗ then
5151 (cache,Absyn.UNARY(op,e_1));
5152
5153 case (cache, env, Absyn.LBINARY(exp1 = e1,op = op,exp2 = e2), impl, msg)
5154 algorithm
5155 ✗ (cache,e1_1) := cevalAstExp(cache,env, e1, impl, msg, info);
5156 ✗ (cache,e2_1) := cevalAstExp(cache,env, e2, impl, msg, info);
5157 ✗ then
5158 (cache,Absyn.LBINARY(e1_1,op,e2_1));
5159
5160 case (cache, env, Absyn.LUNARY(op = op,exp = e), impl, msg)
5161 algorithm
5162 ✗ (cache,e_1) := cevalAstExp(cache,env, e, impl, msg, info);
5163 ✗ then
5164 (cache,Absyn.LUNARY(op,e_1));
5165
5166 case (cache, env, Absyn.RELATION(exp1 = e1,op = op,exp2 = e2), impl, msg)
5167 algorithm
5168 ✗ (cache,e1_1) := cevalAstExp(cache,env, e1, impl, msg, info);
5169 ✗ (cache,e2_1) := cevalAstExp(cache,env, e2, impl, msg, info);
5170 ✗ then
5171 (cache,Absyn.RELATION(e1_1,op,e2_1));
5172
5173 case (cache, env, Absyn.IFEXP(ifExp = cond,trueBranch = then_,elseBranch = else_,elseIfBranch = nest), impl, msg)
5174 algorithm
5175 ✗ (cache,cond_1) := cevalAstExp(cache,env, cond, impl, msg, info);
5176 ✗ (cache,then_1) := cevalAstExp(cache,env, then_, impl, msg, info);
5177 ✗ (cache,else_1) := cevalAstExp(cache,env, else_, impl, msg, info);
5178 ✗ (cache,nest_1) := cevalAstExpexpList(cache,env, nest, impl, msg, info);
5179 ✗ then
5180 (cache,Absyn.IFEXP(cond_1,then_1,else_1,nest_1));
5181
5182 case (cache, env, Absyn.CALL(function_ = Absyn.CREF_IDENT(name = "Eval",subscripts = {}),functionArgs = Absyn.FUNCTIONARGS(args = {e},argNames = {})), impl, msg)
5183 algorithm
5184 ✗ (cache,daeExp,_) := Static.elabExp(cache, env, e, impl, true, DAE.NOPRE(), info);
5185 ✗ (cache,Values.CODE(Absyn.C_EXPRESSION(exp))) := ceval(cache, env, daeExp, impl,msg,0);
5186 then
5187 (cache,exp);
5188
5189 case (cache, _, (e as Absyn.CALL()), _, _) then (cache,e);
5190
5191 case (cache, env, Absyn.ARRAY(arrayExp = expl), impl, msg)
5192 algorithm
5193 ✗ (cache,expl_1) := cevalAstExpList(cache,env, expl, impl, msg, info);
5194 ✗ then
5195 (cache,Absyn.ARRAY(expl_1));
5196
5197 case (cache, env, Absyn.MATRIX(matrix = lstExpl), impl, msg)
5198 algorithm
5199 ✗ (cache,lstExpl_1) := cevalAstExpListList(cache, env, lstExpl, impl, msg, info);
5200 ✗ then
5201 (cache,Absyn.MATRIX(lstExpl_1));
5202
5203 case (cache, env, Absyn.RANGE(start = e1,step = SOME(e2),stop = e3), impl, msg)
5204 algorithm
5205 ✗ (cache,e1_1) := cevalAstExp(cache,env, e1, impl, msg, info);
5206 ✗ (cache,e2_1) := cevalAstExp(cache,env, e2, impl, msg, info);
5207 ✗ (cache,e3_1) := cevalAstExp(cache,env, e3, impl, msg, info);
5208 ✗ then
5209 (cache,Absyn.RANGE(e1_1,SOME(e2_1),e3_1));
5210
5211 case (cache, env, Absyn.RANGE(start = e1,step = NONE(),stop = e3), impl, msg)
5212 algorithm
5213 ✗ (cache,e1_1) := cevalAstExp(cache,env, e1, impl, msg, info);
5214 ✗ (cache,e3_1) := cevalAstExp(cache,env, e3, impl, msg, info);
5215 ✗ then
5216 (cache,Absyn.RANGE(e1_1,NONE(),e3_1));
5217
5218 case (cache, env, Absyn.TUPLE(expressions = expl), impl, msg)
5219 algorithm
5220 470 (cache,expl_1) := cevalAstExpList(cache,env, expl, impl, msg, info);
5221 470 then
5222 (cache,Absyn.TUPLE(expl_1));
5223
5224 case (cache, _, Absyn.END(), _, _) then (cache,Absyn.END());
5225
5226 case (cache, _, (e as Absyn.CODE()), _, _) then (cache,e);
5227
5228 end matchcontinue;
5229 end cevalAstExp;
5230
5231 public function cevalAstExpList
5232 "List version of cevalAstExp"
5233 input FCore.Cache inCache;
5234 input FCore.Graph inEnv;
5235 input list<Absyn.Exp> inAbsynExpLst;
5236 input Boolean inBoolean;
5237 input Absyn.Msg inMsg;
5238 input SourceInfo info;
5239 output FCore.Cache outCache;
5240 output list<Absyn.Exp> outAbsynExpLst;
5241 algorithm
5242 (outCache,outAbsynExpLst) :=
5243 match (inCache, inEnv, inAbsynExpLst, inBoolean, inMsg)
5244 local
5245 FCore.Graph env;
5246 Absyn.Msg msg;
5247 Absyn.Exp e;
5248 list<Absyn.Exp> res,es;
5249 Boolean impl;
5250 FCore.Cache cache;
5251
5252 case (cache, _, {}, _, _) then (cache,{});
5253
5254 case (cache, env, (e :: es), impl, msg)
5255 algorithm
5256 ✗ (cache,_) := cevalAstExp(cache,env, e, impl, msg, info);
5257 ✗ (cache,res) := cevalAstExpList(cache,env, es, impl, msg, info);
5258 ✗ then
5259 (cache,e :: res);
5260 end match;
5261 end cevalAstExpList;
5262
5263 protected function cevalAstExpListList "function: cevalAstExpListList"
5264 input FCore.Cache inCache;
5265 input FCore.Graph inEnv;
5266 input list<list<Absyn.Exp>> inAbsynExpLstLst;
5267 input Boolean inBoolean;
5268 input Absyn.Msg inMsg;
5269 input SourceInfo info;
5270 output FCore.Cache outCache;
5271 output list<list<Absyn.Exp>> outAbsynExpLstLst;
5272 algorithm
5273 (outCache,outAbsynExpLstLst) :=
5274 match (inCache, inEnv, inAbsynExpLstLst, inBoolean, inMsg)
5275 local
5276 FCore.Graph env;
5277 Absyn.Msg msg;
5278 list<Absyn.Exp> e;
5279 list<list<Absyn.Exp>> res,es;
5280 Boolean impl;
5281 FCore.Cache cache;
5282
5283 case (cache, _, {}, _, _) then (cache,{});
5284
5285 case (cache, env, (e :: es), impl, msg)
5286 algorithm
5287 ✗ (cache,_) := cevalAstExpList(cache,env, e, impl, msg, info);
5288 ✗ (cache,res) := cevalAstExpListList(cache,env, es, impl, msg, info);
5289 ✗ then
5290 (cache,e :: res);
5291 end match;
5292 end cevalAstExpListList;
5293
5294 public function cevalAstElt
5295 "Evaluates an ast constructor for Element nodes, e.g.
5296 Code(parameter Real x=1;)"
5297 input FCore.Cache inCache;
5298 input FCore.Graph inEnv;
5299 input Absyn.Element inElement;
5300 input Boolean inBoolean;
5301 input Absyn.Msg inMsg;
5302 output FCore.Cache outCache;
5303 output Absyn.Element outElement;
5304 algorithm
5305 (outCache,outElement) :=
5306 match (inCache,inEnv,inElement,inBoolean,inMsg)
5307 local
5308 list<Absyn.ComponentItem> citems_1,citems;
5309 FCore.Graph env;
5310 Boolean f,impl;
5311 Option<Absyn.RedeclareKeywords> r;
5312 Absyn.InnerOuter io;
5313 Absyn.ElementAttributes attr;
5314 Absyn.TypeSpec tp;
5315 SourceInfo info;
5316 Option<Absyn.ConstrainClass> c;
5317 Absyn.Msg msg;
5318 FCore.Cache cache;
5319 case (cache,env,Absyn.ELEMENT(finalPrefix = f,redeclareKeywords = r,innerOuter = io,specification = Absyn.COMPONENTS(attributes = attr,typeSpec = tp,components = citems),info = (info as SOURCEINFO()),constrainClass = c),impl,msg)
5320 algorithm
5321 ✗ (cache,citems_1) := cevalAstCitems(cache,env, citems, impl, msg, info);
5322 ✗ then
5323 (cache,Absyn.ELEMENT(f,r,io,Absyn.COMPONENTS(attr,tp,citems_1),info,c));
5324 end match;
5325 end cevalAstElt;
5326
5327 protected function cevalAstCitems
5328 "Helper function to cevalAstElt."
5329 input FCore.Cache inCache;
5330 input FCore.Graph inEnv;
5331 input list<Absyn.ComponentItem> inAbsynComponentItemLst;
5332 input Boolean inBoolean;
5333 input Absyn.Msg inMsg;
5334 input SourceInfo info;
5335 output FCore.Cache outCache;
5336 output list<Absyn.ComponentItem> outAbsynComponentItemLst;
5337 algorithm
5338 (outCache,outAbsynComponentItemLst) :=
5339 matchcontinue (inCache, inEnv, inAbsynComponentItemLst, inBoolean, inMsg)
5340 local
5341 Absyn.Msg msg;
5342 list<Absyn.ComponentItem> res,xs;
5343 Option<Absyn.Modification> modopt_1,modopt;
5344 list<Absyn.Subscript> ad_1,ad;
5345 FCore.Graph env;
5346 String id;
5347 Option<Absyn.Exp> cond;
5348 Option<Absyn.Comment> cmt;
5349 Boolean impl;
5350 Absyn.ComponentItem x;
5351 FCore.Cache cache;
5352 case (cache, _, {}, _, _) then (cache,{});
5353 case (cache, env, (Absyn.COMPONENTITEM(component = Absyn.COMPONENT(name = id,arrayDim = ad,modification = modopt),condition = cond,comment = cmt) :: xs), impl, msg) /* If one component fails, the rest should still succeed */
5354 algorithm
5355 ✗ (cache,res) := cevalAstCitems(cache,env, xs, impl, msg, info);
5356 ✗ (cache,modopt_1) := cevalAstModopt(cache,env, modopt, impl, msg, info);
5357 ✗ (cache,ad_1) := cevalAstArraydim(cache,env, ad, impl, msg, info);
5358 ✗ then
5359 (cache,Absyn.COMPONENTITEM(Absyn.COMPONENT(id,ad_1,modopt_1),cond,cmt) :: res);
5360 case (cache, env, (x :: xs), impl, msg) /* If one component fails, the rest should still succeed */
5361 algorithm
5362 ✗ (cache,res) := cevalAstCitems(cache,env, xs, impl, msg, info);
5363 ✗ then
5364 (cache,x :: res);
5365 end matchcontinue;
5366 end cevalAstCitems;
5367
5368 protected function cevalAstModopt
5369 "function: cevalAstModopt"
5370 input FCore.Cache inCache;
5371 input FCore.Graph inEnv;
5372 input Option<Absyn.Modification> inAbsynModificationOption;
5373 input Boolean inBoolean;
5374 input Absyn.Msg inMsg;
5375 input SourceInfo info;
5376 output FCore.Cache outCache;
5377 output Option<Absyn.Modification> outAbsynModificationOption;
5378 algorithm
5379 (outCache,outAbsynModificationOption) :=
5380 match (inCache, inEnv, inAbsynModificationOption, inBoolean, inMsg)
5381 local
5382 Absyn.Modification res,mod;
5383 FCore.Graph env;
5384 Boolean impl;
5385 Absyn.Msg msg;
5386 FCore.Cache cache;
5387 case (cache, env, SOME(mod), impl, msg)
5388 algorithm
5389 ✗ (cache,res) := cevalAstModification(cache,env, mod, impl, msg, info);
5390 ✗ then
5391 (cache,SOME(res));
5392 case (cache, _, NONE(), _, _) then (cache,NONE());
5393 end match;
5394 end cevalAstModopt;
5395
5396 protected function cevalAstModification "This function evaluates Eval(variable) inside an AST Modification and replaces
5397 the Eval operator with the value of the variable if it has a type \"Expression\""
5398 input FCore.Cache inCache;
5399 input FCore.Graph inEnv;
5400 input Absyn.Modification inModification;
5401 input Boolean inBoolean;
5402 input Absyn.Msg inMsg;
5403 input SourceInfo info;
5404 output FCore.Cache outCache;
5405 output Absyn.Modification outModification;
5406 algorithm
5407 (outCache,outModification) :=
5408 match (inCache, inEnv, inModification, inBoolean, inMsg)
5409 local
5410 Absyn.Exp e_1,e;
5411 list<Absyn.ElementArg> eltargs_1,eltargs;
5412 FCore.Graph env;
5413 Boolean impl;
5414 Absyn.Msg msg;
5415 FCore.Cache cache;
5416 SourceInfo info2;
5417 case (cache, env, Absyn.CLASSMOD(elementArgLst = eltargs,eqMod = Absyn.EQMOD(e,info2)), impl, msg)
5418 algorithm
5419 ✗ (cache,e_1) := cevalAstExp(cache,env, e, impl, msg, info);
5420 ✗ (cache,eltargs_1) := cevalAstEltargs(cache,env, eltargs, impl, msg, info);
5421 ✗ then
5422 (cache,Absyn.CLASSMOD(eltargs_1,Absyn.EQMOD(e_1,info2)));
5423 case (cache, env, Absyn.CLASSMOD(elementArgLst = eltargs,eqMod = Absyn.NOMOD()), impl, msg)
5424 algorithm
5425 ✗ (cache,eltargs_1) := cevalAstEltargs(cache,env, eltargs, impl, msg, info);
5426 ✗ then
5427 (cache,Absyn.CLASSMOD(eltargs_1,Absyn.NOMOD()));
5428 end match;
5429 end cevalAstModification;
5430
5431 protected function cevalAstEltargs "Helper function to cevalAstModification."
5432 input FCore.Cache inCache;
5433 input FCore.Graph inEnv;
5434 input list<Absyn.ElementArg> inAbsynElementArgLst;
5435 input Boolean inBoolean;
5436 input Absyn.Msg inMsg;
5437 input SourceInfo info;
5438 output FCore.Cache outCache;
5439 output list<Absyn.ElementArg> outAbsynElementArgLst;
5440 algorithm
5441 (outCache,outAbsynElementArgLst):=
5442 matchcontinue (inCache, inEnv, inAbsynElementArgLst, inBoolean, inMsg)
5443 local
5444 FCore.Graph env;
5445 Absyn.Msg msg;
5446 Absyn.Modification mod_1,mod;
5447 list<Absyn.ElementArg> res,args;
5448 Boolean b,impl;
5449 Absyn.Each e;
5450 Option<String> stropt;
5451 Absyn.ElementArg m;
5452 FCore.Cache cache;
5453 SourceInfo mod_info;
5454 Absyn.Path p;
5455
5456 case (cache, _, {}, _, _) then (cache,{});
5457 /* TODO: look through redeclarations for Eval(var) as well */
5458 case (cache, env, (Absyn.MODIFICATION(finalPrefix = b,eachPrefix = e,path = p,modification = SOME(mod),comment = stropt, info = mod_info) :: args), impl, msg)
5459 algorithm
5460 ✗ (cache,mod_1) := cevalAstModification(cache,env, mod, impl, msg, info);
5461 ✗ (cache,res) := cevalAstEltargs(cache,env, args, impl, msg, info);
5462 ✗ then
5463 (cache,Absyn.MODIFICATION(b,e,p,SOME(mod_1),stropt,mod_info) :: res);
5464 case (cache, env, (m :: args), impl, msg) /* TODO: look through redeclarations for Eval(var) as well */
5465 algorithm
5466 ✗ (cache,res) := cevalAstEltargs(cache,env, args, impl, msg, info);
5467 ✗ then
5468 (cache,m :: res);
5469 end matchcontinue;
5470 end cevalAstEltargs;
5471
5472 protected function cevalAstArraydim "Helper function to cevaAstCitems"
5473 input FCore.Cache inCache;
5474 input FCore.Graph inEnv;
5475 input Absyn.ArrayDim inArrayDim;
5476 input Boolean inBoolean;
5477 input Absyn.Msg inMsg;
5478 input SourceInfo info;
5479 output FCore.Cache outCache;
5480 output Absyn.ArrayDim outArrayDim;
5481 algorithm
5482 (outCache,outArrayDim) :=
5483 match (inCache, inEnv, inArrayDim, inBoolean, inMsg)
5484 local
5485 FCore.Graph env;
5486 Absyn.Msg msg;
5487 list<Absyn.Subscript> res,xs;
5488 Boolean impl;
5489 Absyn.Exp e;
5490 FCore.Cache cache;
5491 case (cache, _, {}, _, _) then (cache,{});
5492 case (cache, env, (Absyn.NOSUB() :: xs), impl, msg)
5493 algorithm
5494 ✗ (cache,res) := cevalAstArraydim(cache,env, xs, impl, msg, info);
5495 ✗ then
5496 (cache,Absyn.NOSUB() :: res);
5497 case (cache, env, (Absyn.SUBSCRIPT(subscript = e) :: xs), impl, msg)
5498 algorithm
5499 ✗ (cache,res) := cevalAstArraydim(cache,env, xs, impl, msg, info);
5500 ✗ (cache,_) := cevalAstExp(cache,env, e, impl, msg, info);
5501 ✗ then
5502 (cache,Absyn.SUBSCRIPT(e) :: res);
5503 end match;
5504 end cevalAstArraydim;
5505
5506 protected function cevalAstExpexpList
5507 "For IFEXP"
5508 input FCore.Cache inCache;
5509 input FCore.Graph inEnv;
5510 input list<tuple<Absyn.Exp, Absyn.Exp>> inExpTpls;
5511 input Boolean inBoolean;
5512 input Absyn.Msg inMsg;
5513 input SourceInfo info;
5514 output FCore.Cache outCache;
5515 output list<tuple<Absyn.Exp, Absyn.Exp>> outExpTpls;
5516 algorithm
5517 (outCache, outExpTpls) :=
5518 match (inCache, inEnv, inExpTpls, inBoolean, inMsg)
5519 local
5520 Absyn.Msg msg;
5521 Absyn.Exp e1_1,e2_1,e1,e2;
5522 list<tuple<Absyn.Exp, Absyn.Exp>> res,xs;
5523 FCore.Graph env;
5524 Boolean impl;
5525 FCore.Cache cache;
5526 case (cache, _, {}, _, _) then (cache,{});
5527 case (cache, env, ((e1,e2) :: xs), impl, msg)
5528 algorithm
5529 ✗ (cache,e1_1) := cevalAstExp(cache,env, e1, impl, msg, info);
5530 ✗ (cache,e2_1) := cevalAstExp(cache,env, e2, impl, msg, info);
5531 ✗ (cache,res) := cevalAstExpexpList(cache,env, xs, impl, msg, info);
5532 ✗ then
5533 (cache,(e1_1,e2_1) :: res);
5534 end match;
5535 end cevalAstExpexpList;
5536
5537 public function cevalDimension
5538 "Constant evaluates a dimension, returning the size of the dimension as a value."
5539 input FCore.Cache inCache;
5540 input FCore.Graph inEnv;
5541 input DAE.Dimension inDimension;
5542 input Boolean inImpl;
5543 input Absyn.Msg inMsg;
5544 input Integer numIter;
5545 output FCore.Cache outCache;
5546 output Values.Value outValue;
5547 algorithm
5548 (outCache, outValue) :=
5549 match inDimension
5550 local
5551 Integer dim_int;
5552 DAE.Exp exp;
5553 FCore.Cache cache;
5554 Values.Value res;
5555
5556 // Integer dimension, already constant.
5557 case DAE.DIM_INTEGER(integer = dim_int)
5558 17929 then (inCache, Values.INTEGER(dim_int));
5559
5560 // Enumeration dimension, already constant.
5561 case DAE.DIM_ENUM(size = dim_int)
5562 ✗ then (inCache, Values.INTEGER(dim_int));
5563
5564 case DAE.DIM_BOOLEAN()
5565 ✗ then (inCache, Values.INTEGER(2));
5566
5567 // Dimension given by expression, evaluate the expression.
5568 case DAE.DIM_EXP(exp = exp)
5569 algorithm
5570 1233 (cache, res) := ceval(inCache, inEnv, exp, inImpl, inMsg, numIter+1);
5571 then
5572 (cache, res);
5573
5574 end match;
5575 end cevalDimension;
5576
5577 protected function makeReductionAllCombinations
5578 input list<list<Values.Value>> inValMatrix;
5579 input Absyn.ReductionIterType rtype;
5580 output list<list<Values.Value>> valMatrix;
5581 algorithm
5582 valMatrix := match rtype
5583 131 case Absyn.COMBINE() then listReverse(List.allCombinations(inValMatrix,SOME(100000),Absyn.dummyInfo));
5584 4 case Absyn.THREAD() then listReverse(List.transposeList(inValMatrix));
5585 end match;
5586 end makeReductionAllCombinations;
5587
5588 annotation(__OpenModelica_Interface="frontend");
5589 end Ceval;
5590