source: trunk/Compiler/ModelicaCBackEnd/src/jastadd/CCodeGen/CGenerator.jrag @ 12423

Last change on this file since 12423 was 12423, checked in by Jonathan Kämpe, 9 months ago

#5736 Merging r12400 to trunk

File size: 58.1 KB
Line 
1
2/*
3Copyright (C) 2009 Modelon AB
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, version 3 of the License.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program.  If not, see <http://www.gnu.org/licenses/>.
16*/
17
18/** \file CGenerator.java
19*  CGenerator class.
20*/
21
22import java.io.*;
23
24public class CGenerator extends GenericGenerator {
25   
26    protected static final String INDENT = "    ";
27   
28    /**
29     * C: external function includes
30     */
31    public class DAETag_C_externalFuncIncludes extends DAETag {
32       
33        public DAETag_C_externalFuncIncludes(AbstractGenerator myGenerator, FClass fclass) {
34            super("external_func_includes", myGenerator, fclass);
35        }
36       
37        public void generate(CodeStream genPrinter) {
38            for (String incl : fclass.externalIncludes()) 
39                genPrinter.println(incl);
40        }
41    }
42
43    /**
44     * C: scaling_method
45     */
46    public class DAETag_C_scalingMethod extends DAETag {
47       
48        public DAETag_C_scalingMethod(AbstractGenerator myGenerator, FClass fclass) {
49            super("C_DAE_scaling_method", myGenerator, fclass);
50        }
51   
52        public void generate(CodeStream genPrinter) {
53            if (fclass.myOptions().getBooleanOption("enable_variable_scaling")) {
54                genPrinter.print("JMI_SCALING_VARIABLES");
55            } else {
56                genPrinter.print("JMI_SCALING_NONE");
57            }
58        }
59   
60    }
61   
62    /**
63     * Base class for tags generating an array and the size of the array.
64     */
65    public abstract class DAEArrayTag<T extends ASTNode> extends DAETag {
66       
67        private String varName;
68        private String nullValue;
69        private String type;
70       
71        public DAEArrayTag(String name, AbstractGenerator myGenerator, FClass fclass, 
72                String varName, String type, String nullValue) {
73            super(name, myGenerator, fclass);
74            this.varName = varName;
75            this.type = type;
76            this.nullValue = nullValue;
77        }
78       
79        public void generate(CodeStream str) {
80            Collection<T> elems = elements();
81            int n = numElements(elems);
82            str.print("static const int N_", varName, " = ", n, ";\n");
83           
84            str.print("static const ", type, " DAE_", varName, "[] = { ");
85           
86            if (n == 0) {
87                str.print(nullValue);
88            } else {
89                boolean first = true;
90                for (T e : elems) {
91                    if (first)
92                        first = false;
93                    else
94                        str.print(", ");
95                    generateFor(e, str);
96                }
97            }
98            str.print(" };");
99        }
100       
101        protected int numElements(Collection<T> elems) {
102            return elems.size();
103        }
104       
105        protected abstract Collection<T> elements();
106       
107        protected abstract void generateFor(T e, CodeStream str);
108       
109    }
110
111    /**
112     * C: relational operator kind, <, >, <=, <=
113     */
114    public class DAETag_C_initial_relations extends DAEArrayTag<FRelExp> {
115       
116        public DAETag_C_initial_relations(AbstractGenerator myGenerator, FClass fclass) {
117            super("C_DAE_initial_relations", myGenerator, fclass, "initial_relations", "int", "-1");
118        }
119       
120        protected Collection<FRelExp> elements() {
121            return fclass.eventExpInInitialEquations();
122        }
123       
124        protected void generateFor(FRelExp e, CodeStream genPrinter) {
125            e.genRelExpKind(genPrinter);
126        }
127   
128    }
129
130    /**
131     * C: relational operator kind, <, >, <=, <=
132     */
133    public class DAETag_C_relations extends DAEArrayTag<FExp> {
134       
135        public DAETag_C_relations(AbstractGenerator myGenerator, FClass fclass) {
136            super("C_DAE_relations", myGenerator, fclass, "relations", "int", "-1");
137        }
138       
139        @Override
140        protected Collection<FExp> elements() {
141            return fclass.stateEventExps();
142        }
143       
144        @Override
145        protected int numElements(Collection<FExp> elems) {
146            return fclass.numEventIndicators();
147        }
148       
149        protected void generateFor(FExp e, CodeStream genPrinter) {
150            e.genRelExpKind(genPrinter);
151        }
152       
153    }
154   
155    /**
156     * C: nominal values
157     */
158    public class DAETag_C_nominals extends DAEArrayTag<FVariable> {
159       
160        public DAETag_C_nominals(AbstractGenerator myGenerator, FClass fclass) {
161            super("C_DAE_nominals", myGenerator, fclass, "nominals", "jmi_real_t", "0.0");
162        }
163       
164        protected Collection<FVariable> elements() {
165            return fclass.differentiatedRealVariables();
166        }
167       
168        protected void generateFor(FVariable e, CodeStream genPrinter) {
169            genPrinter.print(StrictMath.abs(e.nominalAttribute()));
170        }
171   
172    }
173
174   
175    /**
176     * C: equation residuals
177     */
178    public class DAETag_C_equationResiduals extends DAETag {
179       
180        public DAETag_C_equationResiduals(AbstractGenerator myGenerator, FClass fclass) {
181            super("C_DAE_equation_residuals", myGenerator, fclass);
182            addOptions("generate_dae");
183        }
184   
185        public void generate(CodeStream genPrinter) {
186            for (FAbstractEquation e : fclass.equations()) 
187                e.genVarDecls_C(ASTNode.printer_C, genPrinter, INDENT);
188            Enumerator enumerator = new Enumerator();
189            for (FAbstractEquation e : fclass.equations())
190                e.genResidual_C(ASTNode.printer_C, genPrinter, INDENT, enumerator, null, null);
191        }
192   
193    }
194
195    /**
196     * C: event indicator residuals in equations
197     */
198    public class DAETag_C_eventIndicatorResiduals extends DAETag {
199       
200        public DAETag_C_eventIndicatorResiduals(AbstractGenerator myGenerator, FClass fclass) {
201            super("C_DAE_event_indicator_residuals", myGenerator, fclass);
202        }
203   
204        public void generate(CodeStream genPrinter) {
205            CodePrinter p = ASTNode.printer_C.eventIndicatorPrinter();
206            if (!fclass.onlyInitBLT()) {
207                ASTNode.genFunctionStart(genPrinter, INDENT);
208                for (FExp e : fclass.stateEventExps()) 
209                    e.genEventResidualVarDecls_C(p, genPrinter, INDENT);
210                Enumerator enumerator = new Enumerator();
211                for (FExp e : fclass.stateEventExps())
212                    e.genEventResidual_C(p, genPrinter, INDENT, enumerator);
213                ASTNode.genFunctionEnd(genPrinter, INDENT);
214            } else {
215                genPrinter.print("  model_init_R0(jmi, res);\n");
216            }
217        }
218   
219    }
220
221    /**
222     * C: initial equation residuals
223     */
224    public class DAETag_C_initialEquationResiduals extends DAETag {
225       
226        public DAETag_C_initialEquationResiduals(AbstractGenerator myGenerator, FClass fclass) {
227            super("C_DAE_initial_equation_residuals", myGenerator, fclass);
228            addOptions("generate_dae");
229        }
230   
231        public void generate(CodeStream genPrinter) {
232            CodePrinter printer = ASTNode.printer_C.initialSystemPrinter();
233            for (FAbstractEquation e : fclass.equations()) 
234                e.genVarDecls_C(printer, genPrinter, INDENT);
235            for (FAbstractEquation e : fclass.initialEquations()) 
236                e.genVarDecls_C(printer, genPrinter, INDENT);
237            Enumerator enumerator = new Enumerator();
238            for (FAbstractEquation e : fclass.equations())
239                e.genResidual_C(printer, genPrinter, INDENT, enumerator, null, null);
240            for (FAbstractEquation e : fclass.initialEquations())
241                e.genResidual_C(printer, genPrinter, INDENT, enumerator, null, null);
242        }   
243    }
244
245    /**
246     * C: event indicator residuals in initial equations
247     */
248    public class DAETag_C_initialEventIndicatorResiduals extends DAETag {
249       
250        public DAETag_C_initialEventIndicatorResiduals(AbstractGenerator myGenerator, FClass fclass) {
251            super("C_DAE_initial_event_indicator_residuals", myGenerator, fclass);
252        }
253   
254        public void generate(CodeStream genPrinter) {
255            ASTNode.genFunctionStart(genPrinter, INDENT);
256            CodePrinter printer = ASTNode.printer_C.initialSystemPrinter().eventIndicatorPrinter();
257            for (FExp e : fclass.stateEventExps()) 
258                e.genEventResidualVarDecls_C(printer, genPrinter, INDENT);
259            for (FExp e : fclass.eventExpInInitialEquations()) 
260                e.genEventResidualVarDecls_C(printer, genPrinter, INDENT);
261            Enumerator enumerator = new Enumerator();
262            for (FExp e : fclass.stateEventExps())
263                e.genEventResidual_C(printer, genPrinter, INDENT, enumerator);
264            for (FExp e : fclass.eventExpInInitialEquations())
265                e.genEventResidual_C(printer, genPrinter, INDENT, enumerator);
266            ASTNode.genFunctionEnd(genPrinter, INDENT);
267        }
268    }
269   
270    /**
271     * C: initial guess equation residuals
272     */
273    public class DAETag_C_initialGuessEquationResiduals extends DAETag {
274       
275        public DAETag_C_initialGuessEquationResiduals(AbstractGenerator myGenerator, FClass fclass) {
276            super("C_DAE_initial_guess_equation_residuals", myGenerator, fclass);
277        }
278   
279        public void generate(CodeStream genPrinter) {
280            for (FRealVariable fv : fclass.realVariables())
281                if (!fv.isFixed()) {
282                    fv.genVarDecls_C(ASTNode.printer_C, genPrinter, INDENT);
283                }
284            Enumerator enumerator = new Enumerator();
285            for (FRealVariable fv : fclass.realVariables())
286                if (!fv.isFixed()) {
287                    fv.genStartAttributeResidual_C(ASTNode.printer_C, genPrinter, INDENT, enumerator);
288                }
289        }
290   
291    }
292
293    /**
294     * C: dependent parameter residuals
295     */
296    public class DAETag_C_initialDependentParameterResiduals extends DAETag {
297       
298        public DAETag_C_initialDependentParameterResiduals(AbstractGenerator myGenerator, FClass fclass) {
299            super("C_DAE_initial_dependent_parameter_residuals", myGenerator, fclass);
300            addOptions("generate_dae");
301        }
302   
303        public void generate(CodeStream genPrinter) {
304            Enumerator enumerator = new Enumerator();
305            for (FAbstractEquation e : fclass.getParameterEquations())
306                e.genResidual_C(ASTNode.printer_C, genPrinter, INDENT, enumerator, null, null);
307        }
308   
309    }
310
311    /**
312     * C: macros for C variable aliases
313     */
314    public class DAETag_C_variableAliases extends DAETag {
315       
316        public DAETag_C_variableAliases(AbstractGenerator myGenerator, FClass fclass) {
317            super("C_variable_aliases", myGenerator, fclass);
318        }
319       
320        private class Visitor implements FClass.ZVisitor {
321
322            private static final String FMT_DEFAULT       = 
323                    "#define %s ((*(jmi->z))[jmi->offs%s_%s+%d])\n";
324            private static final String FMT_DEFAULT_INDEX = 
325                    "#define %s ((*(jmi->z))[%d])\n";
326            private static final String FMT_DEFAULT_STRING = 
327                    "#define %s (jmi->z_t.strings.values[jmi->z_t.strings.offs.wp+%d])\n";
328            private static final String FMT_DEFAULT_STRING_INDEX = 
329                    "#define %s (jmi->z_t.strings.values[%d])\n";
330            private static final String FMT_EXTERNAL      = 
331                    "#define %s ((jmi->ext_objs)[%d])\n";
332            private static final String FMT_VIRTUAL_FIRST = 
333                    "#define _%s ((*(jmi->z))[jmi->offs_%s])\n";
334            private static final String FMT_VIRTUAL       = 
335                    "#define _%s ((*(jmi->z))[jmi->offs_%s + %d])\n";
336           
337            private boolean pre;
338            private String prefix;
339            private CodeStream cs;
340
341            public Visitor(CodeStream cs, boolean pre) {
342                this.pre = pre;
343                prefix = pre ? "_pre" : "";
344                this.cs = cs;
345            }
346
347            public void visitVariable(FVariable fv, FClass.ZCategoryEntry entry) {
348                switch (entry.category().zStructVector()) {
349                case DEFAULT:
350                    if (pre) { //TODO: Should also be changed to direct index once the mapping from pre to index is defined
351                        cs.format(FMT_DEFAULT, fv.preName_C(), prefix, entry.category().zOffsetName(), entry.getOffsetIndexFor(fv));
352                    } else {
353                        cs.format(FMT_DEFAULT_INDEX, fv.name_C(), entry.getIndexFor(fv));
354                    }
355                    break;
356                case STRING:
357                    if (pre) {
358                        cs.format(FMT_DEFAULT_STRING, fv.preName_C(), entry.getOffsetIndexFor(fv));
359                    } else {
360                        cs.format(FMT_DEFAULT_STRING_INDEX, fv.name_C(), entry.getIndexFor(fv));
361                    }
362                    break;
363                case EXTERNAL:
364                    cs.format(FMT_EXTERNAL, fv.name_C(), entry.getOffsetIndexFor(fv));
365                    break;
366                }
367            }
368
369            public void visitVirtualVariable(String name, String zOffsetName, int offset) {
370                String format = (offset == 0) ? FMT_VIRTUAL_FIRST : FMT_VIRTUAL;
371                cs.format(format, name, zOffsetName, offset);
372            }
373
374        }
375
376        public void generate(CodeStream genPrinter) {
377            fclass.varRefMap().visitZOrder(new Visitor(genPrinter, false), false);
378            if (fclass.myOptions().getBooleanOption("generate_ode")) {
379                fclass.varRefMap().visitZOrder(new Visitor(genPrinter, true), true);
380            }
381        }
382    }
383
384    class ZOffsets {
385        private LinkedHashListMap<TypePrefixVariability.VariabilityCausality_C, FVariable> m = 
386                new LinkedHashListMap<TypePrefixVariability.VariabilityCausality_C, FVariable>();
387       
388        public ZOffsets(Collection<? extends FVariable> fvs) {
389            for (FVariable fv : fvs) {
390                m.add(fv.variabilityCausality_C(), fv);
391            }
392        }
393       
394        public int size() {
395            int res = 0;
396            for (java.util.List<FVariable> l : m.values()) {
397                res = res + l.size();
398            }
399            return res;
400        }
401       
402        public java.util.List<FVariable> get(TypePrefixVariability.VariabilityCausality_C s) {
403            return m.getList(s);
404        }
405    }
406   
407    public class DAETag_C_z_stringOffsets extends DAETag {
408       
409        public DAETag_C_z_stringOffsets(AbstractGenerator myGenerator, FClass fclass) {
410            super("C_z_offsets_strings", myGenerator, fclass);
411        }
412       
413        public void generate(CodeStream str) {
414            ZOffsets zo = new ZOffsets(fclass.strings());
415            int o = 0;
416            o = genList(str, fclass.numIndependentStringConstants()           , o, TypePrefixVariability.VariabilityCausality_C.CI);
417            o = genList(str, fclass.numDependentStringConstants()             , o, TypePrefixVariability.VariabilityCausality_C.CD);
418            o = genList(str, fclass.numRegularIndependentStringParameters()   , o, TypePrefixVariability.VariabilityCausality_C.PI);
419            o = genList(str, fclass.numStructuralIndependentStringParameters(), o, TypePrefixVariability.VariabilityCausality_C.PS);
420            o = genList(str, fclass.numFinalIndependentStringParameters()     , o, TypePrefixVariability.VariabilityCausality_C.PF);
421            o = genList(str, fclass.numEvalIndependentStringParameters()      , o, TypePrefixVariability.VariabilityCausality_C.PE);
422            o = genList(str, fclass.numDependentStringParameters()            , o, TypePrefixVariability.VariabilityCausality_C.PD);
423            int nStringVariables = fclass.numDiscreteStringVariables() + fclass.numStringInputs();
424            o = genList(str, nStringVariables                                 , o, TypePrefixVariability.VariabilityCausality_C.W);
425            o = genList(str, nStringVariables                                 , o, TypePrefixVariability.VariabilityCausality_C.WP);
426            str.print("z->n = ", o, ";\n");
427        }
428       
429        int genList(CodeStream str, int n, int o, TypePrefixVariability.VariabilityCausality_C s) {
430            str.print("z->offs.", s, " = ", o, ";\n");
431            str.print("z->nums.", s, " = ", n, ";\n");
432            return o + n;
433        }
434    }
435   
436   
437    /**
438     * Generates code for BLT block residuals
439     */
440    /**
441     * C: C functions for the DAE BLT block residuals
442     */
443    public class DAETag_C_dae_blocks_residual_functions extends DAETag {
444       
445        public DAETag_C_dae_blocks_residual_functions(AbstractGenerator myGenerator, FClass fclass) {
446            super("C_dae_blocks_residual_functions", myGenerator, fclass);
447            addOptions("generate_ode");
448        }
449       
450        @Override
451        public boolean isActive() {
452            return !fclass.onlyInitBLT() && super.isActive();
453        }
454
455        public void generate(CodeStream genPrinter) {
456            String indent = "";
457            int generateSparseThreshold = fclass.myOptions().getIntegerOption("generate_sparse_block_jacobian_threshold");
458            for (AbstractEquationBlock block : fclass.getDAEStructuredBLT().getAllBlocks()) {
459                CodePrinter printer = block.blockPrinter();
460                block.genBlockResidualFunction(printer, genPrinter, indent, generateSparseThreshold);
461                if (block.isLinear() && generateSparseThreshold < block.localSolvedRealVariables().size()) {
462                    block.genBlockResidualFunction_sparse_jacobian(printer, genPrinter, indent, false);
463                }
464            }
465        }
466    }
467
468    /**
469     * Generates code for adding BLT blocks
470     */
471    /**
472     * C: Add the DAE block functions to the JMI struct
473     */
474    public class DAETag_C_dae_add_blocks_residual_functions extends DAETag {
475
476        public DAETag_C_dae_add_blocks_residual_functions(AbstractGenerator myGenerator, FClass fclass) {
477            super("C_dae_add_blocks_residual_functions", myGenerator, fclass);
478            addOptions("generate_ode");
479        }
480
481        @Override
482        public boolean isActive() {
483            return !fclass.onlyInitBLT() && super.isActive();
484        }
485
486        public void generate(CodeStream genPrinter) {
487            CodePrinter p = ASTNode.printer_C;
488            String indent = p.indent("");
489            OptionRegistry options = fclass.myOptions();
490
491            for (AbstractEquationBlock block : fclass.getDAEStructuredBLT().getAllBlocks())
492                block.genBlockAddCall_C(p, genPrinter, indent, false,
493                        false, block.isLinear() && options.getIntegerOption("generate_sparse_block_jacobian_threshold") < block.localSolvedRealVariables().size(),
494                        options.getStringOption("nonlinear_solver"), -1);
495        }
496    }
497
498    /**
499     * Number of DAE blocks
500     */
501    /**
502     * C: Number of DAE blocks
503     */
504    public class DAETag_C_dae_n_blocks extends DAETag {
505       
506        public DAETag_C_dae_n_blocks(AbstractGenerator myGenerator, FClass fclass) {
507            super("n_dae_blocks", myGenerator, fclass);
508        }
509
510        public void generate(CodeStream genPrinter) {
511            if (fclass.onlyInitBLT())
512                genPrinter.print("0");
513            else
514                genPrinter.print(fclass.getDAEBLT().getNumLabledBlocks());
515        }
516    }
517
518    /**
519     * Generates code for BLT block residuals (DAE initialization system)
520     */
521    /**
522     * C: C functions for the DAE BLT block residuals
523     */
524    public class DAETag_C_dae_init_blocks_residual_functions extends DAETag {
525
526        public DAETag_C_dae_init_blocks_residual_functions(AbstractGenerator myGenerator, FClass fclass) {
527            super("C_dae_init_blocks_residual_functions", myGenerator, fclass);
528            addOptions("generate_ode");
529        }
530
531        public void generate(CodeStream genPrinter) {
532            String indent = "";
533           
534            int generateSparseThreshold = fclass.myOptions().getIntegerOption("generate_sparse_block_jacobian_threshold");
535
536            for (AbstractEquationBlock block : fclass.getDAEInitBLT()) {
537                CodePrinter printer = block.blockPrinter().initialSystemPrinter();
538                block.genBlockResidualFunction(printer, genPrinter, indent, generateSparseThreshold);
539
540                if (block.isLinear() && generateSparseThreshold < block.localSolvedRealVariables().size()) {
541                    block.genBlockResidualFunction_sparse_jacobian(printer, genPrinter, indent, true);
542                }
543            } 
544        }
545    }
546
547    /**
548     * Generates code for adding BLT blocks
549     */
550    /**
551     * C: Add the DAE initialization block functions to the JMI struct
552     */
553    public class DAETag_C_dae_init_add_blocks_residual_functions extends DAETag {
554
555        public DAETag_C_dae_init_add_blocks_residual_functions(AbstractGenerator myGenerator, FClass fclass) {
556            super("C_dae_init_add_blocks_residual_functions", myGenerator, fclass);
557            addOptions("generate_ode");
558        }
559
560        public void generate(CodeStream genPrinter) {
561            CodePrinter p = ASTNode.printer_C;
562            String indent = p.indent("");
563            OptionRegistry options = fclass.myOptions();
564
565            for (AbstractEquationBlock block : fclass.getDAEInitBLT())
566                block.genBlockAddCall_C(p, genPrinter, indent, false,
567                        true, block.isLinear() && options.getIntegerOption("generate_sparse_block_jacobian_threshold") < block.localSolvedRealVariables().size(),
568                        fclass.myOptions().getStringOption("init_nonlinear_solver"), -1);
569        }
570    }
571
572    /**
573     * Number of DAE initialization blocks
574     */
575    /**
576     * C: Number of DAE initialization blocks
577     */
578    public class DAETag_C_dae_init_n_blocks extends DAETag {
579       
580        public DAETag_C_dae_init_n_blocks(AbstractGenerator myGenerator, FClass fclass) {
581            super("n_dae_init_blocks", myGenerator, fclass);
582        }
583
584        public void generate(CodeStream genPrinter) {
585            genPrinter.print(fclass.getDAEInitBLT().getNumLabledBlocks());
586        }
587    }
588
589    /**
590     * Generates code for computing the guard expressions
591     */
592    /**
593     * C: Compute guard expressions ODE
594     */
595    public class DAETag_C_ode_guards extends DAETag {
596       
597        public DAETag_C_ode_guards(AbstractGenerator myGenerator, FClass fclass) {
598            super("C_ode_guards", myGenerator, fclass);
599            addOptions("generate_ode");
600        }
601
602        public void generate(CodeStream str) {
603            if (!fclass.onlyInitBLT()) {
604                for (FExp e : fclass.guardExpInEquations()) 
605                    e.genVarDecls_C(ASTNode.printer_C, str, INDENT);
606                int i=0;
607                for (FExp e : fclass.guardExpInEquations()) {
608                    str.print("  _guards(" + i + ") = ");
609                    ASTNode.printer_C.print(e, str, "");
610                    str.print(";\n");       
611                    i++;
612                }
613            } else {
614                str.print("  model_ode_guards_init(jmi);\n");
615            }
616        }
617    }
618
619    /**
620     * Generates code for computing the guard expressions in the initial equations
621     */
622    /**
623     * C: Compute guard expressions ODE initialization system
624     */
625    public class DAETag_C_ode_guards_init extends DAETag {
626       
627        public DAETag_C_ode_guards_init(AbstractGenerator myGenerator, FClass fclass) {
628            super("C_ode_guards_init", myGenerator, fclass);
629            addOptions("generate_ode");
630        }
631
632        public void generate(CodeStream genPrinter) {
633            CodePrinter printer = ASTNode.printer_C.initialSystemPrinter();
634            for (FExp e : fclass.guardExpInInitialEquations()) 
635                e.genVarDecls_C(printer, genPrinter, INDENT);
636            int i=0;
637            for (FExp e : fclass.guardExpInInitialEquations()) {
638                genPrinter.print("  _guards_init(" + i + ") = ");
639                e.prettyPrint_C(printer, genPrinter,"");
640                genPrinter.print(";\n");
641                i++;
642            }
643        }
644    }
645
646    /**
647     * Generates code for computation of the nect time event.
648     */
649    /**
650     * C: Compute the next time event.
651     */
652    public class DAETag_C_ode_time_events extends DAETag {
653       
654        public DAETag_C_ode_time_events(AbstractGenerator myGenerator, FClass fclass) {
655            super("C_ode_time_events", myGenerator, fclass);
656            addOptions("generate_ode");
657        }
658
659        @Override
660        public boolean isActive() {
661            return !fclass.onlyInitBLT() && super.isActive();
662        }
663       
664        public void generate(CodeStream str) {
665            CodePrinter p = ASTNode.printer_C.eventIndicatorPrinter();
666            String indent = p.indent("");
667            for (FExp e : fclass.timeEventExps()) 
668                e.genTimeEventVarDecls_C(p, str, INDENT);
669           
670            str.formatln("%sjmi_real_t nSamp;", indent);
671            for (FExp e : fclass.timeEventExps()) {
672                e.genTimeEvent_C(p, str, indent, "nextTimeEvent");
673            }
674        }
675    }
676   
677    /**
678     * Generates code for solving the BLT blocks
679     */
680    /**
681     * C: Compute derivatives of the ODE
682     */
683    public class DAETag_C_ode_derivatives extends DAETag {
684       
685        public DAETag_C_ode_derivatives(AbstractGenerator myGenerator, FClass fclass) {
686            super("C_ode_derivatives", myGenerator, fclass);
687        }
688
689        public void generate(CodeStream str) {
690            CodePrinter p = ASTNode.printer_C;
691            String indent = "";
692            String next = p.indent(indent);
693           
694            CodeSplitter<AbstractEquationBlock> cs = new CodeSplitter<AbstractEquationBlock>(p, str, next, true,
695                    "model_ode_derivatives", fclass.myOptions()) {
696                @Override
697                public void genDecl(AbstractEquationBlock element) {
698                    element.genVarDecls(p, str, indent);
699                }
700                @Override
701                public void genPre(AbstractEquationBlock element) {
702                    element.genReinitTempInits_C(p, str, indent);
703                }
704                @Override
705                public void gen(AbstractEquationBlock element) {
706                    element.genSolvedInBLT(p, str, indent);
707                }
708                @Override
709                public void genPost(AbstractEquationBlock element) {
710                    //element.genReinitWritebacks_C(p, indent, str);
711                }
712            };
713           
714            if (!fclass.onlyInitBLT() && fclass.myOptions().getBooleanOption("generate_ode")) {
715                cs.add(fclass.getDAEStructuredBLT().getAllBlocks());
716            }
717           
718            cs.genFuncImpls();
719           
720            cs.genFuncHeads();
721           
722            str.print("int model_ode_derivatives_base(jmi_t* jmi) {\n");
723            cs.printStatusDecl();
724            if (fclass.onlyInitBLT()) {
725                str.print(next + "ef = model_ode_initialize(jmi);\n");
726            } else {
727                cs.genFuncCalls();
728            }
729            cs.printStatusReturn();
730            str.print("}\n");
731        }
732    }
733   
734    /**
735     * Generates code for solving the BLT blocks in the initialization system
736     */
737    /**
738     * C: Solve the initialization system
739     */
740    public class DAETag_C_ode_initialization extends DAETag {
741       
742        public DAETag_C_ode_initialization(AbstractGenerator myGenerator, FClass fclass) {
743            super("C_ode_initialization", myGenerator, fclass);
744        }
745
746        public void generate(CodeStream str) {
747           
748            CodePrinter p = ASTNode.printer_C.initialSystemPrinter();
749            String indent = "";
750            String next = p.indent(indent);
751           
752            CodeSplitter<AbstractEquationBlock> cs = new CodeSplitter<AbstractEquationBlock>(p, str, next, true,
753                    "model_ode_initialize", fclass.myOptions()) {
754                @Override
755                public void genDecl(AbstractEquationBlock element) {
756                    element.genVarDecls(p, str, indent);
757                }
758                @Override
759                public void genPre(AbstractEquationBlock element) {
760                    element.genReinitTempInits_C(p, str, indent);
761                }
762                @Override
763                public void gen(AbstractEquationBlock element) {
764                    element.genSolvedInBLT(p, str, indent);
765                }
766                @Override
767                public void genPost(AbstractEquationBlock element) {
768                    //element.genReinitWritebacks_C(p, indent, str);
769                }
770            };
771           
772            if (fclass.myOptions().getBooleanOption("generate_ode")) {
773                cs.add(fclass.getDAEInitBLT());
774            }
775           
776            cs.genFuncImpls();
777           
778            cs.genFuncHeads();
779           
780            str.print("int model_ode_initialize_base(jmi_t* jmi) {\n");
781            cs.printStatusDecl();
782            cs.genFuncCalls();
783            cs.printStatusReturn();
784            str.print("}\n");
785        }
786    }
787
788    /**
789     * Generates code for solving the BLT blocks for computing the outputs
790     */
791    /**
792     * C: Compute the ODE outputs
793     */
794    public class DAETag_C_ode_outputs extends DAETag {
795       
796        public DAETag_C_ode_outputs(AbstractGenerator myGenerator, FClass fclass) {
797            super("C_ode_outputs", myGenerator, fclass);
798        }
799
800        public void generate(CodeStream genPrinter) {
801        }
802    }
803   
804    /**
805     * Generates headers for Modelica functions.
806     */
807    /**
808     * C: C function headers representing Modelica functions
809     */
810    public class DAETag_C_function_headers extends DAETag {
811       
812        public DAETag_C_function_headers(AbstractGenerator myGenerator, FClass fclass) {
813            super("C_function_headers", myGenerator, fclass);
814        }
815
816        public void generate(CodeStream str) {
817            fclass.generateFunctionHeaders(ASTNode.printer_C, str, "");
818        }
819    }
820   
821    /**
822     * Generates definitions for Modelica functions.
823     */
824    /**
825     * C: C functions representing Modelica functions
826     */
827    public class DAETag_C_functions extends DAETag {
828       
829        public DAETag_C_functions(AbstractGenerator myGenerator, FClass fclass) {
830            super("C_functions", myGenerator, fclass);
831        }
832
833        public void generate(CodeStream str) {
834            for (FFunctionDecl func : fclass.myFFunctionDeclsPartialCalled()) {
835                func.prettyPrintPartial_C(ASTNode.printer_C, str, "");
836            }
837            for (FFunctionDecl func : fclass.getFFunctionDecls()) {
838                ASTNode.printer_C.print(func, str, "");
839            }
840        }
841    }
842   
843    /**
844     * Generates structs for Modelica records.
845     */
846    /**
847     * C: C structs representing Modelica records
848     */
849    public class DAETag_C_records extends DAETag {
850       
851        public DAETag_C_records(AbstractGenerator myGenerator, FClass fclass) {
852            super("C_records", myGenerator, fclass);
853        }
854
855        public void generate(CodeStream str) {
856            for (FRecordDecl rec : fclass.getFRecordDecls()) {
857                ASTNode.printer_C.print(rec, str, "");
858            }
859        }
860    }
861   
862    /**
863     * Generates string representations of enumeration literals.
864     */
865    /**
866     * C: string representations of enumeration literals
867     */
868    public class DAETag_C_enums_strings extends DAETag {
869       
870        public DAETag_C_enums_strings(AbstractGenerator myGenerator, FClass fclass) {
871            super("C_enum_strings", myGenerator, fclass);
872        }
873
874        public void generate(CodeStream str) {
875            for (FEnumDecl e : fclass.getFEnumDecls()) {
876                ASTNode.printer_C.print(e, str, "");
877            }
878        }
879    }
880   
881    /**
882     * Generates wrappers for Modelica functions for exporting in a shared library.
883     */
884    /**
885     * C: C functions wrapping internal representation of Modelica functions
886     */
887    public class DAETag_C_export_functions extends DAETag {
888       
889        public DAETag_C_export_functions(AbstractGenerator myGenerator, FClass fclass) {
890            super("C_export_functions", myGenerator, fclass);
891            addOptions("export_functions");
892        }
893
894        public void generate(CodeStream out) {
895            for (FFunctionDecl func : fclass.getFFunctionDecls())
896                if (func.hasExportWrapper_C())
897                    func.exportWrapper_C(out, "");
898        }
899    }
900   
901    /**
902     * Generates export wrappers for groups of Modelica functions with the same signature.
903     *
904     * Allows less functions to be imported from resulting shared library.
905     * Requires $C_export_functions$, and must be after it.
906     */
907    /**
908     * C: C functions wrapping groups of export function with same signature
909     */
910    public class DAETag_C_export_wrappers extends DAETag {
911       
912        public DAETag_C_export_wrappers(AbstractGenerator myGenerator, FClass fclass) {
913            super("C_export_wrappers", myGenerator, fclass);
914            addOptions("export_functions_vba");
915        }
916
917        public void generate(CodeStream out) {
918            // TODO: refactor out parts not specific to VBA to make it
919            //       easier to support other platforms with special needs
920            int i = 0;
921            String ind = ASTNode.printer_C.indent("");
922            for (java.util.List<FFunctionDecl> grp : fclass.exportWrapperGroups()) {
923                FFunctionDecl first = grp.get(0);
924                String type = first.exportWrapperType_C();
925                String name = "select_vba_" + (++i);
926               
927                out.format("char* %s_names[] = { ", name);
928                String fmt = "\"%s\"";
929                for (FFunctionDecl f : grp) {
930                    out.format(fmt, f.getFAccess().nameUnderscore());
931                    fmt = ", \"%s\"";
932                }
933                out.print(" };\n");
934               
935                out.format("int %s_lengths[] = { ", name);
936                fmt = "%d";
937                for (FFunctionDecl f : grp) {
938                    out.format(fmt, f.getFAccess().nameUnderscore().length());
939                    fmt = ", %d";
940                }
941                out.print(" };\n");
942               
943                out.format("%s (*%s_funcs[])(", type, name);
944                first.exportWrapperArgumentTypeDecl_C(out);
945                out.print(") = { ");
946                fmt = "*%s";
947                for (FFunctionDecl f : grp) {
948                    out.format(fmt, f.funcNameExportWrapper());
949                    fmt = ", *%s";
950                }
951                out.print(" };\n");
952               
953                String sep = first.myInputs().isEmpty() ? "" : ", "; 
954                out.format("DllExport %s __stdcall %s(char* name%s", type, name, sep);
955                first.exportWrapperArgumentDecl_C(out);
956                out.print(") {\n");
957                out.format("%sint i, j;\n", ind);
958                out.format("%sfor (i = 0, j = 0; name[i] != 0; i++) \n", ind);
959                out.format("%s%swhile (j < %d && i <= %s_lengths[j] && name[i] > %s_names[j][i]) j++;\n", ind, ind, grp.size(), name, name);
960                out.format("%sif (j >= %d || strcmp(%s_names[j], name)) return 0;\n", ind, grp.size(), name);
961                out.format("%sreturn %s_funcs[j](", ind, name);
962                first.exportWrapperArgumentCall_C(out);
963                out.print(");\n");
964                out.print("}\n\n");
965            }
966        }
967    }
968
969    /**
970     * C: DAE output value references
971     */
972    public class DAETag_C_outputVrefs extends DAETag {
973       
974        public DAETag_C_outputVrefs(AbstractGenerator myGenerator, FClass fclass) {
975            super("C_DAE_output_vrefs", myGenerator, fclass);
976        }
977   
978        public void generate(CodeStream genPrinter) {
979
980            if (fclass.numOutputs()>0) {
981                genPrinter.print("static const int Output_vrefs[" + 
982                    fclass.numOutputs() + "] = {");     
983
984                int ind = 0;
985                for (FVariable fv : fclass.outputs()) {
986                    genPrinter.print(fv.valueReference());
987                    if (ind < fclass.numOutputs()-1) {
988                        genPrinter.print(",");
989                    }   
990                    ind++;
991                }       
992                genPrinter.print("};\n");
993            } else {
994                genPrinter.print("static const int Output_vrefs[1] = {-1};");
995            } 
996        }   
997    }
998
999    /**
1000     * Generates MODEL_IDENTIFIER.
1001     */
1002    /**
1003     * C: Model identifier
1004     */
1005    public class DAETag_C_model_id extends DAETag {
1006       
1007        public DAETag_C_model_id(AbstractGenerator myGenerator, FClass fclass) {
1008            super("C_model_id", myGenerator, fclass);
1009        }
1010
1011        public void generate(CodeStream genPrinter) {
1012            genPrinter.print(fclass.nameUnderscore());
1013        }
1014    }
1015   
1016    /**
1017     * Generates JM_VERSION.
1018     */
1019    /**
1020     * C: JModelica version
1021     */
1022    public class DAETag_C_jmodelica_version extends DAETag {
1023       
1024        public DAETag_C_jmodelica_version(AbstractGenerator myGenerator, FClass fclass) {
1025            super("C_jmodelica_version", myGenerator, fclass);
1026        }
1027       
1028        public void generate(CodeStream genPrinter) {
1029            genPrinter.print(Version.parseVersion());
1030        }
1031    }
1032
1033    /**
1034     * Generates GUID.
1035     */
1036    /**
1037     * C: GUID
1038     */
1039    public class DAETag_C_guid extends DAETag {
1040       
1041        public DAETag_C_guid(AbstractGenerator myGenerator, FClass fclass) {
1042            super("C_guid", myGenerator, fclass);
1043        }
1044
1045        public void generate(CodeStream genPrinter) {
1046            genPrinter.print("\""+fclass.guidManager().getGuidToken()+"\"");
1047        }
1048    }
1049
1050    /**
1051     * C: block number for the block that contains homotopy
1052     */
1053    public class DAETag_C_DAE_INIT_homotopy_block extends DAETag {
1054       
1055        public DAETag_C_DAE_INIT_homotopy_block(AbstractGenerator myGenerator, FClass fclass) {
1056            super("C_DAE_INIT_homotopy_block", myGenerator, fclass);
1057        }
1058   
1059        public void generate(CodeStream genPrinter) {
1060            int num = -1;
1061            if (fclass.myOptions().getBooleanOption("generate_ode")) {
1062                for (AbstractEquationBlock block : fclass.getDAEInitBLT()) {
1063                    if (block.containsFHomotopyExp()) {
1064                        if (num != -1) {
1065                            throw new UnsupportedOperationException("There is more than one block which contains homotopy operator, this should not be possible!");
1066                        } else {
1067                            num = block.getSequenceNumber();
1068                        }
1069                    }
1070                }
1071            }
1072            genPrinter.print(num);
1073        }
1074   
1075    }
1076
1077    public class DAETag_model_init_eval_independent_start extends DAETag {
1078       
1079        public DAETag_model_init_eval_independent_start(AbstractGenerator myGenerator, FClass fclass) {
1080            super("C_model_init_eval_independent_start", myGenerator, fclass);
1081        }
1082       
1083        public void generate(CodeStream str) {
1084            CodePrinter p = ASTNode.printer_C;
1085            String indent = "";
1086            String next = p.indent(indent);
1087           
1088            CodeSplitter<FVariable> splitter = new CodeSplitter<FVariable>(p, str, next, true,
1089                    "model_init_eval_independent_start", fclass.myOptions()) {
1090                @Override
1091                public void genDecl(FVariable element) {
1092                    p.printVarDecls(element, str, indent);
1093                }
1094                @Override
1095                public void gen(FVariable element) {
1096                    element.genStartValue_C(p, str, indent);
1097                }
1098            };
1099            splitter.add(fclass.independentConstants());
1100            splitter.add(fclass.dependentConstants());
1101            splitter.add(fclass.independentParameters());
1102           
1103            for (FVariable fv : fclass.initialParameters()) {
1104                if (!fv.hasParameterEquation() && !fv.hasDependentStartValue()) {
1105                    splitter.add(fv);
1106                }
1107            }
1108            for (FVariable fv : fclass.variables()) {
1109                if (!fv.hasDependentStartValue()) {
1110                    splitter.add(fv);
1111                }
1112            }
1113            for (FVariable fv : fclass.discretePreVariables()) {
1114                if (!fv.hasDependentStartValue()) {
1115                    splitter.add(fv);
1116                }
1117            }
1118            splitter.generate();
1119        }
1120    }
1121   
1122    public class DAETag_model_init_eval_dependent extends DAETag {
1123       
1124        public DAETag_model_init_eval_dependent(AbstractGenerator myGenerator, FClass fclass) {
1125            super("C_model_init_eval_dependent_parameters", myGenerator, fclass);
1126        }
1127       
1128        public void generate(CodeStream str) {
1129            CodePrinter p = ASTNode.printer_C;
1130            String indent = "";
1131            String next = p.indent(indent);
1132           
1133            CodeSplitter<FAbstractEquation> splitter = new CodeSplitter<FAbstractEquation>(p, str, next, 
1134                    true, "model_init_eval_dependent_parameters", fclass.myOptions(), fclass.getParameterEquations().toArrayList()) {
1135                @Override
1136                public void genDecl(FAbstractEquation element) {
1137                    p.printVarDecls(element, str, indent);
1138                }
1139                @Override
1140                public void gen(FAbstractEquation element) {
1141                    element.genAssignment_C(p, str, indent);
1142                }
1143            };
1144            splitter.generate();
1145        }
1146    }
1147   
1148    public class DAETag_model_init_eval_dependent_variables extends DAETag {
1149       
1150        public DAETag_model_init_eval_dependent_variables(AbstractGenerator myGenerator, FClass fclass) {
1151            super("C_model_init_eval_dependent_variables", myGenerator, fclass);
1152        }
1153       
1154        public void generate(CodeStream str) {
1155            CodePrinter p = ASTNode.printer_C;
1156            String indent = "";
1157            String next = p.indent(indent);
1158           
1159            CodeSplitter<FVariable> splitter = new CodeSplitter<FVariable>(p, str, next, true,
1160                    "model_init_eval_dependent_variables", fclass.myOptions()) {
1161                @Override
1162                public void genDecl(FVariable element) {
1163                    p.printVarDecls(element, str, indent);
1164                }
1165                @Override
1166                public void gen(FVariable element) {
1167                    element.genStartValue_C(p, str, indent);
1168                }
1169            };
1170            for (FVariable fv : fclass.initialParameters()) {
1171                if (fv.hasParameterEquation() || fv.hasDependentStartValue()) {
1172                    splitter.add(fv);
1173                }
1174            }
1175            for (FVariable fv : fclass.variables()) {
1176                if (fv.hasDependentStartValue()) {
1177                    splitter.add(fv);
1178                }
1179            }
1180            for (FVariable fv : fclass.discretePreVariables()) {
1181                if (fv.hasDependentStartValue()) {
1182                    splitter.add(fv);
1183                }
1184            }
1185            splitter.generate();
1186        }
1187    }
1188   
1189    /**
1190     * Generates mapping between runtime option names and value references for the
1191     * associated parameters.
1192     */
1193    /**
1194     * C: runtime option name map
1195     */
1196    public class DAETag_C_runtime_option_map extends DAETag {
1197       
1198        public DAETag_C_runtime_option_map(AbstractGenerator myGenerator, FClass fclass) {
1199            super("C_runtime_option_map", myGenerator, fclass);
1200        }
1201
1202        public void generate(CodeStream genPrinter) {
1203            genPrinter.print("const char *fmi_runtime_options_map_names[] = {\n");
1204            for (FVariable fv : fclass.runtimeOptionParameters())
1205                genPrinter.println("    \"" + fv.name() + "\",");
1206            genPrinter.print("    NULL\n};\n\n");
1207
1208            genPrinter.print("const int fmi_runtime_options_map_vrefs[] = {\n    ");
1209            int i = 0;
1210            for (FVariable fv : fclass.runtimeOptionParameters()) 
1211                genPrinter.print(fv.valueReference() + ((++i % 10) == 0 ? ",\n    " : ", "));
1212            genPrinter.print("0\n};\n\n");
1213
1214            genPrinter.print("const int fmi_runtime_options_map_length = " + fclass.numRuntimeOptionParameters() + ";");
1215        }
1216    }
1217   
1218    /**
1219     * Generates calls to the destructors of all external objects.
1220     */
1221    public class DAETag_C_destruct_external_object extends DAETag {
1222       
1223        public DAETag_C_destruct_external_object(AbstractGenerator myGenerator, FClass fclass) {
1224            super("C_destruct_external_object", myGenerator, fclass);
1225        }
1226
1227        public void generate(CodeStream str) {
1228            CodePrinter p = ASTNode.printer_C;
1229            for (FVariable eo : fclass.externalObjectVariables()) {
1230                eo.genDestructorCall_C(p, str, p.indent(""));
1231            }
1232            for (FGlobalVariable eo : fclass.getFGlobalVariables()) {
1233                eo.genDestructorCall_C(p, str, p.indent(""));
1234            }
1235        }
1236    }
1237   
1238    /**
1239     * Prints number of delay blocks.
1240     */
1241    public class DAETag_n_delays extends DAETag {
1242       
1243        public DAETag_n_delays(AbstractGenerator myGenerator, FClass fclass) {
1244            super("n_delays", myGenerator, fclass);
1245        }
1246       
1247        public void generate(CodeStream genPrinter) {
1248            genPrinter.print(fclass.myDelayExps().size());
1249        }
1250    }
1251   
1252    /**
1253     * Prints number of delay switches needed.
1254     */
1255    public class DAETag_numDelaySwitchingFunctions extends DAETag {
1256       
1257        public DAETag_numDelaySwitchingFunctions(AbstractGenerator myGenerator, FClass fclass) {
1258            super("n_delay_switches", myGenerator, fclass);
1259        }
1260   
1261        public void generate(CodeStream genPrinter) {
1262            genPrinter.print(fclass.numDelaySwitches());
1263        }
1264   
1265    }
1266   
1267    /**
1268     * Prints number of spatialDistribution blocks.
1269     */
1270    public class DAETag_n_spatialdists extends DAETag {
1271       
1272        public DAETag_n_spatialdists(AbstractGenerator myGenerator, FClass fclass) {
1273            super("n_spatialdists", myGenerator, fclass);
1274        }
1275       
1276        public void generate(CodeStream genPrinter) {
1277            genPrinter.print(fclass.mySpatialDistExps().size());
1278        }
1279    }
1280   
1281    /**
1282     * Prints number of spatialDistribution switches needed.
1283     */
1284    public class DAETag_numSpatialDistSwitchingFunctions extends DAETag {
1285       
1286        public DAETag_numSpatialDistSwitchingFunctions(AbstractGenerator myGenerator, FClass fclass) {
1287            super("n_spatialdist_switches", myGenerator, fclass);
1288        }
1289   
1290        public void generate(CodeStream genPrinter) {
1291            genPrinter.print(fclass.numSpatialDistSwitches());
1292        }
1293   
1294    }
1295   
1296    /**
1297     * Generates statements to initialize delay blocks.
1298     */
1299    public class DAETag_C_delay_init extends DAETag {
1300       
1301        public DAETag_C_delay_init(AbstractGenerator myGenerator, FClass fclass) {
1302            super("C_delay_init", myGenerator, fclass);
1303        }
1304       
1305        public void generate(CodeStream genPrinter) {
1306            CodePrinter p = ASTNode.printer_C;
1307            String indent = p.indent("");
1308            for (FDelayExp d : fclass.myDelayExps()) {
1309                d.genInitVarDecls_C(p, genPrinter, indent);
1310            }
1311            for (FSpatialDistExp d : fclass.mySpatialDistExps()) {
1312                d.genInitVarDecls_C(p, genPrinter, indent);
1313            }
1314            for (FDelayExp d : fclass.myDelayExps()) {
1315                d.genInit_C(p, genPrinter, indent);
1316            }
1317            for (FSpatialDistExp d : fclass.mySpatialDistExps()) {
1318                d.genInit_C(p, genPrinter, indent);
1319            }
1320        }
1321    }
1322   
1323    /**
1324     * Generates statements to sample delay blocks.
1325     */
1326    public class DAETag_C_delay_sample extends DAETag {
1327       
1328        public DAETag_C_delay_sample(AbstractGenerator myGenerator, FClass fclass) {
1329            super("C_delay_sample", myGenerator, fclass);
1330        }
1331       
1332        public void generate(CodeStream genPrinter) {
1333            CodePrinter p = ASTNode.printer_C;
1334            String indent = p.indent("");
1335            for (FDelayExp d : fclass.myDelayExps()) {
1336                d.genSampleVarDecls_C(p, genPrinter, indent);
1337            }
1338            for (FSpatialDistExp d : fclass.mySpatialDistExps()) {
1339                d.genSampleVarDecls_C(p, genPrinter, indent);
1340            }
1341            for (FDelayExp d : fclass.myDelayExps()) {
1342                d.genSample_C(p, genPrinter, indent);
1343            }
1344            for (FSpatialDistExp d : fclass.mySpatialDistExps()) {
1345                d.genSample_C(p, genPrinter, indent);
1346            }
1347        }
1348    }
1349   
1350    /**
1351     * Returns the string denoting the beginning of the copyright blurb.
1352     */
1353    protected String startOfBlurb() { return "/*"; }
1354   
1355    /**
1356     * Constructor.
1357     *
1358     * @param expPrinter Printer object used to generate code for expressions.
1359     * @param escapeCharacter Escape characters used to decode tags.
1360     * @param fclass An FClass object used as a basis for the code generation.
1361     */
1362    public CGenerator(Printer expPrinter, char escapeCharacter,
1363            FClass fclass) {
1364        super(expPrinter, escapeCharacter, fclass);
1365    }
1366   
1367   
1368   
1369    public class ECETag_external_includes extends ExternalCEvalTag {
1370        public ECETag_external_includes(AbstractGenerator myGenerator, FClass fClass) {
1371            super("ECE_external_includes", myGenerator, fClass);
1372        }
1373       
1374        @Override
1375        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1376                CodeGenContext cgc, Map<String,String> tempMap) {
1377            Set<String> incs = new LinkedHashSet<String>();
1378            ext.externalDependencies(incs, null, null, null);
1379            for (String inc : incs) {
1380                str.println(inc);
1381            }
1382        }
1383    }
1384   
1385    public class ECETag_record_definitions extends ExternalCEvalTag {
1386        public ECETag_record_definitions(AbstractGenerator myGenerator, FClass fClass) {
1387            super("ECE_record_definitions", myGenerator, fClass);
1388        }
1389       
1390        @Override
1391        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1392                CodeGenContext cgc, Map<String,String> tempMap) {
1393            for (FType rec : ext.usedTypes().values()) {
1394                if (rec.isRecord()) {
1395                    p.print(rec, str, indent);
1396                }
1397            }
1398        }
1399    }
1400   
1401    public class ECETag_decl extends ExternalCEvalTag {
1402        public ECETag_decl(AbstractGenerator myGenerator, FClass fClass) {
1403            super("ECE_decl", myGenerator, fClass);
1404        }
1405       
1406        @Override
1407        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1408                CodeGenContext cgc, Map<String,String> tempMap) {
1409            indent = p.indent(indent);
1410            TypePrinter_C tp = new DeclPrinter_ECE(p, str, tempMap, cgc);
1411            for (ExternalArgument cvd : ext.externalObjectsToSerialize()) {
1412                 tp.reset(cvd.name_C(), null, cvd.type().size(), false, indent);
1413                 tp.print(cvd.type());
1414            }
1415        }
1416    }
1417   
1418    public class ECETag_free extends ExternalCEvalTag {
1419        public ECETag_free(AbstractGenerator myGenerator, FClass fClass) {
1420            super("ECE_free", myGenerator, fClass);
1421        }
1422       
1423        @Override
1424        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1425                CodeGenContext cgc, Map<String,String> tempMap) {
1426            indent = p.indent(indent);
1427            TypePrinter_C tp = new FreePrinter_ECE(p, str, tempMap, cgc);
1428            for (ExternalArgument cvd : ext.externalObjectsToSerialize()) {
1429                 tp.reset(cvd.name_C(), null, cvd.type().size(), false, indent);
1430                 tp.printExt((FExternalObjectType)cvd.type());
1431            }
1432        }
1433    }
1434   
1435    public class ECETag_setup_decl extends ExternalCEvalTag {
1436        public ECETag_setup_decl(AbstractGenerator myGenerator, FClass fClass) {
1437            super("ECE_setup_decl", myGenerator, fClass);
1438        }
1439       
1440        @Override
1441        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1442                CodeGenContext cgc, Map<String,String> tempMap) {
1443            indent = p.indent(indent);
1444            TypePrinter_C tp = new DeclPrinter_ECE(p, str, tempMap, cgc);
1445            ext.genSerializeComps_C(tp, indent, cgc, tempMap, ext.externalObjectsToSerialize());
1446        }
1447    }
1448   
1449    public class ECETag_setup_init extends ExternalCEvalTag {
1450        public ECETag_setup_init(AbstractGenerator myGenerator, FClass fClass) {
1451            super("ECE_setup_init", myGenerator, fClass);
1452        }
1453       
1454        @Override
1455        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1456                CodeGenContext cgc, Map<String,String> tempMap) {
1457            indent = p.indent(indent);
1458            TypePrinter_C tp = new InitPrinter_ECE(p, str, tempMap, cgc);
1459            ext.genSerialize_C(tp, indent, cgc, tempMap, ext.externalObjectsToSerialize());
1460        }
1461    }
1462   
1463    public class ECETag_setup_free extends ExternalCEvalTag {
1464        public ECETag_setup_free(AbstractGenerator myGenerator, FClass fClass) {
1465            super("ECE_setup_free", myGenerator, fClass);
1466        }
1467       
1468        @Override
1469        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1470                CodeGenContext cgc, Map<String,String> tempMap) {
1471            indent = p.indent(indent);
1472            TypePrinter_C tp = new FreePrinter_ECE(p, str, tempMap, cgc);
1473            ext.genSerializeComps_C(tp, indent, cgc, tempMap, ext.externalObjectsToSerialize());
1474        }
1475    }
1476   
1477    public class ECETag_calc_decl extends ExternalCEvalTag {
1478        public ECETag_calc_decl(AbstractGenerator myGenerator, FClass fClass) {
1479            super("ECE_calc_decl", myGenerator, fClass);
1480        }
1481       
1482        @Override
1483        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1484                CodeGenContext cgc, Map<String,String> tempMap) {
1485            indent = p.indent(indent);
1486            ext.setExternalArgumentAliases(cgc);
1487            TypePrinter_C tp = new DeclPrinter_ECE(p, str, tempMap, cgc);
1488            ext.genSerialize_C(tp, indent, cgc, tempMap, ext.functionArgsToSerialize());
1489            ext.genVarDecls_C(p, str, indent);
1490        }
1491    }
1492   
1493    public class ECETag_calc_init extends ExternalCEvalTag {
1494        public ECETag_calc_init(AbstractGenerator myGenerator, FClass fClass) {
1495            super("ECE_calc_init", myGenerator, fClass);
1496        }
1497       
1498        @Override
1499        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1500                CodeGenContext cgc, Map<String,String> tempMap) {
1501            indent = p.indent(indent);
1502            ext.setExternalArgumentAliases(cgc);
1503            TypePrinter_C tp = new InitPrinter_ECE(p, str, tempMap, cgc);
1504            ext.genSerialize_C(tp, indent, cgc, tempMap, ext.functionArgsToSerialize());
1505        }
1506    }
1507   
1508    public class ECETag_calc extends ExternalCEvalTag {
1509        public ECETag_calc(AbstractGenerator myGenerator, FClass fClass) {
1510            super("ECE_calc", myGenerator, fClass);
1511        }
1512       
1513        @Override
1514        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1515                CodeGenContext cgc, Map<String,String> tempMap) {
1516            indent = p.indent(p.indent(indent));
1517            ext.setExternalArgumentAliases(cgc);
1518            ext.genSerializeCalc_C(p, str, indent, cgc, tempMap);
1519        }
1520    }
1521   
1522    public class ECETag_calc_free extends ExternalCEvalTag {
1523        public ECETag_calc_free(AbstractGenerator myGenerator, FClass fClass) {
1524            super("ECE_calc_free", myGenerator, fClass);
1525        }
1526       
1527        @Override
1528        public void generate(CodePrinter p, CodeStream str, String indent, FExternalStmt ext,
1529                CodeGenContext cgc, Map<String,String> tempMap) {
1530            indent = p.indent(indent);
1531            TypePrinter_C tp = new FreePrinter_ECE(p, str, tempMap, cgc);
1532            ext.setExternalArgumentAliases(cgc);
1533            ext.genSerialize_C(tp, indent, cgc, tempMap, ext.functionArgsToSerialize());
1534        }
1535    }
1536   
1537    /**
1538     * C: Add the DAE block functions to the JMI struct
1539     */
1540    public class DAETag_C_dynamic_state_add_call extends DAETag {
1541
1542        public DAETag_C_dynamic_state_add_call(AbstractGenerator myGenerator, FClass fclass) {
1543            super("C_dynamic_state_add_call", myGenerator, fclass);
1544            addOptions("generate_ode");
1545        }
1546
1547        public void generate(CodeStream genPrinter) {
1548            CodePrinter p = ASTNode.printer_C;
1549            fclass.getDynamicStateManager().genDynamicStateAddCall_C(p, genPrinter, p.indent(""));
1550        }
1551    }
1552
1553    /**
1554     * C: C functions for the DAE BLT block residuals
1555     */
1556    public class DAETag_C_dynamic_state_coefficients extends DAETag {
1557       
1558        public DAETag_C_dynamic_state_coefficients(AbstractGenerator myGenerator, FClass fclass) {
1559            super("C_dynamic_state_coefficients", myGenerator, fclass);
1560            addOptions("generate_ode");
1561        }
1562       
1563        public void generate(CodeStream genPrinter) {
1564            CodePrinter p = ASTNode.printer_C;
1565            fclass.getDynamicStateManager().genDynamicStateCoefficients_C(p, genPrinter, "");
1566        }
1567    }
1568
1569}
1570
1571public class ExternCEvalGenerator extends CGenerator {
1572    public ExternCEvalGenerator(Printer expPrinter, char escapeCharacter, FClass fclass,
1573            FExternalStmt ext, CodeGenContext cgc, Map<String,String> tempMap) {
1574        super(expPrinter, escapeCharacter, fclass);
1575        for (AbstractTag t : tagMap.values())
1576            if (t instanceof ExternalCEvalTag)
1577                ((ExternalCEvalTag)t).setExt(ext, cgc, tempMap);
1578    }
1579}
Note: See TracBrowser for help on using the repository browser.