scc

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

commit 0dc51a53f9e0728586d36fe4f39402f91defe4e7
parent 3bb913a9bf49c3144c5e7b7864d0a77ab6c67f63
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  8 Apr 2014 21:10:50 +0200

Add lvalue to Node

Some operations (assignment, increment, decrement, take address,
or content) can be only applied to lvalues, so it is important keep track
when a node is a lvalue or not.

Diffstat:
Mcc.h | 3+++
Mexpr.c | 18++++++++++++++----
2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/cc.h b/cc.h @@ -204,6 +204,9 @@ extern void expect(uint8_t tok); typedef struct node { void (*code)(struct node *); Type *type; + struct { + bool lvalue : 1; + } b; union unode { Symbol *sym; Type *type; diff --git a/expr.c b/expr.c @@ -18,6 +18,7 @@ primary(void) if ((sym = yylval.sym) == NULL) error("'%s' undeclared", yytext); np = node(emitsym, sym->type, SYM(sym), 0); + np->b.lvalue = 1; next(); break; case CONSTANT: @@ -50,7 +51,7 @@ arithmetic(char op, Node *np1, Node *np2) { Node *naux; Type *tp1, *tp2, *tp3; - uint8_t t1, t2, taux; + uint8_t t1, t2, taux, lvalue = 0; tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np2->type); t1 = tp1->op, t2 = tp2->op; @@ -101,12 +102,15 @@ pointer: np2 = bincode(OMUL, tp1, castcode(np2, tp1), sizeofcode(tp3)); + lvalue = 1; break; default: goto incorrect; } - return bincode(op, tp1, np1, np2); + np1 = bincode(op, tp1, np1, np2); + np1->b.lvalue = lvalue; + return np1; nocomplete: error("invalid use of indefined type"); @@ -145,7 +149,8 @@ incdec(Node *np, char op) Type *tp; char *err; - /* TODO: Check against l-value */ + if (!np->b.lvalue) + goto nolvalue; tp = UNQUAL(np->type); if (isconst(np->type->op)) goto const_mod; @@ -155,11 +160,16 @@ incdec(Node *np, char op) if (!tp->type->defined) goto nocomplete; case INT: case FLOAT: - return unarycode(op, np->type, np); + np = unarycode(op, np->type, np); + np->b.lvalue = 0; + return np; default: goto bad_type; } +nolvalue: + err = "lvalue required in operation"; + goto error; nocomplete: err = "invalid use of indefined type"; goto error;