Index: src/prelude/prelude-gen.cc
===================================================================
--- src/prelude/prelude-gen.cc	(revision 1d386a7bcae033ad6eadd76917517ba0c38d76f9)
+++ src/prelude/prelude-gen.cc	(revision 1d386a7bcae033ad6eadd76917517ba0c38d76f9)
@@ -0,0 +1,406 @@
+#include <algorithm>
+#include <array>
+#include <iostream>
+#include <string>
+#include <vector>
+using namespace std;
+
+static struct{
+	const string name;
+	bool isFloat;
+	bool hasComparison;
+} basicTypes[] = {
+	// { "char"                  , false, true , },
+	// { "signed char"           , false, true , },
+	// { "unsigned char"         , false, true , },
+	{ "signed short"          , false, true , },
+	{ "unsigned short"        , false, true , },
+	{ "signed int"            , false, true , },
+	{ "unsigned int"          , false, true , },
+	{ "signed long int"       , false, true , },
+	{ "unsigned long int"     , false, true , },
+	{ "signed long long int"  , false, true , },
+	{ "unsigned long long int", false, true , },
+	{ "float"                 , true , true , },
+	{ "double"                , true , true , },
+	{ "long double"           , true , true , },
+	{ "float _Complex"        , true , false, },
+	{ "double _Complex"       , true , false, },
+	{ "long double _Complex"  , true , false, },
+#if defined(__SIZEOF_INT128__)
+	{ "__int128"              , false, true , },
+	{ "unsigned __int128"     , false, true , },
+#endif
+#if defined(__i386__) || defined(__ia64__) || defined(__x86_64__)
+	{ "__float80"             , true , true , },
+	{ "_Float128"             , true , true , },
+#endif
+};
+
+struct {
+	const string name;
+	bool assignment = false;
+	bool floatCompat = true;
+	bool isComparison = false;
+	bool isEqual = false;
+} arithmeticOperators[] = {
+	{ "?++"  , true , true, false, false },
+	{ "?--"  , true , true, false, false },
+	{ "++?"  , true , true, false, false },
+	{ "--?"  , true , true, false, false },
+	{ "+?"   , false, true , false, false },
+	{ "-?"   , false, true , false, false },
+	{ "~?"   , false, false, false, false },
+	{ "!?"   , false, true , false, true  },
+	{ "?*?"  , false, true , false, false },
+	{ "?/?"  , false, true , false, false },
+	{ "?%?"  , false, false, false, false },
+	{ "?+?"  , false, true , false, false },
+	{ "?-?"  , false, true , false, false },
+	{ "?<<?" , false, false, false, false },
+	{ "?>>?" , false, false, false, false },
+	{ "?<?"  , false, true , true , false },
+	{ "?<=?" , false, true , true , true  },
+	{ "?>?"  , false, true , true , false },
+	{ "?>=?" , false, true , true , true  },
+	{ "?==?" , false, true , false, true  },
+	{ "?!=?" , false, true , false, true  },
+	{ "?&?"  , false, false, false, false },
+	{ "?^?"  , false, false, false, false },
+	{ "?|?"  , false, false, false, false },
+	{ "?=?"  , true , true , false, false },
+	{ "?+=?" , true , true , false, false },
+	{ "?-=?" , true , true , false, false },
+	{ "?*=?" , true , true , false, false },
+	{ "?/=?" , true , true , false, false },
+	{ "?%=?" , true , false, false, false },
+	{ "?<<=?", true , false, false, false },
+	{ "?>>=?", true , false, false, false },
+	{ "?&=?" , true , false, false, false },
+	{ "?|=?" , true , false, false, false },
+	{ "?^=?" , true , false, false, false },
+};
+
+enum ArgType { Normal, PtrDiff, CommPtrDiff };
+
+struct {
+	const string name;
+	bool assignment = false;
+	string diffReturn;
+	ArgType diffArg2 = Normal;
+	string sized;
+} pointerOperators[] = {
+	{ "?++", true, "", Normal, " | sized(DT)" },
+	{ "?--", true, "", Normal, " | sized(DT)" },
+	{ "++?", true, "", Normal, " | sized(DT)" },
+	{ "--?", true, "", Normal, " | sized(DT)" },
+	{ "!?" , false, "int", Normal, "" },
+	{ "?<?", false, "signed int", Normal, "" },
+	{ "?<=?", false, "signed int", Normal, "" },
+	{ "?>?", false, "signed int", Normal, "" },
+	{ "?>=?", false, "signed int", Normal, "" },
+	{ "?==?", false, "signed int", Normal, "" },
+	{ "?!=?", false, "signed int", Normal, "" },
+	{ "?=?", true, "", Normal, "" }, // void * LHS, zero_t RHS ???
+	{ "*?", false, "&", Normal, " | sized(DT)" }, // & ???
+
+	{ "?-?", false, "ptrdiff_t", Normal, " | sized(DT)" },
+	{ "?-?", false, "", PtrDiff, " | sized(DT)" },
+	{ "?-=?", true, "", PtrDiff, " | sized(DT)" },
+
+	{ "?+?", false, "", CommPtrDiff, " | sized(DT)" },
+	{ "?[?]", false, "&", CommPtrDiff, " | sized(DT)" }, // & ???
+	{ "?+=?" , true, "", PtrDiff, " | sized(DT)" },
+};
+
+template<size_t N>
+string mask2string(unsigned int mask, array<string, N> names) {
+	string result = "";
+	int i = 0;
+	for(auto name : names) {
+		if(mask & (1 << i)) {
+			result += name;
+		}
+		i++;
+	}
+	return result;
+}
+
+template <typename... T>
+constexpr auto make_array(T&&... values) ->
+    std::array<
+        typename std::decay<typename std::common_type<T...>::type>::type,
+        sizeof...(T)>
+{
+    return std::array<
+        typename std::decay<
+            typename std::common_type<T...>::type>::type,
+        sizeof...(T)>{{std::forward<T>(values)...}};
+}
+
+int main() {
+	cout << "# 2 \"prelude.cf\"  // needed for error messages from this file" << endl;
+	cout << "trait sized(dtype T) {};" << endl;
+
+	cout << "//////////////////////////" << endl;
+	cout << "// Arithmetic Operators //" << endl;
+	cout << "//////////////////////////" << endl;
+	cout << endl;
+
+	cout << "void	?{}( zero_t & );" << endl;
+	cout << "void	?{}( one_t & );" << endl;
+	cout << "void	?{}( zero_t &, zero_t );" << endl;
+	cout << "void	?{}( one_t &, one_t );" << endl;
+	cout << "void	^?{}( zero_t & );" << endl;
+	cout << "void	^?{}( one_t & );" << endl;
+	cout << "zero_t			?=?( zero_t &, zero_t );" << endl;
+	cout << "one_t			?=?( one_t &, one_t );" << endl;
+	cout << "signed int ?==?( zero_t, zero_t ),							?!=?( zero_t, zero_t );" << endl;
+	cout << "signed int ?==?( one_t, one_t ),							?!=?( one_t, one_t );" << endl;
+
+	cout << "signed int ?==?( _Bool, _Bool ),							?!=?( _Bool, _Bool );" << endl;
+	cout << "void	?{}( _Bool & );" << endl;
+	cout << "void	?{}( _Bool &, _Bool );" << endl;
+	cout << "void	^?{}( _Bool & );" << endl;
+	cout << "_Bool			?=?( _Bool &, _Bool ),					?=?( volatile _Bool &, _Bool );" << endl;
+	cout << "signed int	!?( _Bool );" << endl;
+
+	cout << "void	^?{}( char & );" << endl;
+	cout << "void	^?{}( char unsigned & );" << endl;
+	cout << "void	^?{}( char signed & );" << endl;
+	cout << "void	?{}( char &, char );" << endl;
+	cout << "void	?{}( unsigned char &, unsigned char );" << endl;
+	cout << "void	?{}( char signed &, char signed );" << endl;
+	cout << "void	?{}( char & );" << endl;
+	cout << "void	?{}( unsigned char & );" << endl;
+	cout << "void	?{}( char signed & );" << endl;
+	cout << "char			?=?( char &, char ),					?=?( volatile char &, char );" << endl;
+	cout << "char signed		?=?( char signed &, char signed ),			?=?( volatile char signed &, char signed );" << endl;
+	cout << "char unsigned		?=?( char unsigned &, char unsigned ),			?=?( volatile char unsigned &, char unsigned );" << endl;
+
+
+	for (auto op : arithmeticOperators) {
+		for (auto type : basicTypes ) {
+			auto operands = count(op.name.begin(), op.name.end(), '?');
+			if (! op.floatCompat && type.isFloat) continue;
+			if (op.isComparison && ! type.hasComparison) continue;
+			if (op.assignment) {
+				const char * qualifiers[] = { "", "volatile " };
+				for (auto q : qualifiers){
+					cout << type.name << " " << op.name << "(";
+					cout << q << type.name << " &";
+					for (int i = 1; i < operands; ++i) {
+						cout << ", " << type.name;
+					}
+					cout << ");" << endl;
+				}
+			} else {
+				if (op.isComparison || op.isEqual) cout << "signed int";
+				else cout << type.name;
+				cout << " " << op.name << "(";
+				for (int i = 0; i < operands; ++i) {
+					cout << type.name;
+					if ((i+1) != operands) cout << ", ";
+				}
+				cout << ");" << endl;
+			}
+		}
+		cout << endl;
+	}
+	cout << endl;
+
+	cout << "/////////////////////////////" << endl;
+	cout << "// Arithmetic Constructors //" << endl;
+	cout << "/////////////////////////////" << endl;
+	for (auto type : basicTypes) {
+		cout << "void  ?{}(" << type.name << " &);" << endl;
+		cout << "void  ?{}(" << type.name << " &, " << type.name << ");" << endl;
+		cout << "void ^?{}(" << type.name << " &);" << endl;
+		cout << endl;
+	}
+	cout << endl;
+
+	cout << "//////////////////////////" << endl;
+	cout << "// Pointer Constructors //" << endl;
+	cout << "//////////////////////////" << endl;
+	cout << "forall(ftype FT) void  ?{}( FT *&, FT * );" << endl;
+	cout << "forall(ftype FT) void  ?{}( FT * volatile &, FT * );" << endl;
+
+	// generate qualifiers for first and second parameters of copy constructors
+	vector<pair<const string, const string>> qualifiersPair;
+	const unsigned int NQ = 2;
+	for(unsigned int lhs = 0; lhs < (1<<NQ); lhs++) {
+		for(unsigned int rhs = 0; rhs < (1<<NQ); rhs++) {
+			if((lhs & rhs) == rhs) {
+				qualifiersPair.push_back({
+					mask2string(lhs, make_array("const "s, "volatile "s)),
+					mask2string(rhs, make_array("const "s, "volatile "s))
+				});
+			}
+		}
+	}
+
+	for (auto type : { "DT", "void" }) {
+		for (auto q : qualifiersPair) {
+			cout << "forall(dtype DT) void  ?{}(" << q.first << type << " *&, " << q.second << "DT *);" << endl;
+		}
+	}
+
+
+	// generate qualifiers for parameter of default constructor and destructor
+	vector<string> qualifiersSingle;
+	for (unsigned int lhs = 0; lhs < (1<<NQ); lhs++) {
+		qualifiersSingle.push_back(mask2string(lhs, make_array("const "s, "volatile "s)));
+	}
+
+	for (auto type : { "DT", "void" }) {
+		for (auto q : qualifiersSingle) {
+			cout << "forall(dtype DT) void  ?{}(" << q << type << " *&);" << endl;
+			cout << "forall(dtype DT) void ^?{}(" << q << type << " *&);" << endl;
+		}
+	}
+	cout << endl;
+
+	cout << "forall(dtype DT) void ?{}(		    DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) void ?{}(		    DT * volatile &, zero_t );" << endl;
+	cout << "forall(dtype DT) void ?{}( const	    DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) void ?{}( volatile	    DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) void ?{}( volatile	    DT * volatile &, zero_t );" << endl;
+	cout << "forall(dtype DT) void ?{}( const volatile DT *	  &, zero_t );" << endl;
+	cout << "forall(ftype FT) void	?{}( FT *	   &, zero_t );	" << endl;
+	cout << "forall( ftype FT ) void	?{}( FT *	   & );" << endl;
+	cout << "forall( ftype FT ) void	^?{}( FT *	   & );" << endl;
+	cout << endl;
+
+	cout << "///////////////////////" << endl;
+	cout << "// Pointer Operators //" << endl;
+	cout << "///////////////////////" << endl;
+
+	cout << "forall( ftype FT ) FT *			?=?( FT *&, FT * );" << endl;
+	cout << "forall( ftype FT ) FT *			?=?( FT * volatile &, FT * );" << endl;
+	cout << "forall( ftype FT ) int !?( FT * );" << endl;
+	cout << "forall( ftype FT ) signed int ?==?( FT *, FT * );" << endl;
+	cout << "forall( ftype FT ) signed int ?!=?( FT *, FT * );" << endl;
+	cout << "forall( ftype FT ) FT &		 *?( FT * );" << endl;
+
+
+	cout << "forall( dtype DT ) void *		 ?=?(		     void *	     &,			DT * );" << endl;
+	cout << "forall( dtype DT ) void *		 ?=?(		     void * volatile &,			DT * );" << endl;
+	cout << "forall( dtype DT ) const void *		 ?=?( const	     void *	     &,			DT * );" << endl;
+	cout << "forall( dtype DT ) const void *		 ?=?( const	     void * volatile &,			DT * );" << endl;
+	cout << "forall( dtype DT ) const void *		 ?=?( const	     void *	     &, const		DT * );" << endl;
+	cout << "forall( dtype DT ) const void *		 ?=?( const	     void * volatile &, const		DT * );" << endl;
+	cout << "forall( dtype DT ) volatile void *	 ?=?(	    volatile void *	     &,			DT * );" << endl;
+	cout << "forall( dtype DT ) volatile void *	 ?=?(	    volatile void * volatile &,			DT * );" << endl;
+	cout << "forall( dtype DT ) volatile void *	 ?=?(	    volatile void *	     &,	      volatile	DT * );" << endl;
+	cout << "forall( dtype DT ) volatile void *	 ?=?(	    volatile void * volatile &,	      volatile	DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &,			DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &,			DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &, const		DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const		DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &,	      volatile	DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &,	      volatile	DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &, const volatile	DT * );" << endl;
+	cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const volatile	DT * );" << endl;
+
+	for (auto op : pointerOperators) {
+		for (auto type : { "DT"/*, "void"*/ } ) {
+			auto operands = count(op.name.begin(), op.name.end(), '?');
+			if (op.assignment) {
+				// const char * qualifiers[] = { "", "volatile ", "const ", "const volatile " };
+				switch(op.diffArg2) {
+					case Normal:
+						if (operands == 1) {
+							for (auto q : qualifiersSingle){
+								for (auto q2 : { " ", " volatile " }) {
+									cout << "forall(dtype DT" << op.sized <<  ") ";
+									cout << q << type << " * " << op.name << "(";
+									cout << q << type << " *" << q2 << "&";
+									cout << ");" << endl;
+								}
+							}
+						} else {
+							for (auto q : qualifiersPair){
+								for (auto q2 : { " ", " volatile " }) {
+									cout << "forall(dtype DT" << op.sized <<  ") ";
+									cout << q.first << type << " * " << op.name << "(";
+									cout << q.first << type << " *" << q2 << "&";
+
+									for (int i = 1; i < operands; ++i) {
+										cout << ", " << q.second << type << " *";
+									}
+									cout << ");" << endl;
+								}
+							}
+						}
+						break;
+					case PtrDiff:
+						for (auto q : qualifiersSingle){
+							for (auto q2 : { " ", " volatile " }) {
+								cout << "forall(dtype DT" << op.sized << ") ";
+								cout << q << type << " * " << op.name << "(";
+								cout << q << type << " *" << q2 << "&";
+
+								for (int i = 1; i < operands; ++i) {
+									cout << ", ptrdiff_t";
+								}
+								cout << ");" << endl;
+							}
+						}
+						break;
+					default:
+						abort();
+					}
+			} else {
+				switch(op.diffArg2) {
+					case Normal:
+						for (auto q : qualifiersSingle) {
+							cout << "forall(dtype DT" << op.sized << ") ";
+							if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
+							else if (op.diffReturn != "") cout << op.diffReturn;
+							else cout << q << type << " *";
+							cout << " " << op.name << "(";
+							for (int i = 0; i < operands; ++i) {
+								cout << q << type << " *";
+								if ((i+1) != operands) cout << ", ";
+							}
+							cout << ");" << endl;
+						}
+						break;
+					case CommPtrDiff:
+						for (auto q : qualifiersSingle) {
+							cout << "forall(dtype DT" << op.sized << ") ";
+							if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
+							else if (op.diffReturn != "") cout << op.diffReturn;
+							else cout << q << type << " *";
+							cout << " " << op.name << "(ptrdiff_t, " << q << type << " *);" << endl;
+						}
+						// fallthrough
+					case PtrDiff:
+						for (auto q : qualifiersSingle) {
+							cout << "forall(dtype DT" << op.sized << ") ";
+							if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
+							else if (op.diffReturn != "") cout << op.diffReturn;
+							else cout << q << type << " *";
+							cout << " " << op.name << "(" << q << type << " *, ptrdiff_t);" << endl;
+						}
+						break;
+				}
+			}
+		}
+		cout << endl;
+	}
+	cout << endl;
+
+	cout << "forall(dtype DT) DT *			?=?(		    DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) DT *			?=?(		    DT * volatile &, zero_t );" << endl;
+	cout << "forall(dtype DT) const DT *		?=?( const	    DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) const DT *		?=?( const	    DT * volatile &, zero_t );" << endl;
+	cout << "forall(dtype DT) volatile DT *	?=?( volatile	    DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) volatile DT *	?=?( volatile	    DT * volatile &, zero_t );" << endl;
+	cout << "forall(dtype DT) const volatile DT *	?=?( const volatile DT *	  &, zero_t );" << endl;
+	cout << "forall(dtype DT) const volatile DT *	?=?( const volatile DT * volatile &, zero_t );" << endl;
+	cout << "forall(ftype FT) FT *			?=?( FT *	   &, zero_t );" << endl;
+	cout << "forall(ftype FT) FT *			?=?( FT * volatile &, zero_t );" << endl;
+}
+
