scc

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

commit 105071d951fde01834dc9f66db522fd186c148e3
parent f5ecaab1bde3f51e6ccce10416530d5b29b4e84b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat,  8 Mar 2014 17:55:01 +0100

Avoid local functions

Functions nested are evil, forbid them.

Diffstat:
Mdecl.c | 32++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/decl.c b/decl.c @@ -303,8 +303,6 @@ direct: sym = directdcl(tp, ns); static struct node * initializer(register struct ctype *tp) { - if (!accept('=')) - return NULL; if (accept('{')) { struct compound c; @@ -327,7 +325,6 @@ listdcl(struct ctype *base, struct storage *store, struct qualifier *qlf, unsigned char ns) { struct compound c; - char fun; c.tree = NULL; @@ -341,17 +338,28 @@ listdcl(struct ctype *base, sym->qlf = *qlf; sym->ctype = *decl_type(base); tp = &sym->ctype; - if ((tp->type == STRUCT || tp->type == UNION) && tp->forward) - error("declaration of variable with incomplete type"); - np = nodesym(sym); - fun = tp->type == FTN && yytoken == '{'; - aux = fun ? function(sym) : initializer(tp); - addstmt(&c, node(ODEF, np, aux)); - } while (!fun && accept(',')); + switch (tp->type) { + case FTN: + if (yytoken == '{') { + if (curctx != CTX_OUTER) + error("cannot use local functions"); + aux = function(sym); + addstmt(&c, node(ODEF, nodesym(sym), aux)); + return c.tree; + } + break; + case STRUCT: + case UNION: + if (tp->forward) + error("declaration of variable with incomplete type"); + default: + aux = (accept('=')) ? initializer(tp) : NULL; + addstmt(&c, node(ODEF, nodesym(sym), aux)); + } + } while (accept(',')); - if (!fun) - expect(';'); + expect(';'); return c.tree; }