scc

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

commit eea0139149e4b53947fc3ba850a0b3f4713f3837
parent 9a456e19d03b2c6e68182cac6e8fbd77eecfc90e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 25 Jan 2016 20:08:21 +0100

[cc2] Add support for parsing structs and member definitions

We had to move type to the beginning of Symbol, because composed
returns the type associated to the Symbol where the type is stored,
but we need the symbol to store the name

Diffstat:
Mcc2/cc2.h | 3++-
Mcc2/parser.c | 73++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/cc2/cc2.h b/cc2/cc2.h @@ -113,11 +113,12 @@ struct type { }; struct symbol { + Type type; unsigned short id; unsigned short numid; char *name; - Type type; char kind; + TSIZE off; Symbol *next; Symbol *h_next; }; diff --git a/cc2/parser.c b/cc2/parser.c @@ -32,11 +32,11 @@ union tokenop { typedef void parsefun(char *, union tokenop); static parsefun type, symbol, getname, unary, binary, ternary, call, - parameter, constant, aggregate; + parameter, constant, composed; typedef void evalfun(void); static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, - endinit, array; + endinit, array, aggregate, flddecl; static struct decoc { void (*eval)(void); @@ -49,8 +49,8 @@ static struct decoc { [EXTRN] = {vardecl, symbol, .u.op = MEM}, [PRIVAT] = {vardecl, symbol, .u.op = MEM}, [LOCAL] = {vardecl, symbol, .u.op = MEM}, - [MEMBER] = {NULL, symbol}, - [LABEL] = {NULL, symbol}, + [MEMBER] = {flddecl, symbol}, + [LABEL] = {flddecl, symbol}, [INT8] = {NULL, type, .u.arg = &int8type}, [INT16] = {NULL, type, .u.arg = &int16type}, @@ -69,9 +69,9 @@ static struct decoc { [ELLIPSIS] = {NULL, type, .u.arg = &elipsistype}, [FUNCTION] = {NULL, type, .u.arg = &funtype}, - [VECTOR] = {array, aggregate}, - [UNION] = {NULL, NULL}, - [STRUCT] = {NULL, NULL}, + [VECTOR] = {array, composed}, + [UNION] = {aggregate, composed}, + [STRUCT] = {aggregate, composed}, [ONAME] = {NULL, getname}, ['{'] = {beginfun}, @@ -122,7 +122,7 @@ static struct decoc { }; static void *stack[STACKSIZ], **sp = stack; -static Symbol *lastsym, *curfun; +static Symbol *lastsym, *curfun, *lastaggreg; static Symbol *params[NR_FUNPARAM]; static int funpars = -1, sclass, callpars, ininit; static Node *stmtp, *callp; @@ -150,7 +150,7 @@ type(char *token, union tokenop u) } static void -aggregate(char *token, union tokenop u) +composed(char *token, union tokenop u) { Symbol *sym; @@ -323,6 +323,36 @@ endpars(void) } static void +aggregate(void) +{ + Node *align, *size; + char *name; + Type *tp; + Symbol *sym; + + align = pop(); + size = pop(); + name = pop(); + tp = pop(); + + tp->size = size->u.i; + tp->align = align->u.i; + /* + * type is the first field of Symbol so we can obtain the + * address of the symbol from the address of the type. + * We have to do this because composed returns the pointer + * to the type, but in this function we also need the + * symbol to store the name. + */ + sym = (Symbol *) tp; + lastaggreg = sym; + sym->name = name; + + delnode(align); + delnode(size); +} + +static void array(void) { Type *tp, *base; @@ -374,6 +404,31 @@ vardecl(void) } static void +flddecl(void) +{ + Node *off, *np; + char *name; + Type *tp; + Symbol *sym; + + if (!lastaggreg) + error(ESYNTAX); + + off = pop(); + name = pop(); + tp = pop(); + np = pop(); + + sym = np->u.sym; + sym->off = off->u.i; + sym->name = name; + sym->type = *tp; + + delnode(np); + delnode(off); +} + +static void stmt(void) { static Node *lastp;