shithub: scc

Download patch

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 *