ref: 2715d0eda708c570f3af021729242ffb2cea859c
parent: 6fd6dfd8592bc08ea2e4b40893e3d57a44297f44
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Apr 20 04:32:03 EDT 2014
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.
--- a/cc1.h
+++ b/cc1.h
@@ -40,6 +40,21 @@
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 *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 */
--- a/expr.c
+++ b/expr.c
@@ -26,49 +26,37 @@
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 *
--- a/types.c
+++ b/types.c
@@ -21,7 +21,7 @@
.op = INT,
.letter = 'B',
.defined = 1,
- .u.size = 0
+ .u.rank = RANK_BOOL
},
*uchartype = &(Type) {
.op = INT,
@@ -28,25 +28,25 @@
.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,
@@ -53,19 +53,19 @@
.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,
@@ -72,7 +72,7 @@
.letter = 'Z',
.sign = 1,
.defined = 1,
- .u.size = 4
+ .u.rank = RANK_ULONG
},
*ullongtype = &(Type) {
.op = INT,
@@ -79,31 +79,31 @@
.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 *