scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 45c7260ce0fb41d8bf7eb57274af599e84904b06
parent 328f45d5dcadced32eaeee1ea0a6f05f7cb2a969
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 15 Apr 2014 21:59:52 +0200

Add integer conversions

When two integer types with different size are together in an
expression then there are some rules that indicate what is the
size of both operands.

Diffstat:
cc.h | 7++++---
expr.c | 29+++++++++++++++++++++++++++--
types.c | 53++++++++++++++++++++++++++++++++---------------------
3 files changed, 63 insertions(+), 26 deletions(-)

diff --git a/cc.h b/cc.h @@ -44,13 +44,14 @@ struct symbol; struct ctype { uint8_t op; /* type builder operator */ char letter; /* letter of the type */ - short nelem; /* number of elements in arrays */ - unsigned defined : 1; /* type defined (is not a forward reference) */ - unsigned sign : 1; /* sign type */ + bool defined : 1; /* type defined (is not a forward reference) */ + bool sign : 1; /* sign type */ struct symbol *sym; /* symbol of the tag identifier */ struct ctype *type; /* base type */ struct ctype *next; /* next element in the hash */ union { + signed char size; + short nelem; /* number of elements in arrays */ struct funpar *pars; /* function parameters */ struct field *fields; /* aggregate fields */ } u; diff --git a/expr.c b/expr.c @@ -38,8 +38,30 @@ promote(Node *np) } static void -intconv(Node **np1, Node **np2) +intconv(Node **p1, Node **p2) { + Type *tp1, *tp2, *new1, *new2; + Node *np1 = *p1, *np2 = *p2; + signed char n; + + tp1 = UNQUAL(np1->type); + tp2 = UNQUAL(np2->type); + new1 = new2 = NULL; + n = tp1->u.size - tp2->u.size; + + 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); } static void @@ -60,7 +82,8 @@ bitlogic(char op, Node *np1, Node *np2) if (t1 != INT || t2 != INT) error("No integer operand in bit logical operation"); - intconv(&np1, &np2); + if (tp1 != tp2) + intconv(&np1, &np2); return bincode(op, np1->type, np1, np2); } @@ -125,6 +148,7 @@ arithmetic(char op, Node *np1, Node *np2) case INT: if (tp1 != tp2) intconv(&np1, &np2); + tp1 = np1->type; break; case FLOAT: np2 = castcode(np1, np2->type); @@ -142,6 +166,7 @@ arithmetic(char op, Node *np1, Node *np2) case FLOAT: if (tp1 != tp2) floatconv(&np1, &np2); + tp1 = np1->type; break; case INT: np2 = castcode(np2, np1->type); diff --git a/types.c b/types.c @@ -16,61 +16,72 @@ Type *booltype = &(Type) { .op = INT, .letter = 'B', - .defined = 1 + .defined = 1, + .u.size = 0 }, *uchartype = &(Type) { .op = INT, .letter = 'M', .sign = 1, - .defined = 1 + .defined = 1, + .u.size = 1 }, *chartype = &(Type) { .op = INT, .letter = 'C', - .defined = 1 + .defined = 1, + .u.size = 1 + }, + *ushortype = &(Type) { + .op = INT, + .letter = 'E', + .defined = 1, + .u.size = 2 + }, + *shortype = &(Type) { + .op = INT, + .letter = 'K', + .defined = 1, + .u.size = 2 }, *uinttype = &(Type) { .op = INT, .letter = 'U', .sign = 1, - .defined = 1 + .defined = 1, + .u.size = 3 }, *inttype = &(Type) { .op = INT, .letter = 'I', - .defined = 1 - }, - *ushortype = &(Type) { - .op = INT, - .letter = 'E', - .defined = 1 - }, - *shortype = &(Type) { - .op = INT, - .letter = 'K', - .defined = 1 + .defined = 1, + .u.size = 3 }, *longtype = &(Type) { .op = INT, .letter = 'L', - .defined = 1 + .defined = 1, + .u.size = 4 }, *ulongtype = &(Type) { .op = INT, .letter = 'Z', .sign = 1, - .defined = 1 + .defined = 1, + .u.size = 4 }, *ullongtype = &(Type) { .op = INT, .letter = 'O', .sign = 1, - .defined = 1 + .defined = 1, + .u.size = 5 }, *llongtype = &(Type) { .op = INT, .letter = 'G', - .defined = 1 + .defined = 1, + .u.size = 5 }, *floattype = &(Type) { .op = FLOAT, @@ -131,7 +142,7 @@ mktype(Type *tp, uint8_t op, if (op != FTN || op != STRUCT || op != UNION || op != ENUM) { for (bp = *tbl; bp; bp = bp->next) { if (bp->type == tp && bp->op == op && - bp->sym == sym && bp->nelem == nelem) { + bp->sym == sym && bp->u.nelem == nelem) { return bp; } } @@ -149,7 +160,7 @@ mktype(Type *tp, uint8_t op, bp->next = *tbl; bp->type = tp; bp->op = op; - bp->nelem = nelem; + bp->u.nelem = nelem; bp->sym = sym; bp->letter = letter; return *tbl = bp;