scc

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

commit 3a225104759c18a70e8eb918d88a07111f3a128b
parent f6970279c96254b3407c1d0f2ade3342c26b87b6
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  8 Sep 2015 21:35:40 +0200

Add initializers for non static local variables

This is the simpler case, because we only have to generate
an assignation.

Diffstat:
cc1/cc1.h | 1+
cc1/decl.c | 26++++++++++++++++++--------
cc1/expr.c | 2+-
3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -373,6 +373,7 @@ extern bool isnodecmp(int op); extern int negop(int op); extern bool cmpnode(Node *np, TUINT val); extern Node *decay(Node *np); +extern Node *assignop(char op, Node *lp, Node *rp); /* cpp.c */ extern void icpp(void); diff --git a/cc1/decl.c b/cc1/decl.c @@ -360,18 +360,28 @@ return_type: /* TODO: check correctness of the initializator */ /* TODO: emit initializer */ -static struct node * +static void initializer(Symbol *sym) { + Type *tp = sym->type; + Node *np; + if (accept('{')) { initializer(sym); expect('}'); - } else { - do { - expr(); - } while (accept(',')); + return; + } + np = expr(); + if ((np = convert(np, tp, 0)) == NULL) + goto bad_initializer; + if ((sym->flags & ISLOCAL) == 0) { + emit(OEXPR, assignop(OASSIGN, varnode(sym), np)); + return; } - return NULL; + return; + +bad_initializer: + errorp("invalid initializer"); } static Symbol * @@ -683,13 +693,13 @@ identifier(struct decl *dcl) sym->flags = flags; } - if (accept('=')) - initializer(sym); /* TODO: disallow initializators in functions */ /* TODO: check if typedef has initializer */ /* TODO: check if the variable is extern and has initializer */ if (sym->token == IDEN && sym->type->op != FTN) emit(ODECL, sym); + if (accept('=')) + initializer(sym); return sym; redeclaration: diff --git a/cc1/expr.c b/cc1/expr.c @@ -421,7 +421,7 @@ array(Node *lp, Node *rp) return content(OPTR, np); } -static Node * +Node * assignop(char op, Node *lp, Node *rp) { int force = 0;