source: branches/dev-5819/Compiler/ModelicaCBackEnd/src/jastadd/CCodeGen/CCodeGenExternalCeval.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: 17.9 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(returnVarToSerialize());
251        }
252        res.addAll(argVarsToSerialize());
253        return res;
254    }
255   
256    syn ExternalArgument FExternalStmt.returnVarToSerialize() = getReturnVar().externalArgument();
257    syn Collection<ExternalArgument> FExternalStmt.argVarsToSerialize() {
258        Collection<ExternalArgument> res = new LinkedHashSet<>();
259        for (FExp e : getArgs()) {
260            res.add(e.externalArgument());
261        }
262        return res;
263    }
264   
265    syn ExternalArgument FExp.externalArgument();
266    eq FExp           .externalArgument() = this;
267    eq CommonAccessExp.externalArgument() = myCommonVarDecl().externalArgument(this);
268
269    public interface CommonVariableDecl {
270        ExternalArgument externalArgument(FExp exp);
271    }
272
273    syn ExternalArgument InstComponentDecl.externalArgument(FExp exp) = variability().constantVariability() ? exp : this;
274
275    syn ExternalArgument FAbstractVariable.externalArgument(FExp exp);
276    eq FAbstractVariable.externalArgument(FExp exp) = exp;
277    eq FFunctionVariable.externalArgument(FExp exp) = this;
278
279    syn ArrayList<ExternalArgument> FExternalStmt.externalObjectsToSerialize() {
280        ArrayList<ExternalArgument> externalObjects = new ArrayList<ExternalArgument>();
281        for (ExternalArgument var : varsToSerialize()) {
282            if (var.type().isExternalObject()) {
283                externalObjects.add(var);
284            }
285        }
286        return externalObjects;
287    }
288
289    syn ArrayList<ExternalArgument> FExternalStmt.functionArgsToSerialize() {
290        ArrayList<ExternalArgument> functionArgs = new ArrayList<ExternalArgument>();
291        for (ExternalArgument var : varsToSerialize()) {
292            if (!var.type().isExternalObject()) {
293                functionArgs.add(var);
294            }
295        }
296        return functionArgs;
297    }
298   
299
300    syn String FType.cMappedTypeString() = cMappedTypeStringScalar() + (isArray() ? "v" : "");
301
302    syn String FType.cMappedTypeStringScalar() {
303        throw new InternalCompilerError("cMappedTypeStringScalar() is not supported for class type " + getClass().getSimpleName());
304    }
305    eq FArrayType.cMappedTypeStringScalar() = getFPrimitiveType().cMappedTypeStringScalar();
306    eq FIntegerType.cMappedTypeStringScalar() = "i";
307    eq FEnumType.cMappedTypeStringScalar() = "i";
308    eq FBooleanType.cMappedTypeStringScalar() = "i";
309    eq FRealType.cMappedTypeStringScalar() = "d";
310    eq FStringType.cMappedTypeStringScalar() = "s";
311    eq FRecordType.cMappedTypeStringScalar() {
312        String o = "R[";
313        for (FRecordComponentType rType: getComponents()) {
314                o = o.concat(rType.getFType().cMappedTypeStringScalar());
315                o = o.concat(",");
316        }
317        return o.concat("]");
318    }
319   
320    syn String FExternalStmt.functionReturnArgSerialized() {
321        if (hasReturnVar()) {
322            return returnVarToSerialize().type().cMappedTypeString();
323        } else {
324            return "void";
325        }
326    }
327   
328    syn String FExternalStmt.functionArgsSerialized() {
329        String input = "";
330        for (ExternalArgument var : argVarsToSerialize()) {
331            if (var.isOutput()) {
332               input = input.concat("*");
333            }
334            input += var.type().cMappedTypeString() + ",";
335        }
336        return input;
337    }
338   
339    /**
340     * List of CommonVariableDecl which has to be read from the process
341     * when evaluating an external function.
342     */
343    syn ArrayList<ExternalArgument> FExternalStmt.varsToDeserialize() {
344        ArrayList<ExternalArgument> res = new ArrayList<>();
345        for (ExternalArgument cvd : varsToSerialize()) {
346            if (cvd.isOutput()) {
347                res.add(cvd);
348            }
349        }
350        return res;
351    }
352
353    /**
354     * Declarations of records used in this function
355     */
356    public Map<String,FType> FExternalStmt.usedTypes() {
357        Map<String,FType> res = new LinkedHashMap<String,FType>();
358        for (ExternalArgument cvd : varsToSerialize()) {
359            cvd.type().usedTypes(res);
360        }
361        return res;
362    }
363   
364    public void FType.usedTypes(Map<String,FType> res) {
365        if (res.containsKey(name())) {
366            return;
367        }
368        res.put(name(), this);
369    }
370    public void FRecordType.usedTypes(Map<String,FType> res) {
371        if (res.containsKey(name())) {
372            return;
373        }
374        for (FRecordComponentType frct : getComponents()) {
375            frct.getFType().usedTypes(res);
376        }
377        res.put(name(), this);
378    }
379    public void FExternalObjectType.usedTypes(Map<String,FType> res) {
380        if (res.containsKey(name())) {
381            return;
382        }
383        res.put(name(), this);
384        FExternalStmt stmt = myConstructorStmt();
385        for (ExternalArgument arg : stmt.varsToSerialize()) {
386            FType t = arg.type();
387            boolean par = t.getParent() == null;
388            if (par) {
389                t.setParent(stmt);
390            }
391            t.usedTypes(res);
392            if (par) {
393                t.setParent(null);
394            }
395        }
396    }
397   
398    public String FClass.externalCTypes() {
399        StringBuilder sb = new StringBuilder();
400        for (FExternalStmt stmt : myExternals()) {
401            if (stmt.dynamicEvaluatorEnabled()) {
402                sb.append(stmt.getName());
403                sb.append("\n");
404                    sb.append(stmt.functionReturnArgSerialized());
405                    sb.append("\n");
406                    sb.append(stmt.functionArgsSerialized());
407                    sb.append("\n");
408                }
409        }
410        return sb.toString();
411    }
412
413    public String FClass.externalDependencies() {
414        StringBuilder sb = new StringBuilder();
415        for (FExternalStmt stmt : myExternals()) {
416            Set<String> incs    = new LinkedHashSet();
417            Set<String> incDirs = new LinkedHashSet();
418            Set<String> libs    = new LinkedHashSet();
419            Set<String> libDirs = new LinkedHashSet();
420            stmt.externalDependencies(incs, incDirs, libs, libDirs);
421           
422            sb.append(stmt.getName());
423            sb.append("\n");
424            for (String s : incs) {
425                sb.append(s);
426                sb.append("\n");
427            }
428            for (String s : incDirs) {
429                sb.append(new File(s).getName());
430                sb.append("\n");
431            }
432            for (String s : libs) {
433                sb.append(s);
434                sb.append("\n");
435            }
436            for (String s : libDirs) {
437                sb.append(new File(s).getName());
438                sb.append("\n");
439            }
440            sb.append("\n");
441        }
442        return sb.toString();
443    }
444
445    public void FExternalStmt.externalDependencies(
446            Set<String> incs, Set<String> incDirs,
447            Set<String> libs, Set<String> libDirs) {
448        for (FExternalStmt dep : externalDependencies()) {
449            if (incs != null && dep.include() != null) {
450                incs.add(dep.include());
451            }
452            if (incDirs != null && dep.includeDirectory() != null) {
453                incDirs.add(dep.includeDirectory());
454            }
455            if (libs != null && dep.library() != null) {
456                for (String lib : dep.library()) {
457                    libs.add(lib);
458                }
459            }
460            if (libDirs != null && dep.libraryDirectory() != null) {
461                libDirs.add(dep.libraryDirectory());
462            }
463        }
464    }
465
466    public Set<FExternalStmt> FExternalStmt.externalDependencies() {
467        Set<FExternalStmt> res = new LinkedHashSet<FExternalStmt>();
468        externalDependencies(res);
469        return res;
470    }
471
472    public void FExternalStmt.externalDependencies(Set<FExternalStmt> res) {
473        if (res.contains(this)) {
474            return;
475        }
476        res.add(this);
477       
478        for (ExternalArgument arg : varsToSerialize()) {
479            FType t = arg.type();
480            boolean par = t.getParent() == null;
481            if (par) {
482                t.setParent(this);
483            }
484            t.externalDependencies(res);
485            if (par) {
486                t.setParent(null);
487            }
488        }
489       
490        res.remove(this);
491        res.add(this);
492    }
493
494    public void FType.externalDependencies(Set<FExternalStmt> res) {
495       
496    }
497
498    public void FRecordType.externalDependencies(Set<FExternalStmt> res) {
499        for (FRecordComponentType frct : getComponents()) {
500            frct.getFType().externalDependencies(res);
501        }
502    }
503   
504    public void FExternalObjectType.externalDependencies(Set<FExternalStmt> res) {
505        myConstructorStmt().externalDependencies(res);
506        myDestructorStmt().externalDependencies(res);
507    }
508
509    /*
510     * Some code generation for the instance tree.
511     */
512    syn String InstAccess.name_C() = toString_C(printer_C);
513
514    syn String InstAccess.toString_C(CodePrinter p) =
515        myInstLookupComponent().target().name_C();
516
517    public String InstComponentDecl.name_C() {
518        StringBuilder buf = new StringBuilder();
519        buf.append(getFAccess().nameUnderscore());
520        buf.append('_');
521        buf.append(type().isArray() ? C_SUFFIX_ARRAY : C_SUFFIX_VARIABLE);
522        return buf.toString();
523    }
524}
Note: See TracBrowser for help on using the repository browser.