Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 7d9bbef38fd89d81efc810bb49d3c7bc32dc47f4)
+++ src/Parser/ExpressionNode.cc	(revision f6582252f6e12255699993ce90ce23e19835e29a)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:17:07 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec 18 21:14:58 2019
-// Update Count     : 981
+// Last Modified On : Sat Jul 11 16:44:49 2020
+// Update Count     : 1034
 //
 
@@ -85,5 +85,5 @@
 	} // if
 	// remove "lL" for these cases because it may not imply long
-	str.erase( posn );									// remove length
+	str.erase( posn );									// remove length suffix and "uU"
 } // lnthSuffix
 
@@ -108,9 +108,20 @@
 } // valueToType
 
+static void scanbin( string & str, unsigned long long int & v ) {
+	v = 0;
+	size_t last = str.length() - 1;						// last subscript of constant
+	for ( unsigned int i = 2;; ) {						// ignore prefix
+		if ( str[i] == '1' ) v |= 1;
+		i += 1;
+	  if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
+		v <<= 1;
+	} // for
+} // scanbin
+
 Expression * build_constantInteger( string & str ) {
 	static const BasicType::Kind kind[2][6] = {
 		// short (h) must be before char (hh) because shorter type has the longer suffix
-		{ BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
-		{ BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
+		{ BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, },
+		{ BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ BasicType::LongLongUnsignedInt, },
 	};
 
@@ -120,8 +131,7 @@
 	}; // lnthsInt
 
-	unsigned long long int v;							// converted integral value
-	size_t last = str.length() - 1;						// last subscript of constant
-	Expression * ret;
-	//string fred( str );
+	string str2( "0x0" );
+	unsigned long long int v, v2 = 0;					// converted integral value
+	Expression * ret, * ret2;
 
 	int type = -1;										// 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
@@ -139,68 +149,136 @@
 	} // if
 
+	string::size_type posn;
+
+	// 'u' can appear before or after length suffix
+	if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
+
+	if ( isdigit( str[str.length() - 1] ) ) {			// no suffix ?
+		lnthSuffix( str, type, ltype );					// could have length suffix
+		if ( type == 5 && Unsigned ) str.erase( str.length() - 1 ); // L128 and terminating "uU" ?
+	} else {
+		// At least one digit in integer constant, so safe to backup while looking for suffix.
+
+		posn = str.find_last_of( "pP" );				// pointer value
+		if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; }
+
+		posn = str.find_last_of( "zZ" );				// size_t
+		if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
+
+		posn = str.rfind( "hh" );						// char
+		if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
+
+		posn = str.rfind( "HH" );						// char
+		if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
+
+		posn = str.find_last_of( "hH" );				// short
+		if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
+
+		posn = str.find_last_of( "nN" );				// int (natural number)
+		if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
+
+		if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
+
+		lnthSuffix( str, type, ltype );					// must be after check for "ll"
+	  FINI: ;
+	} // if
+
 	// Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
