commit b030a1fcb12be82e5c78e76c3a9a3eb76879334c
parent 627efdb4af18c26fa5707e247fc276837cfed3db
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 17 Mar 2014 18:02:22 +0100
Create newtag function
This function will be used by struct, enum and union in order to create
a new tag.
Diffstat:
3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/decl.c b/decl.c
@@ -177,6 +177,7 @@ specifier(int8_t *sclass)
switch (sym->u.c) {
case ENUM: case STRUCT: case UNION:
t = sym->u.c;
+ next();
tp = (t == UNION) ? enumdcl(t) : structdcl(t);
p = &type;
goto check_spec;
@@ -288,14 +289,11 @@ fielddcl(uint8_t ns, uint8_t type)
}
static struct ctype *
-structdcl(uint8_t tag)
+newtag(uint8_t tag)
{
register struct symbol *sym;
- struct ctype *tp;
- short size;
extern uint8_t namespace;
- next();
if (yytoken == IDEN) {
sym = lookup(yytext, NS_TAG);
if (sym) {
@@ -308,28 +306,40 @@ structdcl(uint8_t tag)
} else {
sym = install(NULL, NS_TAG);
}
- sym->type = tp = mktype(NULL, STRUCT, NULL, 0);
++namespace;
+ return sym->type = mktype(NULL, tag, NULL, 0);
+bad_tag:
+ error("'%s' defined as wrong kind of tag", yytext);
+}
+
+static struct ctype *
+structdcl(uint8_t tag)
+{
+ struct ctype *tp;
+ short size = 0;
+
+ tp = newtag(tag);
if (yytoken != ';') {
expect('{');
+ if (tp->defined)
+ goto redefined;
while (!accept('}'))
size = fielddcl(namespace, tag);
- } else {
- size = 0;
+ tp->size = size;
+ tp->defined = 1;
}
- tp->size = size;
return tp;
-bad_tag:
- error("error '%s' defined as wrong kind of tag", yytext);
+redefined:
+ error("redefinition of struct/union '%s'", yytext);
}
static struct ctype *
enumdcl(uint8_t token)
{
- return NULL;
+ /* TODO: create function for creating identifiers */
}
struct node *
diff --git a/symbol.h b/symbol.h
@@ -21,9 +21,9 @@ struct symbol;
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 */
+ short size; /* size of variables */
+ short nelem; /* number of elements in arrays */
+ unsigned defined : 1; /* type defined (is not a forward reference) */
unsigned cplex : 1; /* complex specifier */
unsigned imag : 1;
unsigned sign : 1; /* sign type */
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 || op != STRUCT || op != ENUM) {
+ 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) {