source: libcfa/prelude/prelude-gen.cc@ 9018dcf

Last change on this file since 9018dcf was 88771d7, checked in by Peter A. Buhr <pabuhr@…>, 7 months ago

second attempt to move builtin types through the system

  • 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 Mar 10 17:30:48 2025
13// Update Count : 65
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.