source: branches/dev-5819/Compiler/ModelicaCBackEnd/src/jastadd/CCodeGen/CGenerator.jrag @ 13800

Last change on this file since 13800 was 13800, checked in by randersson, 7 weeks ago

#5819 Merged trunk into branch

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