scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 2715d0eda708c570f3af021729242ffb2cea859c
parent 6fd6dfd8592bc08ea2e4b40893e3d57a44297f44
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 20 Apr 2014 08:32:03 +0200

Simplify typeconv() and promote() using rank

The concept of rank can help in order to simplify these functions.
C99 rank concept is a bit different of how we define rank, but
the final implementation is C99 standard.

Diffstat:
Mcc1.h | 17++++++++++++++++-
Mexpr.c | 46+++++++++++++++++-----------------------------
Mtypes.c | 28++++++++++++++--------------
3 files changed, 47 insertions(+), 44 deletions(-)

diff --git a/cc1.h b/cc1.h @@ -40,6 +40,21 @@ enum { struct funpars; struct symbol; +#define RANK_BOOL 0 +#define RANK_SCHAR 1 +#define RANK_UCHAR 2 +#define RANK_SHORT 3 +#define RANK_USHORT 4 +#define RANK_INT 5 +#define RANK_UINT 6 +#define RANK_LONG 7 +#define RANK_ULONG 8 +#define RANK_LLONG 9 +#define RANK_ULLONG 10 +#define RANK_FLOAT 11 +#define RANK_DOUBLE 12 +#define RANK_LDOUBLE 13 + struct ctype { uint8_t op; /* type builder operator */ char letter; /* letter of the type */ @@ -49,7 +64,7 @@ struct ctype { struct ctype *type; /* base type */ struct ctype *next; /* next element in the hash */ union { - signed char size; + unsigned char rank; /* convertion rank */ short nelem; /* number of elements in arrays */ struct funpar *pars; /* function parameters */ struct field *fields; /* aggregate fields */ diff --git a/expr.c b/expr.c @@ -26,49 +26,37 @@ static Node * promote(Node *np) { Type *tp; + uint8_t r; if (options.npromote) return np; tp = np->utype; - if (tp == chartype || tp == shortype || tp == booltype) - return castcode(np, inttype); - else if (tp == uchartype || tp == ushortype) - return castcode(np, uinttype); - return np; + r = tp->u.rank; + if (r > RANK_UINT || tp == inttype || tp == uinttype) + return np; + return castcode(np, (r == RANK_UINT) ? uinttype : inttype); } static void typeconv(Node **p1, Node **p2) { - Type *tp1, *tp2, *new1, *new2; + Type *tp1, *tp2; Node *np1 = *p1, *np2 = *p2; - signed char n; + uint8_t r1, r2; + + np1 = promote(np1); + np2 = promote(np2); tp1 = np1->utype; tp2 = np1->utype; - if (tp1 == tp2) - return; - if (tp1->op == INT && tp2->op == INT) { - np1 = promote(np1); - np2 = promote(np2); + if (tp1 != tp2) { + if (r1 > r2) + np2 = castcode(np2, tp1); + else if (r1 < r2) + np1 = castcode(np1, tp2); } - - n = tp1->u.size - tp2->u.size; - new1 = new2 = NULL; - - if (n > 0) - new2 = tp1; - else if (n < 0) - new1 = tp2; - else if (tp1->sign) - new2 = tp1; - else - new1 = tp2; - - if (new1) - *p1 = castcode(np1, new1); - else - *p2 = castcode(np2, new2); + *p1 = np1; + *p2 = np2; } static Node * diff --git a/types.c b/types.c @@ -21,89 +21,89 @@ Type .op = INT, .letter = 'B', .defined = 1, - .u.size = 0 + .u.rank = RANK_BOOL }, *uchartype = &(Type) { .op = INT, .letter = 'M', .sign = 1, .defined = 1, - .u.size = 1 + .u.rank = RANK_UCHAR }, *chartype = &(Type) { .op = INT, .letter = 'C', .defined = 1, - .u.size = 1 + .u.rank = RANK_SCHAR }, *ushortype = &(Type) { .op = INT, .letter = 'E', .defined = 1, - .u.size = 2 + .u.rank = RANK_USHORT }, *shortype = &(Type) { .op = INT, .letter = 'K', .defined = 1, - .u.size = 2 + .u.rank = RANK_SHORT }, *uinttype = &(Type) { .op = INT, .letter = 'U', .sign = 1, .defined = 1, - .u.size = 3 + .u.rank = RANK_UINT }, *inttype = &(Type) { .op = INT, .letter = 'I', .defined = 1, - .u.size = 3 + .u.rank = RANK_INT }, *longtype = &(Type) { .op = INT, .letter = 'L', .defined = 1, - .u.size = 4 + .u.rank = RANK_LONG }, *ulongtype = &(Type) { .op = INT, .letter = 'Z', .sign = 1, .defined = 1, - .u.size = 4 + .u.rank = RANK_ULONG }, *ullongtype = &(Type) { .op = INT, .letter = 'O', .sign = 1, .defined = 1, - .u.size = 5 + .u.rank = RANK_ULLONG }, *llongtype = &(Type) { .op = INT, .letter = 'J', .defined = 1, - .u.size = 5 + .u.rank = RANK_LLONG }, *floattype = &(Type) { .op = FLOAT, .letter = 'F', .defined = 1, - .u.size = 10 + .u.rank = RANK_FLOAT }, *doubletype = &(Type) { .op = FLOAT, .letter = 'D', .defined = 1, - .u.size = 11 + .u.rank = RANK_DOUBLE }, *ldoubletype = &(Type) { .op = FLOAT, .letter = 'H', .defined = 1, - .u.size = 12 + .u.rank = RANK_LDOUBLE }; Type *