scc

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

commit 3394d4da4e02f25e0ffbafca52f7a41c49fd6ef0
parent 6e021a04133c17cc9510a71ffd0cff2be70d7b35
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 11 Apr 2014 18:09:55 +0200

Check types in assigment

Not all the types are compatible in assigment, so a check is needed
before the assigment.

Diffstat:
expr.c | 51+++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/expr.c b/expr.c @@ -37,6 +37,36 @@ bitlogic(char op, Node *np1, Node *np2) return bincode(op, np1->type, np1, np2); } +/* + * Convert the second Node to the type of the first + */ +static Node * +convert(Node *np1, Node *np2) +{ + Type *tp1, *tp2; + register uint8_t t1, t2; + + tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np2->type); + if (tp1 == tp2) + return np2; + t1 = tp1->op, t2 = tp2->op; + + switch (t1) { + case ENUM: case INT: case FLOAT: + switch (t2) { + case INT: case FLOAT: case ENUM: + return castcode(np2, tp1); + } + break; + case PTR: + switch (t2) { + case ARY: case FTN: + /* TODO: take address of np2 */; + } + } + return NULL; +} + static Node * arithmetic(char op, Node *np1, Node *np2) { @@ -423,7 +453,8 @@ bit_or(void) static Node * assign(void) { - register Node *np = bit_or(); + register Node *np1 = bit_or(), *np2; + char *err; for (;;) { register char op; @@ -443,11 +474,23 @@ assign(void) default: goto return_np; } next(); - /* TODO: cast types */ - np = bincode(op, np->type, np, assign()); + np2 = assign(); + if (!np1->b.lvalue) + goto nolvalue; + if ((np2 = convert(np1, np2)) == NULL) + goto incompatibles; + np1 = bincode(op, np1->type, np1, np2); } return_np: - return np; + return np1; + +nolvalue: + err = "lvalue required as left operand of assignment"; + goto error; +incompatibles: + err = "incompatible types when assigning"; +error: + error(err); } Node *