scc

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

commit 42b7d44e5a719cb28265e58432dcdb306f687690
parent f29ca15fca80ed1d1f4865e9e7e258cfd3992948
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 11 Jul 2014 22:47:37 +0200

Accept parameter especificacion in function declaration

This is the first step in order to get functions in our compiler. It is
a naive implementation but good enough now.

Diffstat:
Mcc1/cc1.h | 2--
Mcc1/decl.c | 63++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -32,8 +32,6 @@ enum { typedef struct ctype Type; typedef struct symbol Symbol; -struct funpars; - typedef struct field { char *name; Type *type; diff --git a/cc1/decl.c b/cc1/decl.c @@ -15,7 +15,7 @@ struct dcldata { union { unsigned short nelem; Symbol *sym; - struct funpars *pars; + struct funpar *pars; uint8_t qlf; } u; }; @@ -34,15 +34,47 @@ arydcl(struct dcldata *dp) return dp + 1; } +static Type *parameter(void); + static struct dcldata * fundcl(struct dcldata *dp) { + uint8_t n = 0; + expect('('); + dp->op = FTN; + dp->u.pars = NULL; + + do { + struct funpar *fp; + Type *tp; + + if ((tp = parameter()) == voidtype) { + if (n == 0) + break; + else + error("incorrect void parameter"); + } + /* TODO: Use an array and allocate memory at the end */ + fp = xmalloc(sizeof(*fp)); + fp->type = tp; + fp->next = NULL; + if (!dp->u.pars) { + dp->u.pars = fp; + } else { + register struct funpar *p, *q; + + for (p = dp->u.pars; q = p->next; p = q) + /* nothing */; + p->next = fp; + } + ++n; + } while (accept(',')); + +ret: expect(')');; if (dp->op == 255) error("too much declarators"); - dp->op = FTN; - dp->u.pars = NULL; return dp + 1; } @@ -396,6 +428,31 @@ enumdcl(void) return tp; } +static Type * +parameter(void) +{ + Symbol *sym; + int8_t sclass; + Type *tp; + + if ((tp = specifier(&sclass)) == voidtype) + return tp; + sym = declarator(tp, ID_ACCEPTED); + sym->s.isdefined = 1; + /* TODO: check type of the parameter */ + switch (sclass) { + case REGISTER: + sym->s.isregister = 1; + break; + case 0: + sym->s.isauto = 1; + break; + default: + error("bad storage class in function parameter"); + } + return sym->type; +} + void decl(void) {