-
+	
 	if ( str[0] == '0' ) {								// radix character ?
 		dec = false;
 		if ( checkX( str[1] ) ) {						// hex constant ?
-			sscanf( (char *)str.c_str(), "%llx", &v );
+			if ( type < 5 ) {							// not L128 ?
+				sscanf( (char *)str.c_str(), "%llx", &v );
+			} else {									// hex int128 constant
+				unsigned int len = str.length();
+				if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str );
+			  if ( len <= (2 + 16) ) goto FHEX1;		// hex digits < 2^64
+				str2 = "0x" + str.substr( len - 16 );
+				sscanf( (char *)str2.c_str(), "%llx", &v2 );
+				str = str.substr( 0, len - 16 );
+			  FHEX1: ;
+				sscanf( (char *)str.c_str(), "%llx", &v );
+			} // if
 			//printf( "%llx %llu\n", v, v );
 		} else if ( checkB( str[1] ) ) {				// binary constant ?
-			v = 0;										// compute value
-			for ( unsigned int i = 2;; ) {				// ignore prefix
-				if ( str[i] == '1' ) v |= 1;
-				i += 1;
-			  if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
-				v <<= 1;
-			} // for
+			unsigned int len = str.length();
+			if ( type == 5 && len > 2 + 64 ) {
+				if ( len > 2 + 64 + 64 ) SemanticError( yylloc, "128-bit binary constant to large " + str );
+				str2 = "0b" + str.substr( len - 64 );
+				str = str.substr( 0, len - 64 );
+				scanbin( str2, v2 );
+			} // if
+			scanbin( str, v );
 			//printf( "%#llx %llu\n", v, v );
 		} else {										// octal constant
-			sscanf( (char *)str.c_str(), "%llo", &v );
+			if ( type < 5 ) {							// not L128 ?
+				sscanf( (char *)str.c_str(), "%llo", &v );
+			} else {									// octal int128 constant
+				unsigned int len = str.length();
+				char buf[32];
+				__int128 val = v;
+				
+				if ( len > 1 + 43 || (len == 1 + 43 && str[0] > '3') ) SemanticError( yylloc, "128-bit octal constant to large " + str );
+				if ( len <= 1 + 21 ) {					// value < 21 octal digitis
+					sscanf( (char *)str.c_str(), "%llo", &v ); // leave value in octal
+				} else {
+					sscanf( &str[len - 21], "%llo", &v );
+					val = v;							// store bits
+					str[len - 21] ='\0';				// shorten string
+					sscanf( &str[len == 43 ? 1 : 0], "%llo", &v );
+					val |= (__int128)v << 63;			// store bits
+					if ( len == 1 + 43 ) {				// most significant 2 bits ?
+						str[2] = '\0';					// shorten string
+						sscanf( &str[1], "%llo", &v );	// process most significant 2 bits
+						val |= (__int128)v << 126;		// store bits
+					} // if
+					v = val >> 64; v2 = (uint64_t)val;	// replace octal constant with 2 hex constants
+					sprintf( buf, "%#llx", v2 );
+					str2 = buf;
+					sprintf( buf, "%#llx", v );
+					str = buf;
+				} // if
+			} // if
 			//printf( "%#llo %llu\n", v, v );
 		} // if
 	} else {											// decimal constant ?
-		sscanf( (char *)str.c_str(), "%llu", &v );
+		if ( type < 5 ) {								// not L128 ?
+			sscanf( (char *)str.c_str(), "%llu", &v );
+		} else {										// decimal int128 constant
+			#define P10_UINT64 10'000'000'000'000'000'000ULL // 19 zeroes
+			unsigned int len = str.length();
+			char buf[32];
+			__int128 val = v;
+
+			if ( str.length() == 39 && str > (Unsigned ? "340282366920938463463374607431768211455" : "170141183460469231731687303715884105727") )
+				SemanticError( yylloc, "128-bit decimal constant to large " + str );
+			if ( len <= 19 ) {							// value < 19 decimal digitis
+				sscanf( (char *)str.c_str(), "%llu", &v ); // leave value in decimal
+			} else {
+				sscanf( &str[len - 19], "%llu", &v );
+				val = v;								// store bits
+				str[len - 19] ='\0';					// shorten string
+				sscanf( &str[len == 39 ? 1 : 0], "%llu", &v );
+				val += (__int128)v * (__int128)P10_UINT64; // store bits
+				if ( len == 39 ) {						// most significant 2 bits ?
+					str[1] = '\0';						// shorten string
+					sscanf( &str[0], "%llu", &v );		// process most significant 2 bits
+					val += (__int128)v * (__int128)P10_UINT64 * (__int128)P10_UINT64; // store bits
+				} // if
+				v = val >> 64; v2 = (uint64_t)val;		// replace decimal constant with 2 hex constants
+				sprintf( buf, "%#llx", v2 );
+				str2 = buf;
+				sprintf( buf, "%#llx", v );
+				str = buf;
+			} // if
+		} // if
 		//printf( "%llu\n", v );
 	} // if
 
-	string::size_type posn;
-
-	if ( isdigit( str[last] ) ) {						// no suffix ?
-		lnthSuffix( str, type, ltype );					// could have length suffix
-		if ( type == -1 ) {								// no suffix
-			valueToType( v, dec, type, Unsigned );
-		} // if
-	} else {
-		// At least one digit in integer constant, so safe to backup while looking for suffix.
-
-		posn = str.find_last_of( "pP" );
-		if ( posn != string::npos ) { valueToType( v, dec, type, Unsigned ); ltype = 5; str.erase( posn, 1 ); goto FINI; }
-
-		posn = str.find_last_of( "zZ" );
-		if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
-
-		// 'u' can appear before or after length suffix
-		if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
-
-		posn = str.rfind( "hh" );
-		if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
-
-		posn = str.rfind( "HH" );
-		if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
-
-		posn = str.find_last_of( "hH" );
-		if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
-
-		posn = str.find_last_of( "nN" );
-		if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
-
-		if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
-
-		lnthSuffix( str, type, ltype );					// must be after check for "ll"
-		if ( type == -1 ) {								// only 'u' suffix ?
-			valueToType( v, dec, type, Unsigned );
-		} // if
-	  FINI: ;
-	} // if
+	if ( type == -1 ) {									// no suffix => determine type from value size
+		valueToType( v, dec, type, Unsigned );
+	} // if
+	/* printf( "%s %llo %s %llo\n", str.c_str(), v, str2.c_str(), v2 ); */
 
 	//if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); }
@@ -214,5 +292,8 @@
 	} else if ( ltype != -1 ) {							// explicit length ?
 		if ( ltype == 6 ) {								// int128, (int128)constant
-			ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
+//			ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
+			ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) );
+			ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
+										 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) );
 		} else {										// explicit length, (length_type)constant
 			ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
