/
CodegenCppCommon.tpl
3137 lines (2814 loc) · 148 KB
/
CodegenCppCommon.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package CodegenCppCommon
import interface SimCodeTV;
import CodegenUtil.*;
import ExpressionDumpTpl;
/**
* Basic template functions for cpp template
* -cref to string template functions
* -type to string template functions
* -string for temp var template functions
* -exp to string template functions
* -accessors to SimCode attributes
*/
/*******************************************************************************************************************************************************
* cref to string template functions
*******************************************************************************************************************************************************/
template cref(ComponentRef cr, Boolean useFlatArrayNotation)
"Generates C equivalent name for component reference."
::=
match cr
case CREF_IDENT(ident = "time") then "_simTime"
case WILD(__) then ''
else "_"+crefToCStr(cr, useFlatArrayNotation)
end cref;
template localCref(ComponentRef cr, Boolean useFlatArrayNotation)
"Generates C equivalent name for a local component reference."
::=
match cr
case CREF_IDENT(ident = "time") then "_simTime"
case CREF_IDENT(ident = "__HOM_LAMBDA") then "1.0"
case WILD(__) then ''
else crefToCStr(cr,useFlatArrayNotation)
end localCref;
template subscriptsToCStr(list<Subscript> subscripts, Boolean useFlatArrayNotation)
::=
if subscripts then
if useFlatArrayNotation then
'_<%subscripts |> s => subscriptToCStr(s) ;separator="_"%>'
else
'(<%subscripts |> s => subscriptToCStr(s) ;separator=","%>)'
end subscriptsToCStr;
template subscriptToCStr(Subscript subscript)
::=
match subscript
case SLICE(exp=ICONST(integer=i)) then i
case WHOLEDIM(__) then "WHOLEDIM"
case INDEX(__) then
match exp
case ICONST(integer=i) then i
case ENUM_LITERAL(index=i) then i
case CREF(componentRef=cr) then crefToCStr(cr, false)
end match
else "UNKNOWN_SUBSCRIPT"
end subscriptToCStr;
template crefToCStrForArray(ComponentRef cr, Text& dims)
"Convert array cref to cstr. Skip subscripts if not NF_SCALARIZE."
::=
match cr
case CREF_IDENT(__) then
let &dims+=listLength(subscriptLst)
'<%System.unquoteIdentifier(ident)%>_'
case CREF_QUAL(__) then
let subs = if Flags.isSet(Flags.NF_SCALARIZE) then subscriptsToCStrForArray(subscriptLst)
'<%System.unquoteIdentifier(ident)%><%subs%>_P_<%crefToCStrForArray(componentRef,dims)%>'
case WILD(__) then ' '
else "CREF_NOT_IDENT_OR_QUAL"
end crefToCStrForArray;
template crefToCStr1(ComponentRef cr, Boolean useFlatArrayNotation)
::=
match cr
case CREF_IDENT(__) then '<%System.unquoteIdentifier(ident)%>_'
case CREF_QUAL(__) then
'<%System.unquoteIdentifier(ident)%><%subscriptsToCStrForArray(subscriptLst)%>_P_<%crefToCStr1(componentRef,useFlatArrayNotation)%>'
case WILD(__) then ' '
else "CREF_NOT_IDENT_OR_QUAL"
end crefToCStr1;
template subscriptsToCStrForArray(list<Subscript> subscripts)
::=
if subscripts then
'<%subscripts |> s => subscriptToCStr(s) ;separator="$c"%>'
end subscriptsToCStrForArray;
template crefStrForWriteOutput(ComponentRef cr)
"template for writing output variable names in mat or csv files"
::=
match cr
case CREF_IDENT(ident = "xloc") then '__xd<%subscriptsStrForWriteOutput(subscriptLst)%>'
case CREF_IDENT(ident = "time") then "_simTime"
case CREF_IDENT(__) then '<%System.unquoteIdentifier(ident)%><%subscriptsStrForWriteOutput(subscriptLst)%>'
case CREF_QUAL(ident = "$DER") then 'der(<%crefStrForWriteOutput(componentRef)%>)'
case CREF_QUAL(ident = "$CLKPRE") then 'previous(<%crefStrForWriteOutput(componentRef)%>)'
case CREF_QUAL(__) then '<%System.unquoteIdentifier(ident)%><%subscriptsStrForWriteOutput(subscriptLst)%>.<%crefStrForWriteOutput(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end crefStrForWriteOutput;
template crefStrForSetVariables(ComponentRef cr, Boolean useFlatArrayNotation)
"template for Set Variables for labeling reduction"
::=
match cr
case CREF_QUAL(ident = "$DER") then ""
else cref(cr,useFlatArrayNotation)
end crefStrForSetVariables;
template subscriptsStrForWriteOutput(list<Subscript> subscripts)
"Generares subscript part of the name."
::=
if subscripts then
'[<%subscripts |> s => subscriptStr(s) ;separator=","%>]'
end subscriptsStrForWriteOutput;
template crefStr(ComponentRef cr)
::=
match cr
case CREF_IDENT(ident = "xloc") then '__xd<%subscriptsStr(subscriptLst)%>'
case CREF_IDENT(ident = "time") then "_simTime"
case CREF_IDENT(__) then '<%System.unquoteIdentifier(ident)%>_<%subscriptsStr(subscriptLst)%>'
case CREF_QUAL(__) then '<%System.unquoteIdentifier(ident)%>_<%subscriptsStr(subscriptLst)%>.<%crefStr(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end crefStr;
template subscriptsStr(list<Subscript> subscripts)
"Generares subscript part of the name."
::=
if subscripts then
'(<%subscripts |> s => subscriptStr(s) ;separator=","%>)'
end subscriptsStr;
template subscriptStr(Subscript subscript)
"Generates a single subscript."
::=
match subscript
case SLICE(exp=ICONST(integer=i)) then i
case WHOLEDIM(__) then "WHOLEDIM"
case INDEX(__) then
match exp
case ICONST(integer=i) then i
case ENUM_LITERAL(index=i) then i
case CREF(componentRef=cr) then crefStr(cr)
end match
else "UNKNOWN_SUBSCRIPT"
end subscriptStr;
template contextCref(ComponentRef cr, Context context, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Generates code for a component reference depending on which context we're in."
::=
let &varDeclsCref = buffer "" /*BUFD*/
match context
case FUNCTION_CONTEXT(__) then crefStr(cr)
else '<%cref1(cr, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDeclsCref, stateDerVectorName, useFlatArrayNotation)%>'
end contextCref;
template contextCref2(ComponentRef cr, Context context)
"Generates code for a component reference depending on which context we're in."
::=
match context
case FUNCTION_CONTEXT(__) then crefStr(cr)
else ""
end contextCref2;
template contextFunName(String funName, Context context)
"Generates a name in the Functions object depending on the context we're in."
::=
match context
case FUNCTION_CONTEXT(__) then '<%funName%>'
else '_functions-><%funName%>'
end contextFunName;
template contextIteratorName(Ident name, Context context)
"Generates code for an iterator variable."
::=
System.unquoteIdentifier(name) + "_"
end contextIteratorName;
template crefWithIndex(ComponentRef cr, Context context, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl,
Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Return cref with index for the lhs of a for loop, i.e., _resistori_P_i."
::=
match cr
case CREF_QUAL(__) then
"_" + crefToCStrWithIndex(cr, context, varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, stateDerVectorName /*=__zDot*/, useFlatArrayNotation)
end match
end crefWithIndex;
template crefToCStrWithIndex(ComponentRef cr, Context context, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl,
Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Helper function to crefWithIndex."
::=
let &preExp = buffer ""
let tmp = ""
match cr
case CREF_QUAL(__) then
let identTmp = '<%System.unquoteIdentifier(ident)%>'
match listHead(subscriptLst)
case INDEX(__) then
match exp case e as CREF(__) then
let tmp = daeExpCrefRhs(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
'<%identTmp%><%tmp%><%subscriptsToCStrForArray(subscriptLst)%>_P_<%crefToCStr(componentRef,useFlatArrayNotation)%>'
end match
end match
else "CREF_NOT_IDENT_OR_QUAL"
end crefToCStrWithIndex;
template cref1(ComponentRef cr, SimCode simCode ,Text& extraFuncs,Text& extraFuncsDecl,Text extraFuncsNamespace, Context context, Text &varDecls, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) ::=
match cr
case CREF_QUAL(ident = "$PRE") then
'_discrete_events->pre(<%cref1(componentRef, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDecls, stateDerVectorName, useFlatArrayNotation)%>)'
case CREF_IDENT(ident = "xloc") then
'<%representationCref(cr, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDecls, stateDerVectorName, useFlatArrayNotation)%>'
case CREF_IDENT(ident = "time") then
match context
case ALGLOOP_CONTEXT(genInitialisation=false)
then "_system->_simTime"
else "_simTime"
end match
case CREF_QUAL(ident = "$START") then '<%representationCref(componentRef, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDecls, stateDerVectorName, useFlatArrayNotation)%>'
else '<%representationCref(cr, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDecls, stateDerVectorName, useFlatArrayNotation)%>'
end cref1;
template representationCref(ComponentRef inCref, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text &varDecls, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) ::=
match context
case FUNCTION_CONTEXT() then
'<%crefStr(inCref)%>'
else
let representation = cref2simvar(inCref, simCode) |> var as SIMVAR(varKind=varKind, index=i, matrixName=matrixName) =>
match varKind
case STATE() then
'__z[<%i%>]'
case STATE_DER() then
'__zDot[<%i%>]'
case DAE_RESIDUAL_VAR() then
'__daeResidual[<%i%>]'
case JAC_VAR() then
'<%contextSystem(context)%>_<%getOption(matrixName)%>jac_y(<%i%>)'
case JAC_DIFF_VAR() then
'<%contextSystem(context)%>_<%getOption(matrixName)%>jac_tmp(<%i%>)'
case SEED_VAR() then
'<%contextSystem(context)%>_<%getOption(matrixName)%>jac_x(<%i%>)'
case VARIABLE() then
match var
case SIMVAR(index=-2) then
// unknown in cref2simvar, e.g. local in a function, iterator or time
'<%localCref(inCref, useFlatArrayNotation)%>'
else
match context
case ALGLOOP_CONTEXT(genInitialisation = false, genJacobian=false) then
'_system-><%cref(inCref, useFlatArrayNotation)%>'
case ALGLOOP_CONTEXT(genInitialisation = false, genJacobian=true) then
'_system->_<%crefToCStr(inCref,false)%>'
case JACOBIAN_CONTEXT() then
'_<%crefToCStr(inCref, false)%>'
else
'<%cref(inCref, useFlatArrayNotation)%>'
else
'<%contextSystem(context)%><%cref(inCref, useFlatArrayNotation)%>'
'<%representation%>'
end representationCref;
template arraycref(ComponentRef cr, Boolean useFlatArrayNotation)
::=
match cr
case CREF_IDENT(ident = "xloc") then crefStr(cr)
case CREF_IDENT(ident = "time") then "_simTime"
case WILD(__) then ''
else "_"+crefToCStr1(cr, useFlatArrayNotation)
end arraycref;
template arraycref2(ComponentRef cr, Text& dims)
::=
match cr
case CREF_IDENT(ident = "xloc") then crefStr(cr)
case CREF_IDENT(ident = "time") then "_simTime"
case WILD(__) then ''
else "_"+crefToCStrForArray(cr,dims)
end arraycref2;
template cref2(ComponentRef cr, Boolean useFlatArrayNotation)
"Generates C equivalent name for component reference."
::=
match cr
case CREF_IDENT(ident = "xloc") then '<%crefStr(cr)%>'
case CREF_IDENT(ident = "time") then "_simTime"
case WILD(__) then ''
else "_"+crefToCStr(cr,useFlatArrayNotation)
end cref2;
template crefToCStr(ComponentRef cr, Boolean useFlatArrayNotation)
"Helper function to cref."
::=
match cr
case CREF_IDENT(__) then
let subs = if Flags.isSet(Flags.NF_SCALARIZE) then subscriptsToCStr(subscriptLst, useFlatArrayNotation)
'<%System.unquoteIdentifier(ident)%>_<%subs%>'
case CREF_QUAL(__) then
let subs = if Flags.isSet(Flags.NF_SCALARIZE) then subscriptsToCStrForArray(subscriptLst)
'<%System.unquoteIdentifier(ident)%><%subs%>_P_<%crefToCStr(componentRef, useFlatArrayNotation)%>'
case WILD(__) then ''
else "CREF_NOT_IDENT_OR_QUAL"
end crefToCStr;
template contextSystem(Context context)
"Dereference _system in algloop context"
::=
match context
case ALGLOOP_CONTEXT(genInitialisation = false) then
'_system->'
else
''
end contextSystem;
template daeExpCrefRhs(Exp exp, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs,
Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Generates code for a component reference on the right hand side of an
expression."
::=
match exp
// A record cref without subscripts (i.e. a record instance) is handled
// by daeExpRecordCrefRhs only in a simulation context, not in a function.
case CREF(componentRef = cr, ty = t as T_COMPLEX(complexClassType = RECORD(path = _))) then
match context case FUNCTION_CONTEXT(__) then
'<%daeExpCref(false, exp, context, &preExp, &varDecls,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'
else
daeExpRecordCrefRhs(t, cr, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case CREF(ty = T_FUNCTION_REFERENCE_FUNC(functionType=t)) then
functionClosure(underscorePath(crefToPathIgnoreSubs(componentRef)), "", t, t, context, &extraFuncsDecl)
case CREF(componentRef = CREF_IDENT(ident=ident), ty = T_FUNCTION_REFERENCE_VAR(__)) then
contextFunName(ident, context)
else
daeExpCref(false, exp, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
end daeExpCrefRhs;
template daeExpCref(Boolean isLhs, Exp ecr, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs,
Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Generates code for a component reference."
::=
match ecr
case component as CREF(componentRef=cr, ty=T_FUNCTION(path=name)) then
underscorePath(name)
case component as CREF(componentRef=cr, ty=ty) then
let box = daeExpCrefRhsArrayBox(cr, ty, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
if box then
box
else if crefIsScalar(cr, context) then
contextCref(cr, context, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
else
if boolAnd(intEq(listLength(crefSubs(cr)), listLength(crefDims(cr))), crefSubIsScalar(cr)) then
// The array subscript results in a scalar
let arrName = contextCref(crefStripLastSubs(cr), context,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let arrayType = expTypeShort(ty)
let dimsValuesStr = (crefSubs(cr) |> INDEX(__) =>
daeExp(exp, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode , &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
;separator=",")
match arrayType
case "metatype_array" then
'arrayGet(<%arrName%>,<%dimsValuesStr%>) /* DAE.CREF */'
else
<<
<%arrName%>(<%dimsValuesStr%>)
>>
else
// The array subscript denotes a slice
let arrName = contextArrayCref(cr, context)
let arrTypeStr = if isLhs then 'ArraySlice' else 'ArraySliceConst'
let elTypeStr = expTypeShort(ty)
let slice = daeExpCrefIndexSpec(crefSubs(cr), context, &preExp,
&varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace,
stateDerVectorName, useFlatArrayNotation)
let &preExp += '<%arrTypeStr%><<%elTypeStr%>> <%slice%>_as(<%arrName%>, <%slice%>);<%\n%>'
'<%slice%>_as'
end daeExpCref;
template daeExpCrefIndexSpec(list<Subscript> subs, Context context,
Text &preExp, Text &varDecls, SimCode simCode,
Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace,
Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Generates index spec of an array as temporary vector<Slice>."
::=
let tmp_slice = tempDecl("vector<Slice>", &varDecls /*BUFD*/)
let &preExp += '<%tmp_slice%>.clear();<%\n%>'
let _ = (subs |> sub hasindex i1 =>
match sub
case INDEX(__) then
let expPart = daeExp(exp, context, &preExp /*BUFC*/, &varDecls /*BUFD*/,simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let &preExp += '<%tmp_slice%>.push_back(Slice(<%expPart%>));<%\n%>'
''
case WHOLEDIM(__) then
let &preExp += '<%tmp_slice%>.push_back(Slice());<%\n%>'
''
case SLICE(__) then
match exp
case RANGE(__) then
let start_exp = daeExp(start, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let stop_exp = daeExp(stop, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let step_exp = match step case SOME(stepExp) then daeExp(stepExp, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation) else "1"
let &preExp += '<%tmp_slice%>.push_back(Slice(<%start_exp%>, <%step_exp%>, <%stop_exp%>));<%\n%>'
''
else
// default branch if exp is no range
let expPart = daeExp(exp, context, &preExp /*BUFC*/, &varDecls /*BUFD*/, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let &preExp += '<%tmp_slice%>.push_back(Slice(<%expPart%>));<%\n%>'
''
end match
;separator="\n ")
'<%tmp_slice%>'
end daeExpCrefIndexSpec;
template daeExpCrefRhsArrayBox(ComponentRef cr, DAE.Type ty, Context context, Text &preExp,
Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl,
Text extraFuncsNamespace, Text stateDerVectorName, Boolean useFlatArrayNotation)
"Helper to daeExpCrefRhs."
::=
match context
case FUNCTION_CONTEXT(__) then
''
else
let box = cref2simvar(cr, simCode) |> var as SIMVAR(index=i, matrixName=matrixName) =>
match varKind
case STATE()
case STATE_DER()
case DAE_RESIDUAL_VAR() then
let arrdata = representationCref(cr, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDecls, stateDerVectorName, useFlatArrayNotation)
daeExpCrefRhsArrayBox2(arrdata, ty, false, context, preExp, varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)
case JAC_VAR()
case JAC_DIFF_VAR()
case SEED_VAR() then
let arrdata = representationCref(cr, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDecls, stateDerVectorName, useFlatArrayNotation)
daeExpCrefRhsArrayBox2(arrdata, ty, true, context, preExp, varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)
else
match ty
case t as T_ARRAY(ty=aty, dims=dims) then
match cr
case CREF_QUAL(ident = "$PRE") then
let arr = arrayCrefCStr(componentRef, context)
let ndims = listLength(dims)
let dimstr = checkDimension(dims)
let T = expTypeShort(aty)
let &preExp +=
<<
StatArrayDim<%ndims%><<%T%>, <%dimstr%>> <%arr%>_pre;
std::transform(<%arr%>.getData(),
<%arr%>.getData() + <%arr%>.getNumElems(),
<%arr%>_pre.getData(),
PreArray2CArray<<%T%>>(_discrete_events));
>>
'<%arr%>_pre'
else
''
else ''
'<%box%>'
end daeExpCrefRhsArrayBox;
template daeExpCrefRhsArrayBox2(Text arrayData, DAE.Type ty, Boolean isRowMajorData, Context context, Text &preExp /*BUFP*/,
Text &varDecls /*BUFP*/, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace)
::=
match ty
case t as T_ARRAY(ty=aty,dims=dims) then
let dimstr = checkDimension(dims)
let arrayType = match dimstr
case "" then 'DynArrayDim<%listLength(dims)%><<%expTypeShort(ty)%>>'
else 'StatArrayDim<%listLength(dims)%><<%expTypeShort(ty)%>,<%dimstr%>>'
end match
let &tmpdecl = buffer "" /*BUFD*/
let arrayVar = tempDecl(arrayType, &tmpdecl /*BUFD*/)
let arrayAssign = if isRowMajorData then
'assignRowMajorData(&<%arrayData%>, <%arrayVar%>)' else
'<%arrayVar%>.assign(&<%arrayData%>)'
let &preExp +=
<<
<%arrayType%> <%arrayVar%>;
<%arrayAssign%>;<%\n%>
>>
arrayVar
else
arrayData
end daeExpCrefRhsArrayBox2;
template daeExpRecordCrefRhs(DAE.Type ty, ComponentRef cr, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs,
Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
::=
match ty
case T_COMPLEX(complexClassType = record_state, varLst = var_lst) then
let vars = var_lst |> v => daeExp(makeCrefRecordExp(cr,v), context, &preExp, &varDecls,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
;separator=", "
let record_type_name = underscorePath(ClassInf.getStateName(record_state))
let ret_type = '<%record_type_name%>RetType'
let ret_var = tempDecl(ret_type, &varDecls)
let &preExp += '<%contextFunName(record_type_name, context)%>(<%vars%>,<%ret_var%>);<%\n%>'
'<%ret_var%>'
end daeExpRecordCrefRhs;
template crefST(ComponentRef cr, Boolean useFlatArrayNotation)
"Generates C equivalent name for component reference."
::=
match cr
case CREF_IDENT(ident = "time") then "_simTime"
case WILD(__) then ''
else crefToCStr(cr, useFlatArrayNotation)
end crefST;
template contextArrayCref(ComponentRef cr, Context context)
"Generates code for an array component reference depending on the context."
::=
match context
case FUNCTION_CONTEXT(__) then arrayCrefStr(cr)
else arrayCrefCStr(cr,context)
end contextArrayCref;
template arrayCrefStr(ComponentRef cr)
::=
match cr
case CREF_IDENT(ident = "time") then "_simTime"
case CREF_IDENT(__) then '<%System.unquoteIdentifier(ident)%>_'
case CREF_QUAL(__) then '<%System.unquoteIdentifier(ident)%>_.<%arrayCrefStr(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end arrayCrefStr;
template arrayCrefCStr(ComponentRef cr,Context context)
::=
match context
case ALGLOOP_CONTEXT(genInitialisation = false) then
let& dims = buffer "" /*BUFD*/
<< _system->_<%crefToCStrForArray(cr,dims)%> >>
else
let& dims = buffer "" /*BUFD*/
'_<%crefToCStrForArray(cr,dims)%>'
end arrayCrefCStr;
template arrayCrefCStr2(ComponentRef cr)
::=
match cr
case CREF_IDENT(__) then '<%unquoteIdentifier(ident)%>'
case CREF_QUAL(__) then '<%unquoteIdentifier(ident)%>_P_<%arrayCrefCStr2(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end arrayCrefCStr2;
template crefTypeST(ComponentRef cr) "template crefType
Like cref but with cast if type is integer."
::=
match cr
case CREF_IDENT(__) then '<%expTypeShortSPS(identType)%>'
case CREF_QUAL(__) then '<%crefTypeST(componentRef)%>'
else "crefType:ERROR"
end match
end crefTypeST;
template crefTypeMLPI(ComponentRef cr) "template crefType
Like cref but with cast if type is integer."
::=
match cr
case CREF_IDENT(__) then '<%expTypeShortMLPI(identType)%>'
case CREF_QUAL(__) then '<%crefTypeMLPI(componentRef)%>'
else "crefType:ERROR"
end match
end crefTypeMLPI;
template crefStartValueType(ComponentRef cr)
"Returns type string for get/set<type>StartValue methods."
::=
match cr
case CREF_IDENT(__) then
let typeShort = expTypeShort(identType)
let typeString = if stringEq(typeShort, "double") then "Real"
else if stringEq(typeShort, "int") then "Int"
else if stringEq(typeShort, "bool") then
let booltype = match Config.simCodeTarget()
case "Cpp" then
"Bool"
case "omsicpp" then
"Int"
end match
booltype
else if stringEq(typeShort, "string") then "String"
else if stringEq(typeShort, "void*") then "ExternalObject"
else 'ERROR:crefStartValueType <%typeShort%> '
'<%typeString%>'
case CREF_QUAL(__) then
'<%crefStartValueType(componentRef)%>'
else
'crefStartValueType:ERROR'
end match
end crefStartValueType;
/*******************************************************************************************************************************************************
* end of cref to string template functions
*******************************************************************************************************************************************************/
/*******************************************************************************************************************************************************
* type to string template functions
*******************************************************************************************************************************************************/
template dimension(Dimension d,Context context)
::=
match d
case DAE.DIM_BOOLEAN(__) then '2'
case DAE.DIM_INTEGER(__) then integer
case DAE.DIM_ENUM(__) then size
case DAE.DIM_EXP(exp=e) then dimensionExp(e,context, false)
case DAE.DIM_UNKNOWN(__) then '-1'//error(sourceInfo(),"Unknown dimensions may not be part of generated code. This is most likely an error on the part of OpenModelica. Please submit a detailed bug-report.")
else error(sourceInfo(), 'dimension: INVALID_DIMENSION')
end dimension;
template checkDimension(Dimensions dims)
::=
let dimstr = dimensionsList(dims) |> dim as Integer => '<%dim%>';separator=","
// check for unknown dimension that is treated as -1
if intEq(-1, stringFind(dimstr, "-")) then
dimstr
else
""
end checkDimension;
template checkExpDimension(list<DAE.Exp> dims)
::=
expDimensionsList(dims) |> dim as Integer => '<%dim%>';separator=","
end checkExpDimension;
template listDimsFlat(Dimensions dims, Type elty)
"return list of dimensions of form 'd1, d2, ..., dn', flattening subarrays"
::=
let dimstr = checkDimension(dims)
match dimstr
case "" then
''
else
match elty
case T_ARRAY(dims=subdims, ty=subty) then
let subdimstr = listDimsFlat(subdims, subty)
match subdimstr
case "" then
''
else
'<%dimstr%>, <%subdimstr%>'
end match
else
dimstr
end listDimsFlat;
template nDimsFlat(Dimensions dims, Type elty, Integer offset)
"return number of dimensions, flattening subarrays"
::=
match elty
case T_ARRAY(dims=subdims, ty=subty) then
nDimsFlat(subdims, subty, intAdd(listLength(dims), offset))
else
intAdd(listLength(dims), offset)
end nDimsFlat;
template expTypeShort(DAE.Type type)
"Returns the base type name for declarations"
::=
match type
case T_INTEGER(__) then "int"
case T_REAL(__) then "double"
case T_STRING(__) then if acceptMetaModelicaGrammar() then "metatype" else "string"
case T_BOOL(__) then "bool"
case T_ENUMERATION(__) then "int"
case T_UNKNOWN(__) then "double /*W1*/" // assumming real for unknown type
case T_ANYTYPE(__) then "complex2"
case T_SUBTYPE_BASIC(__) then expTypeShort(complexType)
case T_ARRAY(__) then expTypeShort(ty)
case T_COMPLEX(complexClassType=EXTERNAL_OBJ(__)) then "void*"
case T_COMPLEX(__) then '<%underscorePath(ClassInf.getStateName(complexClassType))%>Type'
case T_METATYPE(__)
case T_METABOXED(__) then "metatype"
case T_FUNCTION(__)
case T_FUNCTION_REFERENCE_FUNC(__)
case T_FUNCTION_REFERENCE_VAR(__) then "fnptr"
else 'expTypeShort:ERROR <%unparseType(type)%> '
end expTypeShort;
template expTypeFlag(DAE.Type ty, Integer flag)
"Returns code for a type, depending on flag"
::=
match flag
case 1 then
// we want the short type
expTypeShort(ty)
case 2 then
// we want the "modelica type"
match ty case T_COMPLEX(complexClassType=EXTERNAL_OBJ(__)) then
'<%expTypeShort(ty)%>'
else match ty case T_COMPLEX(complexClassType=RECORD(path=rname)) then
'<%underscorePath(rname)%>Type'
else match ty case T_COMPLEX(__) then
'<%underscorePath(ClassInf.getStateName(complexClassType))%>'
else
'<%expTypeShort(ty)%>'
case 3 then
// we want the "array type", static if dims are known, dynamic otherwise
match ty
case T_ARRAY(ty=elty, dims=dims) then
expTypeArrayDims(elty, dims)
else
'ERROR:expTypeFlag3 no array'
end match
case 4 then
// we want the "array type" only if type is array, otherwise "modelica type"
match ty
case T_ARRAY(ty=elty, dims=dims) then
expTypeArrayDims(elty, dims)
else
expTypeFlag(ty, 2)
end match
case 5 then
match ty
case T_ARRAY(dims=dims) then
//let testbasearray = dims |> dim => '<%testdimension(dim)%>' ;separator=''
let dimstr = checkDimension(dims)
match dimstr
case "" then 'const DynArrayDim<%listLength(dims)%><<%expTypeShort(ty)%>>&'
else 'const StatArrayDim<%listLength(dims)%><<%expTypeShort(ty)%>,<%dimstr%>>&'
else expTypeFlag(ty, 2)
end match
case 6 then
expTypeFlag(ty, 4)
case 7 then
match ty
case T_ARRAY(dims=dims)
then
'multi_array<<%expTypeShort(ty)%>,<%listLength(dims)%>>'
end match
case 8 then
match ty
case T_ARRAY(dims=dims) then 'const BaseArray<<%expTypeShort(ty)%>>&'
else expTypeFlag(ty, 9)
end match
case 9 then
// we want the "modelica type"
match ty case T_COMPLEX(complexClassType=EXTERNAL_OBJ(__)) then
'<%expTypeShort(ty)%>'
else match ty case T_COMPLEX(complexClassType=RECORD(path=rname)) then
'const <%underscorePath(rname)%>Type&'
else match ty case T_COMPLEX(__) then
'const <%underscorePath(ClassInf.getStateName(complexClassType))%>&'
else
'<%expTypeShort(ty)%>'
end expTypeFlag;
template crefType(ComponentRef cr) "template crefType
Like cref but with cast if type is integer."
::=
match cr
case CREF_IDENT(__) then expTypeArrayIf(identType)
case CREF_QUAL(__) then crefType(componentRef)
else "crefType:ERROR"
end match
end crefType;
template expTypeFromExpShort(Exp exp)
::=
expTypeFromExpFlag(exp, 1)
end expTypeFromExpShort;
template expTypeFromExpModelica(Exp exp)
::=
expTypeFromExpFlag(exp, 2)
end expTypeFromExpModelica;
template expTypeFromExpArray(Exp exp)
::=
expTypeFromExpFlag(exp, 4)
end expTypeFromExpArray;
template expTypeShortSPS(DAE.Type type)
::=
match type
case T_INTEGER(__) then "INT"
case T_REAL(__) then "LREAL"
case T_STRING(__) then if acceptMetaModelicaGrammar() then "metatype" else "string"
case T_BOOL(__) then "BOOL"
case T_ENUMERATION(__) then "INT"
/* assumming real for uknown type! */
case T_UNKNOWN(__) then "LREAL"
case T_ANYTYPE(__) then "type not supported"
case T_ARRAY(__) then expTypeShortSPS(ty)
case T_COMPLEX(complexClassType=EXTERNAL_OBJ(__))
then "type not supported"
case T_COMPLEX(__) then '<%underscorePath(ClassInf.getStateName(complexClassType))%>Type'
case T_METATYPE(__) case T_METABOXED(__) then "type not supported"
case T_FUNCTION(__)
case T_FUNCTION_REFERENCE_FUNC(__)
case T_FUNCTION_REFERENCE_VAR(__) then "type not supported"
else "expTypeShort:ERROR"
end expTypeShortSPS;
template expTypeShortMLPI(DAE.Type type)
::=
match type
case T_INTEGER(__) then "MLPI_IEC_INT"
case T_REAL(__) then "MLPI_IEC_LREAL"
case T_STRING(__) then if acceptMetaModelicaGrammar() then "metatype" else "string"
case T_BOOL(__) then "MLPI_IEC_BOOL"
case T_ENUMERATION(__) then "MLPI_IEC_INT"
/* assumming real for uknown type! */
case T_UNKNOWN(__) then "MLPI_IEC_LREAL"
case T_ANYTYPE(__) then "type not supported"
case T_ARRAY(__) then expTypeShortSPS(ty)
case T_COMPLEX(complexClassType=EXTERNAL_OBJ(__))
then "type not supported"
case T_COMPLEX(__) then '<%underscorePath(ClassInf.getStateName(complexClassType))%>Type'
case T_METATYPE(__) case T_METABOXED(__) then "type not supported"
case T_FUNCTION(__)
case T_FUNCTION_REFERENCE_FUNC(__)
case T_FUNCTION_REFERENCE_VAR(__) then "type not supported"
else "expTypeShort:ERROR"
end expTypeShortMLPI;
template expType(DAE.Type ty, Boolean isArray)
"Generate type helper."
::=
if isArray
then 'expType_<%expTypeArray1(ty,0)%>_NOT_YET'
else expTypeShort(ty)
end expType;
template expTypeModelica(DAE.Type ty)
"Generate type helper."
::=
expTypeFlag(ty, 2)
end expTypeModelica;
template expTypeArray(DAE.Type ty)
"Returns the array type"
::=
expTypeFlag(ty, 3)
end expTypeArray;
template expTypeArrayIf(DAE.Type ty)
"Generate type helper."
::=
expTypeFlag(ty, 4)
end expTypeArrayIf;
template expTypeArray1(DAE.Type ty, Integer dims) ::=
<<
SimArray<%dims%><<%expTypeShort(ty)%>>
>>
end expTypeArray1;
template expTypeArrayDims(DAE.Type elty, DAE.Dimensions dims)
"Generate type string for static or dynamic array, depending on dims"
::=
let typeShort = expTypeShort(elty)
let dimstr = listDimsFlat(dims, elty)
match dimstr
case "" then
'DynArrayDim<%nDimsFlat(dims, elty, 0)%><<%typeShort%>>'
else
'StatArrayDim<%nDimsFlat(dims, elty, 0)%><<%typeShort%>, <%dimstr%>>'
end match
end expTypeArrayDims;
template allocateDimensions(DAE.Type ty,Context context)
::=
match ty
case T_ARRAY(dims=dims) then
let dimstr = dims |> dim => '<%dimension(dim,context)%>' ;separator=','
<<
<%dimstr%>
>>
end allocateDimensions;
/*******************************************************************************************************************************************************
* end of type to string template functions
********************************************************************************************************************************************************/
/*******************************************************************************************************************************************************
* string for temp var template functions
********************************************************************************************************************************************************/
template tempDecl(String ty, Text &varDecls /*BUFP*/)
"Declares a temporary variable in varDecls and returns the name."
::=
let newVar = 'tmp<%System.tmpTick()%>'
let &varDecls += '<%ty%> <%newVar%>;<%\n%>'
newVar
end tempDecl;
template tempDeclAssign(String ty, Text &varDecls /*BUFP*/,String assign)
"Declares a temporary variable in varDecls and returns the name."
::=
let newVar = 'tmp<%System.tmpTick()%>'
let &varDecls += '<%ty%> <%newVar%> = <%assign%>;<%\n%>'
newVar
end tempDeclAssign;
template tempDecl1(String ty, String exp, Text &varDecls /*BUFP*/)
"Declares a temporary variable in varDecls and returns the name."
::=
let newVar = 'tmp<%System.tmpTick()%>'
let newVar1 = '<%newVar%>(<%exp%>)'
let &varDecls += '<%ty%> <%newVar1%>;<%\n%>'
newVar
end tempDecl1;
/*******************************************************************************************************************************************************
end string for temp var template functions
********************************************************************************************************************************************************/
/*******************************************************************************************************************************************************
exp to string template functions
********************************************************************************************************************************************************/
template dimensionExp(DAE.Exp dimExp,Context context,Boolean useFlatArrayNotation)
::=
match dimExp
case DAE.CREF(componentRef = cr) then
match context
case FUNCTION_CONTEXT(__) then System.unquoteIdentifier(crefStr(cr))
else '<%cref(cr, useFlatArrayNotation)%>'
else '/* fehler dimensionExp: INVALID_DIMENSION <%ExpressionDumpTpl.dumpExp(dimExp,"\"")%>*/' //error(sourceInfo(), 'dimensionExp: INVALID_DIMENSION <%ExpressionDumpTpl.dumpExp(dimExp,"\"")%>')
end dimensionExp;
template daeDimensionExp(Exp exp)
"Generates code for an expression."
::=
match exp
case e as ICONST(__) then '<%integer%>'
else '-1'
end daeDimensionExp;
template daeExp(Exp exp, Context context, Text &preExp /*BUFP*/, Text &varDecls /*BUFP*/,SimCode simCode ,Text& extraFuncs,Text& extraFuncsDecl,Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Generates code for an expression."
::=
match exp
case e as ICONST(__) then integer
case e as RCONST(__) then real
case e as BCONST(__) then if bool then "true" else "false"
case e as SCONST(__) then daeExpSconst(string, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as CLKCONST(__) then error(sourceInfo(), 'Unsupported CLKCONST exp:<%ExpressionDumpTpl.dumpExp(e,"\"")%>')
case e as ENUM_LITERAL(__) then index
case e as CREF(__) then daeExpCrefRhs(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as CAST(__) then daeExpCast(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as CONS(__) then error(sourceInfo(), 'Unsupported CONS exp:<%ExpressionDumpTpl.dumpExp(e,"\"")%>')
case e as UNARY(__) then daeExpUnary(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as LBINARY(__) then daeExpLbinary(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as LUNARY(__) then daeExpLunary(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as BINARY(__) then daeExpBinary(operator, exp1, exp2, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as IFEXP(__) then daeExpIf(expCond, expThen, expElse, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as RELATION(__) then daeExpRelation(e, context, &preExp, &varDecls,simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as CALL(__) then daeExpCall(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as RECORD(__) then daeExpRecord(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as TUPLE(__) then error(sourceInfo(), 'Unsupported TUPLE exp:<%ExpressionDumpTpl.dumpExp(e,"\"")%>')
case e as ASUB(__) then '<%daeExpAsub(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'
case e as MATRIX(__) then daeExpMatrix(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as RANGE(__) then '<%daeExpRange(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'
case e as TSUB(__) then '<%daeExpTsub(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation )%>'
case e as REDUCTION(__) then daeExpReduction(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as ARRAY(__) then '<%daeExpArray(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>'
case e as SIZE(__) then daeExpSize(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as SHARED_LITERAL(__) then daeExpSharedLiteral(e, context, &preExp, &varDecls, useFlatArrayNotation)
case e as PARTEVALFUNCTION(__)then daeExpPartEvalFunction(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as BOX(__) then daeExpBox(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as UNBOX(__) then daeExpUnbox(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as RSUB(__) then daeExpRSub(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as METARECORDCALL(__) then daeExpRecordCall(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
case e as META_TUPLE(__) then error(sourceInfo(), 'Unsupported META_TUPLE exp:<%ExpressionDumpTpl.dumpExp(e,"\"")%>')
case e as META_OPTION(__) then error(sourceInfo(), 'Unsupported META_OPTION exp:<%ExpressionDumpTpl.dumpExp(e,"\"")%>')
case e as MATCHEXPRESSION(__) then error(sourceInfo(), 'Unsupported MATCHEXPRESSION exp:<%ExpressionDumpTpl.dumpExp(e,"\"")%>')
else error(sourceInfo(), 'Unknown exp:<%ExpressionDumpTpl.dumpExp(exp,"\"")%>')
end daeExp;
template daeExpRSub(Exp exp, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl,
Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)
"Generates code for an tsub expression."
::=
match exp
case RSUB(ix=-1) then
let res = daeExp(exp, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)