scc

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

commit ed8f996d60efdfd7706c9e40a136a18f8422371d
parent 1f09b3f3edd53ace12c72126f5bbad44f4ae8e8b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 10 Sep 2014 18:25:20 +0200

Use different functions for every type of declarations

This change helps to clarify the code because the number of if
and branches decreases.

Diffstat:
Mcc2/parser.c | 143+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
1 file changed, 81 insertions(+), 62 deletions(-)

diff --git a/cc2/parser.c b/cc2/parser.c @@ -15,6 +15,9 @@ #define NR_NODEPOOL 128 #define NR_EXPRESSIONS 64 +#define LOCAL 0 +#define GLOBAL 1 + static Symbol *curfun; static Node *stack[NR_STACKSIZ], **stackp = stack; static Node *listexp[NR_EXPRESSIONS], **listp = listexp; @@ -339,66 +342,6 @@ expression(char *token) } static void -declaration(char *token) -{ - char class = token[0], *type, *name, *brace; - Symbol *sym; - - switch (class) { - case 'P': - if (!curfun) - error(ESYNTAX); - sym = local(token); - sym->next = curfun->u.f.pars; - curfun->u.f.pars = sym; - break; - case 'T': - if (!curfun) - error(ESYNTAX); - sym = local(token); - break; - case 'R': case 'A': - if (!curfun) - error(ESYNTAX); - sym = local(token); - sym->next = curfun->u.f.vars; - curfun->u.f.vars = sym; - break; - case 'X': - sym = global(token); - sym->extrn = 1; - break; - case 'Y': - sym = global(token); - break; - case 'G': - sym = global(token); - sym->public = 1; - break; - } - - type = strtok(NULL, "\t"); - if (type[0] == 'F') { - sym->type = FUN; - } else { - sym->type = VAR; - sym->u.v.sclass = class; - sym->u.v.type = gettype(type); - } - if (name = strtok(NULL, "\t")) - sym->name = xstrdup(name); - if (brace = strtok(NULL, "\t")) { - if (brace[0] != '{' || type[0] != 'F' || curfun) - error(ESYNTAX); - sym->u.f.vars = NULL; - sym->u.f.pars = NULL; - curfun = sym; - listp = listexp; - newp = nodepool; - } -} - -static void deflabel(char *token) { Symbol *sym; @@ -420,6 +363,76 @@ endfunction(char *token) curfun = NULL; } +static Symbol * +declaration(uint8_t t, char *token) +{ + static Symbol *(*tbl[2])(char *)= { + [LOCAL] = local, [GLOBAL] = global + }; + Symbol *sym = (*tbl[t])(token); + char *s; + + if (t == LOCAL && !curfun) + error(ESYNTAX); + if (sym->name) + free(sym->name); + memset(sym, 0, sizeof(*sym)); + sym->type = VAR; + sym->u.v.sclass = token[0]; + + if ((s = strtok(NULL, "\t")) == NULL) + error(ESYNTAX); + sym->u.v.type = gettype(s); + if ((s = strtok(NULL, "\t")) != NULL) + sym->name = xstrdup(s); + + return sym; +} + +static void +globdcl(char *token) +{ + Symbol *sym = declaration(GLOBAL, token); + + switch (token[0]) { + case 'X': + sym->extrn = 1; + break; + case 'G': + sym->public = 1; + break; + } + + if (sym->u.v.type != NULL) + return; + + if (curfun) + error(ESYNTAX); + + sym->type = FUN; + sym->u.f.vars = NULL; + sym->u.f.pars = NULL; + curfun = sym; + listp = listexp; + newp = nodepool; +} + +static void +paramdcl(char *token) +{ + Symbol *sym = declaration(LOCAL, token); + sym->next = curfun->u.f.pars; + curfun->u.f.pars = sym; +} + +static void +localdcl(char *token) +{ + Symbol *sym = declaration(LOCAL, token); + sym->next = curfun->u.f.vars; + curfun->u.f.vars = sym; +} + void parse(void) { @@ -439,8 +452,14 @@ parse(void) case 'S': /* struct */ break; - case 'Y': case 'T': case 'G': case 'A': case 'R': case 'P': - fun = declaration; + case 'P': + fun = paramdcl; + break; + case 'A': case 'R': case 'T': + fun = localdcl; + break; + case 'Y': case 'G': + fun = globdcl; break; case '}': fun = endfunction;