Index: libcfa/src/enum.cfa
===================================================================
--- libcfa/src/enum.cfa	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
+++ libcfa/src/enum.cfa	(revision 4117761a350b196fe0274bfd19c566b08a3969bc)
@@ -6,5 +6,4 @@
 forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) {
 	ostype & ?|?( ostype& os, E e ) {
-//		if ( scoped( e ) ) os | type_name( e ) | '.' | nonl;
 		return os | label( e );
 	}
@@ -12,9 +11,8 @@
 }
 
-// forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
-// ostype & ?|?( ostype & os, E e ) {
-// //    return os | type_name(e) | "." | label(e);
-//     return os | label( e );
-// }
+forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
+ostype & ?|?( ostype & os, E e ) {
+    return os | label( e );
+}
 
 forall( E, V | CfaEnum(E, V) ) {						// relational operators
Index: libcfa/src/enum.hfa
===================================================================
--- libcfa/src/enum.hfa	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
+++ libcfa/src/enum.hfa	(revision 4117761a350b196fe0274bfd19c566b08a3969bc)
@@ -20,6 +20,4 @@
     unsigned int posn( E e );
     V value( E e );
-    char * type_name( E e );
-//    bool scoped( E e );
 };
 
@@ -31,6 +29,6 @@
 }
 
-//forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
-//ostype & ?|?( ostype &, E );
+forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
+ostype & ?|?( ostype &, E );
 
 // Design two <- should go for this if we have change the cost model
Index: src/Common/Stats/Heap.cpp
===================================================================
--- src/Common/Stats/Heap.cpp	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
+++ src/Common/Stats/Heap.cpp	(revision 4117761a350b196fe0274bfd19c566b08a3969bc)
@@ -21,12 +21,15 @@
 #include <iostream>
 
-#if defined(__has_feature)
+// Most of the other statistics features are deactivated only by defining
+// NO_STATISTICS (or their NO_%_STATISTICS macro). However the heap has some
+// other compatability concerns and will disable itself in some cases.
+//
+// I do not claim to understand these cases. But TCMALLOC is often defined by
+// default and you can pass --disable-gprofiler to configure to remove it.
+
+#if defined(NO_STATISTICS) || defined(TCMALLOC) || defined(__SANITIZE_ADDRESS__)
+	#define NO_HEAP_STATISTICS
+#elif defined(__has_feature)
 	#if __has_feature(address_sanitizer)
-		#define NO_HEAP_STATISTICS
-	# endif
-#endif
-
-#if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)
-	#if !defined(NO_HEAP_STATISTICS)
 		#define NO_HEAP_STATISTICS
 	#endif
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
+++ src/Parser/lex.ll	(revision 4117761a350b196fe0274bfd19c566b08a3969bc)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Thu Jun 20 16:54:05 2024
- * Update Count     : 778
+ * Last Modified On : Thu Jun 27 14:38:27 2024
+ * Update Count     : 780
  */
 
@@ -458,5 +458,7 @@
 
 "@="			{ NAMEDOP_RETURN(ATassign); }			// CFA
+"+~"			{ NAMEDOP_RETURN(ErangeUp); }			// CFA
 "~="			{ NAMEDOP_RETURN(ErangeUpEq); }			// CFA
+"+~="			{ NAMEDOP_RETURN(ErangeUpEq); }			// CFA
 "-~"			{ NAMEDOP_RETURN(ErangeDown); }			// CFA
 "-~="			{ NAMEDOP_RETURN(ErangeDownEq); }		// CFA
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 5ccc7336506cd07739e57f3df639075f216ba4fb)
+++ src/Parser/parser.yy	(revision 4117761a350b196fe0274bfd19c566b08a3969bc)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jun 26 09:37:28 2024
-// Update Count     : 6700
+// Last Modified On : Thu Jun 27 14:45:57 2024
+// Update Count     : 6705
 //
 
@@ -224,6 +224,6 @@
 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
 #define MISSING_ANON_FIELD "illegal syntax, missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
-#define MISSING_LOW "illegal syntax, missing low value for up-to range so index is uninitialized."
-#define MISSING_HIGH "illegal syntax, missing high value for down-to range so index is uninitialized."
+#define MISSING_LOW "illegal syntax, missing low value for ascanding range so index is uninitialized."
+#define MISSING_HIGH "illegal syntax, missing high value for descending range so index is uninitialized."
 
 static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
@@ -409,5 +409,5 @@
 %token ANDassign	ERassign	ORassign				// &=	^=	|=
 
-%token ErangeUpEq	ErangeDown	ErangeDownEq			// ~=	-~	-~=
+%token ErangeUp		ErangeUpEq	ErangeDown	ErangeDownEq // +~	+~=/~=	-~	-~=
 %token ATassign											// @=
 
@@ -1526,5 +1526,5 @@
 		}
 	| comma_expression ';' '@' updowneq '@'				// CFA, invalid syntax rule
-		{ SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
+		{ SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
 
 	| comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
@@ -1555,5 +1555,5 @@
 		}
 	| comma_expression ';' '@' updowneq '@' '~' '@' // CFA
-		{ SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
+		{ SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
 
 	| declaration comma_expression						// CFA
@@ -1603,5 +1603,5 @@
 		}
 	| declaration '@' updowneq '@' '~' '@'				// CFA, invalid syntax rule
-		{ SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
+		{ SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
 
 	| comma_expression ';' enum_key						// CFA, enum type
@@ -1632,5 +1632,7 @@
 // it is not possible to just remove the '='. The entire '~=' must be removed.
 downupdowneq:
-	ErangeDown
+	ErangeUp
+		{ $$ = OperKinds::LThan; }
+	| ErangeDown
 		{ $$ = OperKinds::GThan; }
 	| ErangeUpEq
@@ -1641,5 +1643,7 @@
 
 updown:
-	'~'
+	'~'													// shorthand 0 ~ 10 => 0 +~ 10
+		{ $$ = OperKinds::LThan; }
+	| ErangeUp
 		{ $$ = OperKinds::LThan; }
 	| ErangeDown
