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

Last change on this file since de3a579 was 97b47ec, checked in by Andrew Beach <ajbeach@…>, 17 months ago

The 'sized' trait is now implemented on top of 'T *' declarations and has no special status in the compiler.

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