scc

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

commit 242c473f7221643384498dd67ee2717f31482ffd
parent 94fd29519bd9650953b1f9b67ae62c628678297d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 31 May 2012 21:55:36 +0200

Added support for qualifiers in pointer types

Diffstat:
Mdecl.c | 37++++++++++++++++++++++++-------------
Mtypes.c | 22+++++++++++++++++++++-
Mtypes.h | 23+++++++++++++----------
3 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/decl.c b/decl.c @@ -198,32 +198,43 @@ incorrect_sign: void decl(void) { - unsigned char ns = 0; - unsigned char qlf[PTRLEVEL_MAX]; + unsigned char qlf[PTRLEVEL_MAX], *bp, *lim; puts("decl"); - for (ns = 0; yytoken == '*'; ns++) { - if (ns == PTRLEVEL_MAX) - error("Too much indirection levels"); + lim = qlf + PTRLEVEL_MAX; + for (bp = qlf; yytoken == '*' && bp != lim; ++bp) { + *bp = 0; + repeat_qlf: switch (gettok()) { case CONST: - if (!(qlf[ns] ^= 2)) + if (!(*bp ^= 1)) goto duplicated; - continue; + goto repeat_qlf; case RESTRICTED: - if (!(qlf[ns] ^= 4)) + if (!(*bp ^= 2)) goto duplicated; - continue; + goto repeat_qlf; case VOLATILE: - if (!(qlf[ns] ^= 8)) + if (!(*bp ^= 4)) goto duplicated; - continue; + goto repeat_qlf; + default: + break; } } + + if (bp == lim) + error("Too much indirection levels"); + dirdcl(); - if (ns) - push(PTR); /* TODO: pointer qualifiers */ + while (bp-- != qlf) { + if (*bp & 1) push(CONST); + if (*bp & 2) push(RESTRICTED); + if (*bp & 4) push(VOLATILE); + push(PTR); + } + printf("leaving dcl %c\n", yytoken); return; diff --git a/types.c b/types.c @@ -26,7 +26,8 @@ struct type tvoid = {.btype = VOID, .sign = 0}; struct type *mktype(register struct type *base, unsigned char op) { register struct type **ptr, *nt; - assert(op == PTR || op == ARY || op == FTN); + assert(op == PTR || op == ARY || op == FTN || + op == VOLATILE || op == RESTRICTED || op == CONST); switch (op) { case PTR: @@ -38,6 +39,15 @@ struct type *mktype(register struct type *base, unsigned char op) case FTN: ptr = &base->ftn; break; + case VOLATILE: + ptr = &base->vltl; + break; + case RESTRICTED: + ptr = &base->rstr; + break; + case CONST: + ptr = &base->cnst; + break; } if (*ptr) return *ptr; @@ -69,6 +79,16 @@ void ptype(register struct type *t) case FTN: fputs("function that returns ", stdout); break; + case VOLATILE: + fputs("volatile ", stdout); + break; + break; + case RESTRICTED: + fputs("restricted ", stdout); + break; + case CONST: + fputs("const ", stdout); + break; default: { static char *type, *sign; diff --git a/types.h b/types.h @@ -3,11 +3,15 @@ struct type { - unsigned char op; + unsigned op : 5; struct type *base; - struct type *ary; /* array */ - struct type *ptr; /* pointer */ - struct type *ftn; /* function */ + struct type *ary; /* array */ + struct type *ptr; /* pointer */ + struct type *ftn; /* function */ + struct type *cnst; /* const */ + struct type *vltl; /* volatile */ + struct type *rstr; /* restricted */ + union { struct { unsigned btype : 4; @@ -37,13 +41,12 @@ extern struct type tulong, tllong, tullong, tvoid; #define T_ULLONG (&tullong) #define T_VOID (&tvoid) +#define ARY 1 +#define PTR 2 +#define FTN 3 + +#define QLF(x) (VOLATILE - x + 1) -#define ARY 1 -#define PTR 2 -#define FTN 3 -#define T_CONST 8 -#define T_RESTRICTED 16 -#define T_VOLATILE 32 struct type *mktype(register struct type *base, unsigned char op);