#
#  Copyright (c) 1992, NewCode Technology, Inc.  All Rights Reserved.
#  You have the right to make copies of this file for use with cback.
#
#  Rules control file for cback version 2.46 on a sun4.
#  See 'rc.doc2.46' for documentation of these rules.
#
#  Simplification rules to make cfront output readable.
#  These rules do not discard any significant output of cfront.
#
input: (e) => e
expr: (e) => e
expr: a,(b,c,d),e => a,b,c,d,e
expr: &*e => e
expr: *&e => e
expr: (&a)->b => a.b
expr: (*a).b => a->b
expr: (a,b,c)%d => a,b,c%d
expr: (a,b,c)[d] => a,b,c[d]
expr: (a,b,c)?d:e => a,b,c?d:e
expr: (a,b,c).d => a,b,c.d
expr: (a,b,c)->d => a,b,c->d
expr: (a,b,f)(c,d,e) => a,b,f(c,d,e)
expr: (T)(a,b,c) => a,b,(T)c
expr: ~(a,b,c) => a,b,~c
expr: i[a] => a[i]
expr! int a[7]; *a => a[0]
bool: a&&(b&&c) => a&&b&&c
bool: a||(b||c) => a||b||c
expr: struct x *p; ((y *) p)->m => p->m
expr: struct x *p; ((y *) p)->m1 => p->m2
expr! union x *p; ((y *) p)->m => p->m
expr! union x *p; ((y *) p)->m1 => p->m2
void! --e => e--
void! ++e => e++

#
#  Simplification rules which discard unused parts of expressions.
#
expr: (T)e => e // when T == typeof(e)
bool: remove 0's and 1's in conditionals
bool: (struct x *)e => e // when typeof(e) == (struct y *)
bool: (struct x *)a>(struct x *)b => a>b // when typeof(a&b) == (struct y *)
bool: (struct x *)a==(struct x *)b => a==b // when typeof(a&b) == (struct y *)
bool: !!e => e
bool: e!=0 => e
bool: var=7 => var=7,1
expr: (struct x *)(struct y *)a => (struct x *)a
expr: (T*)(struct x*)e => (T*)e // when typeof(e) == (struct y *)
expr: (struct x*)(char *)e => (struct x*)e // when typeof(e) == (struct y*)
expr! !(a>b) => a<=b // when typeof(a&b) == double
expr: !(a>b) => a<=b // when typeof(a&b) == any integer
expr: !(a>b) => a<=b // when typeof(a&b) == any pointer
expr! !(a==b) => a!=b // when typeof(a&b) == double
expr: !(a==b) => a!=b // when typeof(a&b) == any integer
expr: !(a==b) => a!=b // when typeof(a&b) == any pointer
expr: !a?b:c => a?c:b
expr: e+0 => e
expr: e==0 => !e
void: a%b => a,b
void: (T)e => e
void: constant =>
void: a.b => a
void: ~e => e
void: a->b => a
void: sizeof e =>
void: var =>
void: a[i] => a,i
void: a&&b => a&&void(b) => a?b,0:0
void: a||b => a||void(b) => a?0:(b,0)
void: struct x { int m; }; *(struct x*)a=*(struct x*)b => a->m=b->m

#
#  Rename variables and structure members.
#
dcln: T __0x; => T x;
dcln: T _au0_x; => T x;
dcln: T _static_x; => T x;
dcln: struct x { T m__1x; } => struct x { T m; }
dcln: struct x { T _x_m; } => struct x { T m; }
dcln: struct x { T1 y_m1; T2 x_m1; } => struct x { T1 y_m1; T2 m1; }

#
#  Remove unused declarations.
#
dcln! typedef int x (); x *y; => int (*y)();
dcln: remove unused structs and variables
dcln: remove bodys of indirectly used structs
dcln! static T __used_var_; =>
dcln: static char unused[] = "..."; => // at {} scope
file! static char unused[] = "..."; => // at file scope
file! static struct __link { ... } __LINK = { ... } =>
file! static struct __linkl { ... } __link = { ... } =>
file! remove unused static _STD, _STI, _std, _sti functions

#
#  Statement Rules
#
stat: ; =>
stat: a,b,c; => a; b; c;
stat: a&&b; => if (a) b;
stat: a||b; => if (!a) b;
stat: a?b:c; => if (a) b; else c;
stat: if (1) s; => s
stat: if (e) ; => e;
stat: if (e) ; else ; => e;
stat: if (e) s; else ; => if (e) s;
stat: if (e) ; else s; => if (!e) s;
stat! for (a,b,c; d;) s; => a; b; c; while (d) s;
stat: for (a,b,c; d; e) s; => a; b; for (c; d; e) s;
stat! for (; c;) s; => while (c) s;
stat: if (a,b,c) s; => a; b; if (c) s;
stat: switch (a,b,c) s; => a; b; switch (c) s;
stat: return a,b,c; => a; b; return c;
stat: return a?b:c; => if (a) return b; else return c;
stat: return (T*)(a?b:c); => if (a) return (T*)b; else ...;

#
#  Output Formatting
#
output: T a=b=c => T a=(b=c)
output: a?b:c?d:e => a?b:(c?d:e)
output: #line 7 "file.cc"
output: #line 7
output: #7 "file.cc"
output! # 7 "file.cc"
output! uninitialized variables with #line
output: first uninitialized variable with #line
output: original first #line

