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:
M | cc1/cc1.h | | | 2 | -- |
M | cc1/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)
{