source: libcfa/prelude/prelude-gen.cc @ c086c6e

Last change on this file since c086c6e was c086c6e, checked in by Peter A. Buhr <pabuhr@…>, 7 weeks ago

move code out of #ifdef

  • Property mode set to 100644
File size: 13.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// prelude-gen.cc --
8//
9// Author           : Rob Schluntz and Thierry Delisle
10// Created On       : Sat Feb 16 08:44:58 2019
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Mon Jan 13 14:15:29 2025
13// Update Count     : 55
14//
15
16#include <algorithm>
17#include <array>
18#include <iostream>
19#include <string>
20#include <vector>
21using namespace std;
22
23static struct{
24        const string name;
25        bool isFloat;
26        bool hasComparison;             // CANNOT COMPARE COMPLEX NUMBERS!!!
27} basicTypes[] = {
28        { "char",                                       false, true,  },
29        { "signed char",                        false, true,  },
30        { "unsigned char",                      false, true,  },
31        { "signed short",                       false, true,  },
32        { "unsigned short",                     false, true,  },
33        { "signed int",                         false, true,  },
34        { "unsigned int",                       false, true,  },
35        { "signed long int",            false, true,  },
36        { "unsigned long int",          false, true,  },
37        { "signed long long int",       false, true,  },
38        { "unsigned long long int",     false, true,  },
39        { "float",                                      true , true,  },
40        { "double",                                     true,  true,  },
41        { "long double",                        true,  true,  },
42        { "float _Complex",                     true,  false, },
43        { "double _Complex",            true,  false, },
44        { "long double _Complex",       true,  false, },
45#if defined(__SIZEOF_INT128__)
46        { "__int128",                           false, true,  },
47        { "unsigned __int128",          false, true,  },
48#endif
49#if defined(__i386__) || defined(__ia64__) || defined(__x86_64__)
50        { "__float80",                          true,  true,  },
51        { "__float128",                         true,  true,  },
52#endif
53        { "_Float128",                          true,  true,  },
54        { "_Float128 _Complex",         true,  false, },
55//      { "_Float128x",                         true,  true,  },                // add declarations if type supported
56//      { "_Float128x _Complex",        true,  false, },
57};
58
59struct {
60        const string name;
61        bool assignment = false;
62        bool floatCompat = true;
63        bool isComparison = false;
64        bool isEqual = false;
65} arithmeticOperators[] = {
66        { "?++",        true,  true,  false, false },
67        { "?--",        true,  true,  false, false },
68        { "++?",        true,  true,  false, false },
69        { "--?",        true,  true,  false, false },
70        { "+?",         false, true,  false, false },
71        { "-?",         false, true,  false, false },
72        { "~?",         false, false, false, false },
73        { "!?",         false, true,  false, true  },
74        { "?*?",        false, true,  false, false },
75        { "?/?",        false, true,  false, false },
76        { "?%?",        false, false, false, false },
77        { "?+?",        false, true,  false, false },
78        { "?-?",        false, true,  false, false },
79        { "?<<?",       false, false, false, false },
80        { "?>>?",       false, false, false, false },
81        { "?<?",        false, true,  true,  false },
82        { "?<=?",       false, true,  true,  true  },
83        { "?>?",        false, true,  true,  false },
84        { "?>=?",       false, true,  true,  true  },
85        { "?==?",       false, true,  false, true  },
86        { "?!=?",       false, true,  false, true  },
87        { "?&?",        false, false, false, false },
88        { "?^?",        false, false, false, false },
89        { "?|?",        false, false, false, false },
90        { "?=?",        true,  true,  false, false },
91        { "?+=?",       true,  true,  false, false },
92        { "?-=?",       true,  true,  false, false },
93        { "?*=?",       true,  true,  false, false },
94        { "?/=?",       true,  true,  false, false },
95        { "?%=?",       true,  false, false, false },
96        { "?<<=?",      true,  false, false, false },
97        { "?>>=?",      true,  false, false, false },
98        { "?&=?",       true,  false, false, false },
99        { "?|=?",       true,  false, false, false },
100        { "?^=?",       true,  false, false, false },
101};
102
103enum ArgType { Normal, PtrDiff, CommPtrDiff };
104
105struct {
106        const string name;
107        bool assignment = false;
108        string diffReturn;
109        ArgType diffArg2 = Normal;
110        string sized;
111} pointerOperators[] = {
112        { "?++",        true,  "",                              Normal,                 " | sized(DT)" },
113        { "?--",        true,  "",                              Normal,                 " | sized(DT)" },
114        { "++?",        true,  "",                              Normal,                 " | sized(DT)" },
115        { "--?",        true,  "",                              Normal,                 " | sized(DT)" },
116        { "!?",         false, "int",                   Normal,                 "" },
117        { "?<?",        false, "signed int",    Normal,                 "" },
118        { "?<=?",       false, "signed int",    Normal,                 "" },
119        { "?>?",        false, "signed int",    Normal,                 "" },
120        { "?>=?",       false, "signed int",    Normal,                 "" },
121        { "?==?",       false, "signed int",    Normal,                 "" },
122        { "?!=?",       false, "signed int",    Normal,                 "" },
123        { "?=?",        true,  "",                              Normal,                 "" }, // void * LHS, zero_t RHS ???
124//      { "*?",         false, "&",                             Normal,                 " | sized(DT)" }, // & ???
125        { "*?",         false, "&",                             Normal,                 "" }, // & ???
126
127        { "?-?",        false, "ptrdiff_t",             Normal,                 " | sized(DT)" },
128        { "?-?",        false, "",                              PtrDiff,                " | sized(DT)" },
129        { "?-=?",       true,  "",                              PtrDiff,                " | sized(DT)" },
130
131        { "?+?",        false, "",                              CommPtrDiff,    " | sized(DT)" },
132        { "?[?]",       false, "&",                             CommPtrDiff,    " | sized(DT)" }, // & ???
133        { "?+=?",       true,  "",                              PtrDiff,                " | sized(DT)" },
134};
135
136template<size_t N>
137string mask2string(unsigned int mask, array<string, N> names) {
138        string result = "";
139        int i = 0;
140        for(auto name : names) {
141                if(mask & (1 << i)) {
142                        result += name;
143                } else {
144                        result.append(name.size(), ' ');
145                }
146                i++;
147        }
148        return result;
149}
150
151template <typename... T>
152constexpr auto make_array(T&&... values) ->
153    std::array<
154        typename std::decay<typename std::common_type<T...>::type>::type,
155        sizeof...(T)>
156{
157    return std::array<
158        typename std::decay<
159            typename std::common_type<T...>::type>::type,
160        sizeof...(T)>{{std::forward<T>(values)...}};
161}
162
163int main() {
164        cout << "# 2 \"prelude.cfa\"  // needed for error messages from this file" << endl;
165        cout << "forall( T * ) trait sized {};" << endl;
166
167        cout << "//////////////////////////" << endl;
168        cout << "// Arithmetic Operators //" << endl;
169        cout << "//////////////////////////" << endl;
170        cout << endl;
171
172        cout << "signed int ?==?( zero_t, zero_t ),     ?!=?( zero_t, zero_t );" << endl;
173        cout << "signed int ?==?( one_t, one_t ),       ?!=?( one_t, one_t );" << endl;
174        cout << "signed int ?==?( _Bool, _Bool ),       ?!=?( _Bool, _Bool );" << endl;
175        cout << "signed int !?( _Bool );" << endl;
176
177        for (auto op : arithmeticOperators) {
178                for (auto type : basicTypes ) {
179                        auto operands = count(op.name.begin(), op.name.end(), '?');
180                        if (! op.floatCompat && type.isFloat) continue;
181                        if (op.isComparison && ! type.hasComparison) continue;
182                        if (op.assignment) {
183                                const char * qualifiers[] = { "", "volatile " };
184                                for (auto q : qualifiers){
185                                        cout << type.name << " " << op.name << "(";
186                                        cout << q << type.name << " &";
187                                        for (int i = 1; i < operands; ++i) {
188                                                cout << ", " << type.name;
189                                        }
190                                        cout << ");" << endl;
191                                }
192                        } else {
193                                if (op.isComparison || op.isEqual) cout << "signed int";
194                                else cout << type.name;
195                                cout << " " << op.name << "(";
196                                for (int i = 0; i < operands; ++i) {
197                                        cout << type.name;
198                                        if ((i+1) != operands) cout << ", ";
199                                }
200                                cout << ");" << endl;
201                        }
202                }
203                cout << endl;
204        }
205        cout << endl;
206
207        cout << "/////////////////////////////" << endl;
208        cout << "// Arithmetic Constructors //" << endl;
209        cout << "/////////////////////////////" << endl;
210        cout << endl;
211
212        auto otype = [](const std::string & type, bool do_volatile = false) {
213                cout << "void ?{} (" << type << " &);" << endl;
214                cout << "void ?{} (" << type << " &, " << type << ");" << endl;
215                cout << type << " ?=? (" << type << " &, " << type << ")";
216                if ( do_volatile ) {
217                        cout << ", ?=?(volatile " << type << " &, " << type << ")";
218                }
219                cout << ";" << endl;
220                cout << "void ^?{}( " << type << " & );" << endl;
221        };
222
223        otype("zero_t");
224        cout << endl;
225        otype("one_t");
226        cout << endl;
227        otype("_Bool", true);
228        cout << endl;
229
230        for (auto type : basicTypes) {
231                cout << "void ?{}(" << type.name << " &);" << endl;
232                cout << "void ?{}(" << type.name << " &, " << type.name << ");" << endl;
233                cout << "void ?{}(" << type.name << " &, zero_t);" << endl;
234                cout << "void ?{}(" << type.name << " &, one_t);" << endl;
235                cout << "void ^?{}(" << type.name << " &);" << endl;
236                cout << endl;
237        }
238        cout << endl;
239
240        cout << "//////////////////////////" << endl;
241        cout << "// Pointer Constructors //" << endl;
242        cout << "//////////////////////////" << endl;
243        cout << endl;
244
245        cout << "forall(ftype FT) void ?{}( FT *&, FT * );" << endl;
246        cout << "forall(ftype FT) void ?{}( FT * volatile &, FT * );" << endl;
247
248        // generate qualifiers
249        vector<string> qualifiersSingle;
250        vector<pair<const string, const string>> qualifiersPair;
251        const unsigned int NQ = 2;
252        for(unsigned int lhs = 0; lhs < (1<<NQ); lhs++) {
253                // for parameter of default constructor and destructor
254                qualifiersSingle.push_back(mask2string(lhs, make_array("const "s, "volatile "s)));
255
256                // for first and second parameters of copy constructors
257                for(unsigned int rhs = 0; rhs < (1<<NQ); rhs++) {
258                        if((lhs & rhs) == rhs) {
259                                qualifiersPair.push_back({
260                                        mask2string(lhs, make_array("const "s, "volatile "s)),
261                                        mask2string(rhs, make_array("const "s, "volatile "s))
262                                });
263                        }
264                }
265        }
266
267        for (auto type : { "  DT", "void" }) {
268                for (auto cvq : qualifiersPair) {
269                        for (auto is_vol : { "        ", "volatile" }) {
270                                cout << "forall(DT &) void  ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
271                        }
272                }
273        }
274        for (auto cvq : qualifiersSingle) {
275                for (auto is_vol : { "        ", "volatile" }) {
276                        cout << "void  ?{}(" << cvq << "void" << " * " << is_vol << " &);" << endl;
277                }
278                for (auto is_vol : { "        ", "volatile" }) {
279                        cout << "void ^?{}(" << cvq << "void" << " * " << is_vol << " &);" << endl;
280                }
281        }
282
283        for (auto cvq : qualifiersSingle) {
284                for (auto is_vol : { "        ", "volatile" }) {
285                        cout << "forall(DT &) void  ?{}(" << cvq << "  DT" << " * " << is_vol << " &);" << endl;
286                }
287                for (auto is_vol : { "        ", "volatile" }) {
288                        cout << "forall(DT &) void ^?{}(" << cvq << "  DT" << " * " << is_vol << " &);" << endl;
289                }
290        }
291
292        {
293                auto type = "  DT";
294                for (auto is_vol : { "        ", "volatile" }) {
295                        for (auto cvq : qualifiersSingle) {
296                                cout << "forall(DT &) void ?{}( " << cvq << type << " * " << is_vol << " &, zero_t);" << endl;
297                        }
298                }
299        }
300
301        cout << endl;
302
303        cout << "forall(ftype FT) void  ?{}( FT *          &, zero_t );" << endl;
304        cout << "forall(ftype FT) FT *                  ?=?( FT *          &, zero_t );" << endl;
305        cout << "forall(ftype FT) FT *                  ?=?( FT * volatile &, zero_t );" << endl;
306        cout << "forall(ftype FT) void  ?{}( FT *          & );" << endl;
307        cout << "forall(ftype FT) void  ^?{}( FT *         & );" << endl;
308        cout << endl;
309
310        cout << "///////////////////////" << endl;
311        cout << "// Pointer Operators //" << endl;
312        cout << "///////////////////////" << endl;
313
314        cout << "forall(ftype FT) FT *                  ?=?( FT *&, FT * );" << endl;
315        cout << "forall(ftype FT) FT *                  ?=?( FT * volatile &, FT * );" << endl;
316        cout << "forall(ftype FT) int !?( FT * );" << endl;
317        cout << "forall(ftype FT) signed int ?==?( FT *, FT * );" << endl;
318        cout << "forall(ftype FT) signed int ?!=?( FT *, FT * );" << endl;
319        cout << "forall(ftype FT) FT &           *?( FT * );" << endl;
320
321        for (auto op : pointerOperators) {
322                auto forall = [&op]() {
323                        cout << "forall(DT &" << op.sized << ") ";
324                };
325                for (auto type : { "DT"/*, "void"*/ } ) {
326                        auto operands = count(op.name.begin(), op.name.end(), '?');
327                        if (op.assignment) {
328                                // const char * qualifiers[] = { "", "volatile ", "const ", "const volatile " };
329                                switch(op.diffArg2) {
330                                        case Normal:
331                                                if (operands == 1) {
332                                                        for (auto q : qualifiersSingle){
333                                                                for (auto q2 : { "        ", "volatile" }) {
334                                                                        forall();
335                                                                        cout << q << type << " * " << op.name << "(";
336                                                                        cout << q << type << " * " << q2 << " &";
337                                                                        cout << ");" << endl;
338                                                                }
339                                                        }
340                                                } else {
341                                                        for (auto q : qualifiersPair){
342                                                                for (auto q2 : { "        ", "volatile" }) {
343                                                                        forall();
344                                                                        cout << q.first << type << " * " << op.name << "(";
345                                                                        cout << q.first << type << " * " << q2 << " &";
346
347                                                                        for (int i = 1; i < operands; ++i) {
348                                                                                cout << ", " << q.second << type << " *";
349                                                                        }
350                                                                        cout << ");" << endl;
351                                                                }
352                                                        }
353                                                }
354                                                break;
355                                        case PtrDiff:
356                                                for (auto q : qualifiersSingle){
357                                                        for (auto q2 : { "        ", "volatile" }) {
358                                                                forall();
359                                                                cout << q << type << " * " << op.name << "(";
360                                                                cout << q << type << " * " << q2 << " &";
361
362                                                                for (int i = 1; i < operands; ++i) {
363                                                                        cout << ", ptrdiff_t";
364                                                                }
365                                                                cout << ");" << endl;
366                                                        }
367                                                }
368                                                break;
369                                        default:
370                                                abort();
371                                        }
372                        } else {
373                                auto name_and_arg1 = [&op, &type](const std::string & q) {
374                                        if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
375                                        else if (op.diffReturn != "") cout << op.diffReturn;
376                                        else cout << q << type << " *";
377                                        cout << " " << op.name << "(";
378                                };
379                                switch(op.diffArg2) {
380                                        case Normal:
381                                                for (auto q : qualifiersSingle) {
382                                                        forall();
383                                                        name_and_arg1( q );
384                                                        for (int i = 0; i < operands; ++i) {
385                                                                cout << q << type << " *";
386                                                                if ((i+1) != operands) cout << ", ";
387                                                        }
388                                                        cout << ");" << endl;
389                                                }
390                                                break;
391                                        case CommPtrDiff:
392                                                for (auto q : qualifiersSingle) {
393                                                        forall();
394                                                        name_and_arg1( q );
395                                                        cout << "ptrdiff_t, " << q << type << " *);" << endl;
396                                                }
397                                                // fallthrough
398                                        case PtrDiff:
399                                                for (auto q : qualifiersSingle) {
400                                                        forall();
401                                                        name_and_arg1( q );
402                                                        cout << q << type << " *, ptrdiff_t);" << endl;
403                                                }
404                                                break;
405                                }
406                        }
407                }
408                cout << endl;
409        }
410        cout << endl;
411
412        for (auto is_vol : { "        ", "volatile" }) {
413                for (auto cvq : qualifiersPair) {
414                                cout << "forall(DT &) " << cvq.first << "void * ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
415                }
416                for (auto cvq : qualifiersSingle) {
417                        cout << "forall(DT &) " << cvq <<   "  DT * ?=?( " << cvq << "  DT * " << is_vol << " &, zero_t);" << endl;
418                }
419        }
420        cout << endl;
421}
422
423// Local Variables: //
424// tab-width: 4 //
425// End: //
Note: See TracBrowser for help on using the repository browser.