source: trunk/Compiler/ModelicaCBackEnd/src/jastadd/CCodeGen/CCodeGenExternalCeval.jrag @ 13703

Last change on this file since 13703 was 13703, checked in by Christian Andersson, 2 months ago

Reverted changeset:13700. Related to ticket:5837

File size: 15.7 KB
Line 
1/*
2Copyright (C) 2009 Modelon AB
3This program is free software: you can redistribute it and/or modify
4it under the terms of the GNU General Public License as published by
5the Free Software Foundation, version 3 of the License.
6
7This program is distributed in the hope that it will be useful,
8but WITHOUT ANY WARRANTY; without even the implied warranty of
9MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10GNU General Public License for more details.
11
12You should have received a copy of the GNU General Public License
13along with this program.  If not, see <http://www.gnu.org/licenses/>.
14*/
15
16import java.util.ArrayList;
17import java.util.HashMap;
18import java.util.LinkedHashSet;
19import java.util.Map;
20import java.util.Set;
21
22aspect CCodeGenExternalCeval {
23
24    public void FExternalStmt.setExternalArgumentAliases(CodeGenContext cgc) {
25        setExternalArgumentAliases(cgc, getName(), false);
26    }
27
28    public void FExternalStmt.setExternalArgumentAliases(CodeGenContext cgc, String name, boolean all) {
29        int i = 0;
30        for (ExternalArgument arg : varsToSerialize()) {
31            if (all || arg instanceof FExp) {
32                cgc.setAlias(arg, name + "_arg" + i);
33            }
34            i++;
35        }
36    }
37
38    public void FExternalStmt.setExternalArgumentAliases(CodeGenContext cgc, String outName, String name) {
39        setExternalArgumentAliases(cgc, name, true);
40        cgc.setAlias(myConstructorOutput(), outName);
41    }
42
43    public class DeclPrinter_ECE extends DeclPrinter_C {
44        private CodeGenContext cgc;
45        private Map<String,String> tempMap;
46        public DeclPrinter_ECE(CodePrinter p, CodeStream str, Map<String,String> tempMap, CodeGenContext cgc) {
47            super(p, str);
48            this.tempMap = tempMap;
49            this.cgc = cgc;
50        }
51        protected String acquireTemp(String key) {
52            String s = cgc.nextTempName_C();
53            tempMap.put(key, s);
54            return s;
55        }
56        protected void printComps(FType type) {
57            if (type.isExternalObject()) {
58                printComps((FExternalObjectType) type);
59                printExt((FExternalObjectType) type);
60            } else {
61                super.printComps(type);
62            }
63        }
64        protected void printComps(FExternalObjectType type) {
65            FExternalStmt stmt = type.myConstructorStmt();
66            stmt.setExternalArgumentAliases(cgc, name(), acquireTemp(name()));
67            stmt.setCodeGenContext(cgc);
68            stmt.genVarDecls_C(p, str, indent());
69            stmt.setCodeGenContext(null);
70            super.printComps(type);
71        }
72    }
73   
74    public class InitPrinter_ECE extends InitPrinter_C {
75        protected CodeGenContext cgc;
76        private Map<String,String> tempMap;
77        public InitPrinter_ECE(CodePrinter p, CodeStream str, Map<String,String> tempMap, CodeGenContext cgc) {
78            super(p, str);
79            this.tempMap = tempMap;
80            this.cgc = cgc;
81        }
82        protected String acquireTemp(String key) {
83            return tempMap.get(key);
84        }
85        protected void printArray(FType type) {
86            str.print(indent(), "JMCEVAL_parseArrayDims(", type.ndims(), ");\n");
87            super.printArray(type);
88            if (type.isExternalObject()) {
89               
90            } else {
91                type.genSerialize_C(str, indent(), name(), true);
92            }
93        }
94        protected void printNumElements(FType type) {
95            str.print("d[0]");
96            for (int i = 1; i < type.ndims(); i++)
97                str.print("*d["+i+"]");
98        }
99        protected void printDimensions(FType type) {
100            for (int i = 0; i < type.ndims(); i++)
101                str.print(", d["+i+"]");
102        }
103        protected void printScalar(FType type) {
104            if (!type.isExternalObject()) {
105                type.genSerialize_C(str, indent(), name(), true);
106            }
107        }
108        protected void printComps(FType type) {
109            if (type.isExternalObject()) {
110                printComps((FExternalObjectType) type);
111                printExt((FExternalObjectType) type);
112            } else {
113                super.printComps(type);
114            }
115        }
116        protected void printExt(FExternalObjectType type) {
117            FExternalStmt stmt = type.myConstructorStmt();
118            stmt.setExternalArgumentAliases(cgc, name(), acquireTemp(name()));
119            stmt.setCodeGenContext(cgc);
120            stmt.prettyPrint_C(p, str, indent());
121            stmt.setCodeGenContext(null);
122        }
123    }
124   
125    public class FreePrinter_ECE extends InitPrinter_C {
126        private CodeGenContext cgc;
127        private Map<String,String> tempMap;
128
129        public FreePrinter_ECE(CodePrinter p, CodeStream str, Map<String,String> tempMap, CodeGenContext cgc) {
130            super(p, str);
131            this.tempMap = tempMap;
132            this.cgc = cgc;
133        }
134
135        @Override
136        protected String acquireTemp(String key) {
137            return tempMap.get(key);
138        }
139
140        @Override
141        public void print(FType type) {
142           
143        }
144
145        @Override
146        protected void printScalar(FType type) {
147           
148        }
149
150        @Override
151        protected void printComps(FType type) {
152            if (type.isExternalObject()) {
153                printComps((FExternalObjectType) type);
154                printExt((FExternalObjectType) type);
155            }
156        }
157
158        @Override
159        protected void printExt(FExternalObjectType type) {
160            FExternalStmt stmt = type.myDestructorStmt();
161            cgc.setAlias(stmt.varsToSerialize().iterator().next(), name());
162            stmt.setCodeGenContext(cgc);
163            stmt.prettyPrint_C(p, str, indent());
164            stmt.setCodeGenContext(null);
165        }
166
167        @Override
168        public boolean initMaxInd() { return false; }
169    }
170   
171    /**
172     * Generate all C-declarations necessary for an external evaluation
173     *
174     * @param p       ASTNode code generation visitor
175     * @param str     output code stream
176     * @param indent  indentation string
177     * @param cgc     context for generating temporaries
178     * @param tempMap maps expressions that should be replaced with temporaries
179     */
180    public void FExternalStmt.genSerialize_C(TypePrinter_C tp, String indent,
181            CodeGenContext cgc, Map<String,String> tempMap, Iterable<ExternalArgument> cvds) {
182        for (ExternalArgument cvd : cvds) {
183            String name = cgc.alias(cvd);
184            if (name == null) {
185                name = cvd.name_C();
186            }
187            tp.resetUnknown(name, cvd.type(), indent);
188            cvd.type().print(tp);
189        }
190    }
191   
192    public void FExternalStmt.genSerializeComps_C(TypePrinter_C tp, String indent,
193            CodeGenContext cgc, Map<String,String> tempMap, Iterable<ExternalArgument> cvds) {
194        for (ExternalArgument cvd : cvds) {
195            tp.resetUnknown(cvd.name_C(), cvd.type(), indent);
196            tp.printComps((FExternalObjectType)cvd.type());
197        }
198    }
199   
200    /**
201     * Generate statements for type conversions, calling the external function,
202     * and printing return values on stdout.
203     *
204     * For parameters {@link FExternalStmt.genSerializeDecl_C}
205     */
206    public void FExternalStmt.genSerializeCalc_C(CodePrinter p, CodeStream str, String indent,
207            CodeGenContext cgc, Map<String,String> tempMap) {
208        prettyPrint_C(p, str, indent);
209        genCheckPoint(str, indent, "DONE");
210        for (ExternalArgument cvd : varsToDeserialize())
211            cvd.type().genSerialize_C(str, indent, cvd.name_C(), false);
212        str.println();
213    }
214   
215    public void FExternalStmt.genCheckPoint(CodeStream str, String indent, String token) {
216        str.print(indent);
217        str.print("JMCEVAL_check(\"");
218        str.print(token);
219        str.print("\");\n");
220    }
221   
222    /**
223     * Generate code that parses the variable <code>name</code> of type
224     * <code>this</code> from stdin.
225     */
226    public void FType.genSerialize_C(CodeStream str, String indent, String name, boolean parse) {
227        str.print(indent, "JMCEVAL_", 
228                parse ? "parse" : "print", 
229                isArray() ? "Array(" : "(", 
230                isEnum() ? "Enum" : name(), ", ",
231                name, ");\n");
232    }
233   
234    public void FRecordType.genSerialize_C(CodeStream str, String indent, String name, boolean parse) {
235        name = name + "->";
236        for (FRecordComponentType frct : getComponents()) {
237            if (!frct.getFType().isRecord() || !parse) {
238                frct.getFType().genSerialize_C(str, indent, name + frct.getName(), parse);
239            }
240        }
241    }
242   
243    /**
244     * List of ExternalArgument which has to be sent to the process
245     * when evaluating an external function.
246     */
247    syn Collection<ExternalArgument> FExternalStmt.varsToSerialize() {
248        Collection<ExternalArgument> res = new LinkedHashSet<>();
249        if (hasReturnVar()) {
250            res.add(getReturnVar().externalArgument());
251        }
252        for (FExp e : getArgs()) {
253            res.add(e.externalArgument());
254        }
255        return res;
256    }
257   
258    syn ExternalArgument FExp.externalArgument();
259    eq FExp           .externalArgument() = this;
260    eq CommonAccessExp.externalArgument() = myCommonVarDecl().externalArgument(this);
261
262    public interface CommonVariableDecl {
263        ExternalArgument externalArgument(FExp exp);
264    }
265
266    syn ExternalArgument InstComponentDecl.externalArgument(FExp exp) = variability().constantVariability() ? exp : this;
267
268    syn ExternalArgument FAbstractVariable.externalArgument(FExp exp);
269    eq FAbstractVariable.externalArgument(FExp exp) = exp;
270    eq FFunctionVariable.externalArgument(FExp exp) = this;
271
272    syn ArrayList<ExternalArgument> FExternalStmt.externalObjectsToSerialize() {
273        ArrayList<ExternalArgument> externalObjects = new ArrayList<ExternalArgument>();
274        for (ExternalArgument var : varsToSerialize()) {
275            if (var.type().isExternalObject()) {
276                externalObjects.add(var);
277            }
278        }
279        return externalObjects;
280    }
281
282    syn ArrayList<ExternalArgument> FExternalStmt.functionArgsToSerialize() {
283        ArrayList<ExternalArgument> functionArgs = new ArrayList<ExternalArgument>();
284        for (ExternalArgument var : varsToSerialize()) {
285            if (!var.type().isExternalObject()) {
286                functionArgs.add(var);
287            }
288        }
289        return functionArgs;
290    }
291   
292    /**
293     * List of CommonVariableDecl which has to be read from the process
294     * when evaluating an external function.
295     */
296    syn ArrayList<ExternalArgument> FExternalStmt.varsToDeserialize() {
297        ArrayList<ExternalArgument> res = new ArrayList<>();
298        for (ExternalArgument cvd : varsToSerialize()) {
299            if (cvd.isOutput()) {
300                res.add(cvd);
301            }
302        }
303        return res;
304    }
305
306    /**
307     * Declarations of records used in this function
308     */
309    public Map<String,FType> FExternalStmt.usedTypes() {
310        Map<String,FType> res = new LinkedHashMap<String,FType>();
311        for (ExternalArgument cvd : varsToSerialize()) {
312            cvd.type().usedTypes(res);
313        }
314        return res;
315    }
316   
317    public void FType.usedTypes(Map<String,FType> res) {
318        if (res.containsKey(name())) {
319            return;
320        }
321        res.put(name(), this);
322    }
323    public void FRecordType.usedTypes(Map<String,FType> res) {
324        if (res.containsKey(name())) {
325            return;
326        }
327        for (FRecordComponentType frct : getComponents()) {
328            frct.getFType().usedTypes(res);
329        }
330        res.put(name(), this);
331    }
332    public void FExternalObjectType.usedTypes(Map<String,FType> res) {
333        if (res.containsKey(name())) {
334            return;
335        }
336        res.put(name(), this);
337        FExternalStmt stmt = myConstructorStmt();
338        for (ExternalArgument arg : stmt.varsToSerialize()) {
339            FType t = arg.type();
340            boolean par = t.getParent() == null;
341            if (par) {
342                t.setParent(stmt);
343            }
344            t.usedTypes(res);
345            if (par) {
346                t.setParent(null);
347            }
348        }
349    }
350
351    public String FClass.externalDependencies() {
352        StringBuilder sb = new StringBuilder();
353        for (FExternalStmt stmt : myExternals()) {
354            Set<String> incs    = new LinkedHashSet();
355            Set<String> incDirs = new LinkedHashSet();
356            Set<String> libs    = new LinkedHashSet();
357            Set<String> libDirs = new LinkedHashSet();
358            stmt.externalDependencies(incs, incDirs, libs, libDirs);
359           
360            sb.append(stmt.getName());
361            sb.append("\n");
362            for (String s : incs) {
363                sb.append(s);
364                sb.append("\n");
365            }
366            for (String s : incDirs) {
367                sb.append(new File(s).getName());
368                sb.append("\n");
369            }
370            for (String s : libs) {
371                sb.append(s);
372                sb.append("\n");
373            }
374            for (String s : libDirs) {
375                sb.append(new File(s).getName());
376                sb.append("\n");
377            }
378            sb.append("\n");
379        }
380        return sb.toString();
381    }
382
383    public void FExternalStmt.externalDependencies(
384            Set<String> incs, Set<String> incDirs,
385            Set<String> libs, Set<String> libDirs) {
386        for (FExternalStmt dep : externalDependencies()) {
387            if (incs != null && dep.include() != null) {
388                incs.add(dep.include());
389            }
390            if (incDirs != null && dep.includeDirectory() != null) {
391                incDirs.add(dep.includeDirectory());
392            }
393            if (libs != null && dep.library() != null) {
394                for (String lib : dep.library()) {
395                    libs.add(lib);
396                }
397            }
398            if (libDirs != null && dep.libraryDirectory() != null) {
399                libDirs.add(dep.libraryDirectory());
400            }
401        }
402    }
403
404    public Set<FExternalStmt> FExternalStmt.externalDependencies() {
405        Set<FExternalStmt> res = new LinkedHashSet<FExternalStmt>();
406        externalDependencies(res);
407        return res;
408    }
409
410    public void FExternalStmt.externalDependencies(Set<FExternalStmt> res) {
411        if (res.contains(this)) {
412            return;
413        }
414        res.add(this);
415       
416        for (ExternalArgument arg : varsToSerialize()) {
417            FType t = arg.type();
418            boolean par = t.getParent() == null;
419            if (par) {
420                t.setParent(this);
421            }
422            t.externalDependencies(res);
423            if (par) {
424                t.setParent(null);
425            }
426        }
427       
428        res.remove(this);
429        res.add(this);
430    }
431
432    public void FType.externalDependencies(Set<FExternalStmt> res) {
433       
434    }
435
436    public void FRecordType.externalDependencies(Set<FExternalStmt> res) {
437        for (FRecordComponentType frct : getComponents()) {
438            frct.getFType().externalDependencies(res);
439        }
440    }
441   
442    public void FExternalObjectType.externalDependencies(Set<FExternalStmt> res) {
443        myConstructorStmt().externalDependencies(res);
444        myDestructorStmt().externalDependencies(res);
445    }
446
447    /*
448     * Some code generation for the instance tree.
449     */
450    syn String InstAccess.name_C() = toString_C(printer_C);
451
452    syn String InstAccess.toString_C(CodePrinter p) =
453        myInstLookupComponent().target().name_C();
454
455    public String InstComponentDecl.name_C() {
456        StringBuilder buf = new StringBuilder();
457        buf.append(getFAccess().nameUnderscore());
458        buf.append('_');
459        buf.append(type().isArray() ? C_SUFFIX_ARRAY : C_SUFFIX_VARIABLE);
460        return buf.toString();
461    }
462}
Note: See TracBrowser for help on using the repository browser.