// ---------------------------------------------------------------------------
-// Boolean isomorphisms
+// Boolean isomorphisms for int and pointer types
// ---------------------------------------------------------------------------
// the space at the beginning of the line is very important!
Expression
-@ not_int1 @
+@ not_int1 @
int X;
@@
- !X => 0 == X
+ !X => X == 0
+
+TestExpression
+@ not_int2 @
+int X;
+@@
+ X => X != 0
// the space at the beginning of the line is very important!
Expression
-@ not_int2 @
-int X;
+@ not_ptr1 @
+expression *X;
@@
- !X => X == 0
+ !X => X == NULL
+
+TestExpression
+@ not_ptr2 @
+expression *X;
+@@
+ X => X != NULL
+
+// ---------------------------------------------------------------------------
+// Boolean isomorphisms
+// ---------------------------------------------------------------------------
+
+Expression
+@commeq@
+expression E;
+constant C;
+@@
+
+E == C <=> C == E
+
+Expression
+@commneq@
+expression E;
+constant C;
+@@
+
+E != C <=> C != E
Expression
@ is_zero @
expression X;
@@
-X == 0 <=> 0 == X => !X
+X == 0 => !X
-Expression
+// X should be a test expression, but X!=0 doesn't have to be one
+// not nice at all... ToTestExpression sets everything after the first
+// pattern in the iso rule to be TestExpression
+ToTestExpression
@ isnt_zero @
expression X;
@@
-X != 0 <=> 0 != X => X
+X != 0 => X
+
+Expression
+@ is_null @
+expression X;
+@@
+X == NULL => !X
+
+ToTestExpression
+@ isnt_null1 @
+expression X;
+@@
+X != NULL => X
+
+// ---------------------------------------------------------------------------
+// Bit operations
+// ---------------------------------------------------------------------------
Expression
@ bitor_comm @
@@
for(X;Y;i++) S <=> for(X;Y;++i) S
+// ****************************************************************************
+// gcc specific isomorphisms
+// ****************************************************************************
-// ---------------------------------------------------------------------------
-// Pointer isomorphisms
-// ---------------------------------------------------------------------------
+// likely and unlikely are used to give hints to gcc to improve performance.
-// the space at the beginning of the line is very important!
Expression
-@ not_ptr1 @
-expression *X;
+@ unlikely @
+expression E;
@@
- !X => NULL == X
-// the space at the beginning of the line is very important!
-Expression
-@ not_ptr2 @
-expression *X;
-@@
- !X => X == NULL
+unlikely(E) <=> likely(E) => E
-Expression
-@ is_null @
-expression X;
-@@
-X == NULL <=> NULL == X => !X
+// ---------------------------------------------------------------------------
+// Parenthesis isomorphisms
+// ---------------------------------------------------------------------------
+//Expression
+//@@ expression E; @@
+// E => (E)
+//// E => ((E))
-Expression
-@ isnt_null1 @
-expression X;
-@@
-X != NULL <=> NULL != X
+// todo: isomorphism avec les () around ? cf sizeof 3.
+// (E) => E with some conditions.
-TestExpression
-@ isnt_null1 @
-expression X;
+Expression
+@ paren @
+expression E;
@@
-NULL != X => X
-// pointer arithmetic equivalences
+ (E) => E
// ---------------------------------------------------------------------------
// Statement isomorphisms
// ---------------------------------------------------------------------------
-// ----------------
-// If
-// ----------------
-
-Statement
-@ int_if_test1 @
-int X;
-statement S1, S2;
-@@
-if (X) S1 else S2 => if (X != 0) S1 else S2 <=> if (0 != X) S1 else S2
-
-Statement
-@ int_if_test2 @
-int X;
-statement S;
-@@
-if (X) S => if (X != 0) S <=> if (0 != X) S
-
-Statement
-@ ptr_if_test1 @
-expression *X;
-statement S1, S2;
-@@
-if (X) S1 else S2 => if (X != NULL) S1 else S2 => if (NULL != X) S1 else S2
-
-Statement
-@ ptr_if_test2 @
-expression *X;
-statement S;
-@@
-if (X) S => if (X != NULL) S <=> if (NULL != X) S
-
// ---------------------------------------------------------------------------
// Value isomorphisms
// ---------------------------------------------------------------------------
@@
0 => '\0'
-// ****************************************************************************
-// gcc specific isomorphisms
-// ****************************************************************************
-
-// likely and unlikely are used to give hints to gcc to improve performance.
-
-Expression
-@ unlikely @
-expression E;
-@@
-
-unlikely(E) => E
-
-Expression
-@ likely @
-expression E;
-@@
-
-likely(E) => E
+// ----------------
+// If
+// ----------------
// ****************************************************************************
// if structure isomorphisms
// ****************************************************************************
-// these after after the above so that the introduced negation will distribute
+// these are after the above so that the introduced negation will distribute
// properly over the argument to likely/unlikely
Statement
@@
if (X) S1 else S2 => if (!X) S2 else S1
+Statement
+@ ne_if @
+expression E1, E2;
+statement S1, S2;
+@@
+if (E1 != E2) S1 else S2 => if (E1 == E2) S2 else S1
+
Statement
@ drop_else @
expression E;
// They are handled in engine.
// 'X = Y' should also match 'type X = Y';
-// ---------------------------------------------------------------------------
-// Parenthesis isomorphisms
-// ---------------------------------------------------------------------------
-//Expression
-//@@ expression E; @@
-// E => (E)
-//// E => ((E))
-
-// todo: isomorphism avec les () around ? cf sizeof 3.
-// (E) => E with some conditions.
-
-Expression
-@ paren @
-expression E;
-@@
-
- (E) => E
-
// ---------------------------------------------------------------------------
// Pointer/Array isomorphisms
// ---------------------------------------------------------------------------