#
#  Aggressive Rules
#
cleanup: STI
cleanup: trace variable usage
bool! a=(struct x*)__nw(sizeof(struct x)) => a,1
bool! __nw(sizeof(struct x)) => 1
void! __dl((char *)p) => p
bool! a=(struct x *)__nw__FUi(b) => a=(struct x *)__nw__FUi(b),1
bool: &e->m => e,1 // when 'm' has a non-zero offset
bool: &var => 1
bool: constant => 1
dcln: extern int x (); static int x (); => static int x (); static int x ();
file! int x; => extern int x;
expr: f(a,(b,c,d),e) => b,c,f(a,d,e)
expr: a%(b,c,d) => b,c,a%d
expr: a[b,c,d] => b,c,a[d]
expr: a||(a=b)?a||d?e:f,g:h => a||(a=b)?1||d?e:f,g:h
expr: a||(a=b)?c=a,c||d?e:f,g:h => a||(a=b)?c=a,1||d?e:f,g:h
stat: if (a||(a=b)) { a||c?d:e; f; } => if (a||(a=b)) { 1||c?d:e; f; }
expr: a=b,a=c => b,a=c
expr: strlen("abc") => (size_t)(sizeof"abc"-1)
expr: strrchr("Technology",'o') => "Technology"+7
expr: (struct x *) ((char *) e + const_int) => &e->Ox
expr! f((struct x *) e) => f(e) // when typeof(e) == (struct y *)
expr: v=v => v,v
expr! p->__vptr[7].d => p,(short)0
expr! (T1*)(T2*)a => (T1*)a
expr! (T1*)(T2*)0 => (T1*)0
expr! (*(char(*)())pf)(a,b,c) => (*pf)(a,b,c) // when typeof(pf) == (int(*)())
file! move structs, unions, enums, and typedefs
void! a?_new (b):0 => a,b

#
#  Ptbl
#
ptbl! c compiler accepts 'static int x (); ...; static int x () { ... }'
ptbl! c compiler accepts 'static mptr __vtbl__4name;' twice
ptbl! struct __mptr *__ptbl__4nameFILE = __vtbl__4name; => static ...
ptbl: __ptbl__4nameFile => __vtbl__4name
ptbl: __ptbl_vec__file[0] => __vtbl__4name

#
#  Compiler characteristics
#
compiler! char is signed by default
compiler! char is unsigned by default

#
#
#  DECstation (MIPS), HP 9000, SGI Machine, and Sun4 sizes
#
size: (*)()		4	4
size: **		4	4
size: char		1	1
size: char*		4	4
size: double		8	8
size: double*		4	4
size: float		4	4
size: float*		4	4
size: int		4	4
size: int*		4	4
size: long		4	4
size: long*		4	4
size: long long		0	0
size: long long*	0	0
size: short		2	2
size: short*		4	4
size: struct*		4	4
size: void*		4	4

#
#  IBM RS6000 and Xenix 386 sizes
#
#size: (*)()		4	4
#size: **		4	4
#size: char		1	1
#size: char*		4	4
#size: double		8	4
#size: double*		4	4
#size: float		4	4
#size: float*		4	4
#size: int		4	4
#size: int*		4	4
#size: long		4	4
#size: long*		4	4
#size: long long		0	0
#size: long long*	0	0
#size: short		2	2
#size: short*		4	4
#size: struct*		4	4
#size: void*		4	4

#
#  KSR Machine sizes
#
#size: (*)()		8	8
#size: **		8	8
#size: char		1	1
#size: char*		8	8
#size: double		8	8
#size: double*		8	8
#size: float		8	8
#size: float*		8	8
#size: int		4	4
#size: int*		8	8
#size: long		8	8
#size: long*		8	8
#size: long double	0	0
#size: long double*	0	0
#size: short		2	2
#size: short*		8	8
#size: struct*		8	8
#size: void*		8	8

#
#  Macintosh A/UX and Sun3 sizes
#
#size: (*)()		4	2
#size: **		4	2
#size: char		1	1
#size: char*		4	2
#size: double		8	2
#size: double*		4	2
#size: float		4	2
#size: float*		4	2
#size: int		4	2
#size: int*		4	2
#size: long		4	2
#size: long*		4	2
#size: long long		0	0
#size: long long*	0	0
#size: short		2	2
#size: short*		4	2
#size: struct*		4	2
#size: void*		4	2

#
#  Unimplemented
#
cleanup! char _STI_file_cc_ () { } =>
expr! (a?b,1:c,0)?d:e => a?(b,d):(c,e)
expr! (struct x *)(a?b:c) => a?(struct x *)b:(struct x *)c
expr! a?0:b => !a&&b
expr! a?1:b => a||b
expr! a?b:0 => a&&b
expr! a?b:1 => !a||b
expr! a?b:b => a,b
stat! if (a?b,1:c,0) d; else e; => if (a) { b; d; } else { c; e; }

#
#  Rules for NewCode use only
#
dcln! suppress warning about ignoring #pragma linkage
dcln! mark functions in asm statements
dcln! warn about 'asm' .stab references to undefined symbols
stat! asm ("..."); =>
stat! var=a?b,c:d; => if (a) var=b,c; else var=d;
void! _new (e) => e
void! e?0:e_assert_fail("...",#,"...") => e
void! e?e_fsoft(dbg_all,"...",#,"..."):0 => e

#
#  ----  Put local modifications to rules after this line  -----
#
