// ---------------------------------------------------------------------------
-// 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 => X == 0
+
+TestExpression
+@ not_int2 @
int X;
@@
- !X => 0 == 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 @
@@
X & Y => Y & X
-// only if side effect free in theory ...
-Expression
-@ and_comm @
-expression X,Y;
-@@
-X && Y => Y && X
+// only if side effect free in theory, perhaps makes no sense
+// Expression
+// @ and_comm @
+// expression X,Y;
+// @@
+// X && Y => Y && X
-Expression
-@ or_comm @
-expression X,Y;
-@@
-X || Y => Y || X
+// Expression
+// @ or_comm @
+// expression X,Y;
+// @@
+// X || Y => Y || X
// ---------------------------------------------------------------------------
@@
X < Y <=> Y > X
+Expression
+@ gtr_lss_eq @
+expression X, Y;
+@@
+X <= Y <=> Y >= X
+
// ---------------------------------------------------------------------------
// Increment isomorphisms
// ---------------------------------------------------------------------------
@@
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.
-
-
// ---------------------------------------------------------------------------
// Pointer/Array isomorphisms
// ---------------------------------------------------------------------------
// sizeof isomorphisms
// ---------------------------------------------------------------------------
-Expression
-@ sizeof_parens @
-expression E;
-@@
+// The following is made redundant by the paren isomorphism
+// Expression
+// @ sizeof_parens @
+// expression E;
+// @@
-sizeof(E) => sizeof E
+// sizeof(E) => sizeof E
Expression
sizeof(T) => sizeof(E)
+// Expression
+// @ fld_func_call @
+// expression list ES;
+// identifier fld;
+// expression E;
+// @@
+// E.fld(ES) <=> (*E.fld)(ES)
+
// ****************************************************************************
// Linux specific isomorphisms