commit eaf8259846c2b6d77467cddf8fe143c6cce568dd
parent b2fc11b3d2e07e84e2868f5aab8319612257855c
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 17 Mar 2014 16:39:17 +0100
Add definitions for struct and enums
Diffstat:
5 files changed, 99 insertions(+), 62 deletions(-)
diff --git a/decl.c b/decl.c
@@ -11,9 +11,6 @@
int8_t forbid_eof;
-static struct dcldata
- *declarator0(struct dcldata *dp, uint8_t ns, int8_t flags);
-
struct dcldata {
uint8_t op;
union {
@@ -24,6 +21,9 @@ struct dcldata {
} u;
};
+static struct dcldata
+ *declarator0(struct dcldata *dp, uint8_t ns, int8_t flags);
+
static struct dcldata *
arydcl(struct dcldata *dp)
{
@@ -90,8 +90,6 @@ expected:
error: error(err, yytext);
}
-/* TODO: Add a token2 field in yylval to avoid yylval.sym->u.c */
-
static struct dcldata*
declarator0(struct dcldata *dp, uint8_t ns, int8_t flags)
{
@@ -155,13 +153,13 @@ declarator(struct ctype *tp, uint8_t ns, int8_t flags)
return sym;
}
-static struct ctype *structdcl(void), *enumdcl(void);
+static struct ctype *structdcl(uint8_t tag), *enumdcl(uint8_t tag);
static struct ctype *
specifier(int8_t *sclass)
{
struct ctype *tp = NULL;
- int8_t qlf, sign, type, cls, cplex, size;
+ int8_t qlf, sign, type, cls, cplex, size, t;
qlf = sign = type = cls = size = cplex = 0;
@@ -177,15 +175,16 @@ specifier(int8_t *sclass)
goto next_token;
case TYPE:
switch (sym->u.c) {
- case ENUM:
- tp = enumdcl(); goto set_type;
- case STRUCT: case UNION:
- tp = structdcl(); goto set_type;
+ case ENUM: case STRUCT: case UNION:
+ t = sym->u.c;
+ tp = (t == UNION) ? enumdcl(t) : structdcl(t);
+ p = &type;
+ goto check_spec;
case TYPENAME:
tp = yylval.sym->type;
case VOID: case BOOL: case CHAR:
case INT: case FLOAT: case DOUBLE:
-set_type: p = &type; break;
+ p = &type; goto next_token;
case SIGNED: case UNSIGNED:
p = &sign; break;
case LONG:
@@ -194,18 +193,18 @@ set_type: p = &type; break;
goto next_token;
}
case SHORT:
- p = &size; break;
+ p = &size; goto next_token;
case COMPLEX: case IMAGINARY:
- p = &cplex; break;
+ p = &cplex; goto next_token;
}
break;
default:
goto check_types;
}
- if (*p)
+next_token: next();
+check_spec: if (*p)
goto invalid_type;
*p = sym->u.c;
-next_token: next();
}
check_types:
@@ -246,19 +245,86 @@ initializer(register struct ctype *tp)
}
}
+/* TODO: add define for the 3 parameter of declarator */
+/* TODO: bitfields */
+static short
+fielddcl(uint8_t ns, uint8_t type)
+{
+ struct ctype *tp;
+ struct symbol *sym;
+ short offset = 0;
+
+ switch (yytoken) {
+ case IDEN:
+ warn(options.implicit,
+ "type defaults to 'int' in declaration");
+ tp = inttype;
+ break;
+ case SCLASS:
+ error("storage class '%s' in struct/union field", yytext);
+ case TYPE: case TQUALIFIER:
+ tp = specifier(NULL);
+ break;
+ case ';':
+ break;
+ default:
+ error("declaration expected");
+ }
+
+ if (yytoken != ';') {
+ do {
+ sym = declarator(tp, ns, 1);
+ sym->u.offset = offset;
+ if (type == STRUCT)
+ offset += sym->type->size;
+ } while (accept(','));
+ }
+
+ expect(';');
+ return offset;
+}
+
static struct ctype *
-structdcl(void)
+structdcl(uint8_t tag)
{
- uint8_t type = yylval.sym->u.c;
+ register struct symbol *sym;
+ struct ctype *tp;
+ short size;
+ extern uint8_t namespace;
next();
if (yytoken == IDEN) {
+ sym = lookup(yytext, NS_TAG);
+ if (sym) {
+ if (sym->type->op != tag)
+ goto bad_tag;
+ } else {
+ sym = install(yytext, NS_TAG);
+ }
+ next();
+ } else {
+ sym = install(NULL, NS_TAG);
}
- return NULL;
+ sym->type = tp = mktype(NULL, tag, NULL, 0);
+ ++namespace;
+
+ if (yytoken != ';') {
+ expect('{');
+ while (!accept('}'))
+ size = fielddcl(namespace, tag);
+ } else {
+ size = 0;
+ }
+ tp->size = size;
+
+ return tp;
+
+bad_tag:
+ error("error '%s' defined as wrong kind of tag", yytext);
}
static struct ctype *
-enumdcl(void)
+enumdcl(uint8_t token)
{
return NULL;
}
@@ -284,42 +350,6 @@ decl(void)
return NULL;
}
-static struct symbol *
-fielddcl(void)
-{
- struct ctype *tp;
- struct symbol *sym;
-
- switch (yytoken) {
- case IDEN:
- warn(options.implicit,
- "type defaults to 'int' in declaration");
- tp = inttype;
- break;
- case SCLASS:
- error("storage class '%s' in struct/union field", yytext);
- case TYPE: case TQUALIFIER:
- tp = specifier(NULL);
- break;
- case ';':
- break;
- default:
- error("declaration expected");
- }
-
- if (yytoken != ';') {
- do {
- sym = declarator(tp, 0, 1);
- if (accept(':'))
- ; /* TODO: bitfields */
- /* TODO: add to the aggregate */
- } while (accept(','));
- }
-
- expect(';');
- return NULL;
-}
-
struct node *
typename(void)
{
diff --git a/symbol.c b/symbol.c
@@ -101,9 +101,12 @@ install(char *s, uint8_t ns)
tbl = &symtab[(ns >= NR_NAMESPACES) ? NS_IDEN : ns];
sym->next = tbl->head;
tbl->head = sym;
- t = &tbl->htab[hash(s)];
- sym->hash = *t;
- *t = sym;
+
+ if (s != NULL) {
+ t = &tbl->htab[hash(s)];
+ sym->hash = *t;
+ *t = sym;
+ }
return sym;
}
diff --git a/symbol.h b/symbol.h
@@ -23,10 +23,10 @@ struct ctype {
uint8_t op; /* type builder operator */
uint8_t size; /* size of variables */
uint16_t nelem; /* number of elements in arrays */
- unsigned forward : 1; /* forward type */
+ unsigned forward : 1; /* forward type */
unsigned cplex : 1; /* complex specifier */
unsigned imag : 1;
- unsigned sign : 1; /* sign type */
+ unsigned sign : 1; /* sign type */
struct symbol *sym; /* symbol of the tag identifier */
struct ctype *type; /* base type */
struct ctype *next; /* next element in the hash */
@@ -46,6 +46,7 @@ struct symbol {
uint8_t ns;
union {
char c;
+ short offset;
} u;
struct symbol *next;
struct symbol *hash;
diff --git a/syntax.h b/syntax.h
@@ -6,6 +6,7 @@
#endif
extern unsigned char curctx;
+extern uint8_t namespace;
enum opcode {
OARY, OCALL, OFIELD, OPTR, OPOSTINC, OPOSTDEC,
diff --git a/types.c b/types.c
@@ -162,7 +162,7 @@ mktype(struct ctype *tp, uint8_t op,
t = (op ^ (uint8_t) ((unsigned short) tp >> 3))
& NR_TYPE_HASH-1;
tbl = &typetab[t];
- if (op != FTN) {
+ if (op != FTN || op != STRUCT || op != UNION || op != ENUM) {
for (bp = *tbl; bp; bp = bp->next) {
if (bp->type == tp && bp->op == op &&
bp->sym == sym && bp->nelem == nelem) {
@@ -175,6 +175,8 @@ mktype(struct ctype *tp, uint8_t op,
case PTR: size = PTRSIZE; break;
case FTN: size = 0; break;
case ARY: size = tp->size * nelem; break;
+ case ENUM: size = INTSIZE;
+ case STRUCT: case UNION: size = 0; break;
default: size = tp->size; break;
}
bp = xmalloc(sizeof(*bp));