aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-05-29 14:40:50 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-05-29 14:40:50 -0700
commit680d60678b273f1ff20b013b24954773f76b4e1d (patch)
treee164dd28a8534fe27313d604435333e897a45d39
parent3eff49e57b9d122a1da1103988731c9ace69c304 (diff)
checkin: before fix of stale type pointer bug
-rw-r--r--sys/cmd/cc/ast.c504
-rw-r--r--sys/cmd/cc/bits.c70
-rw-r--r--sys/cmd/cc/cc.c13
-rw-r--r--sys/cmd/cc/cc.h80
-rw-r--r--sys/cmd/cc/scratch.c7
5 files changed, 456 insertions, 218 deletions
diff --git a/sys/cmd/cc/ast.c b/sys/cmd/cc/ast.c
index 0547712..e471a32 100644
--- a/sys/cmd/cc/ast.c
+++ b/sys/cmd/cc/ast.c
@@ -31,14 +31,15 @@ nameof(Name *n)
return nameof(n->sfx.name);
}
panicf("unreachable");
+ return nil;
}
static
void
openscope(Parser *p)
{
- if (++p->sp == p->spstk + arrlen(p->spstk))
- panicf("too many nested scopes: crashing");
+ if (++p->sp >= arrend(p->spstk))
+ panicf("scope stack overflow");
}
/*
@@ -50,21 +51,22 @@ static
void
closescope(Parser *p)
{
- if (p->sp == p->spstk)
- panicf("attempting to close the top level scope: crashing");
+ if (p->sp <= p->spstk)
+ panicf("scope stack underflow");
forgetall(&p->sp->objs);
forgetall(&p->sp->tags);
p->sp--;
}
+/* temporary stack helpers */
static
Dtor*
getdtor(Parser *p)
{
- if (p->dt >= p->dtstk + arrlen(p->dtstk)) {
- panicf("out of dtor buffer space");
- }
+ if (p->dt >= arrend(p->dtstk))
+ panicf("dtor stack overflow");
+
return p->dt++;
}
@@ -72,9 +74,8 @@ static
void
putdtor(Parser *p)
{
- if (p->dt == p->dtstk) {
- panicf("too many frees of dtor buffer space");
- }
+ if (p->dt <= p->dtstk)
+ panicf("dtor stack underflow");
*p->dt-- = (Dtor){0};
}
@@ -82,9 +83,8 @@ static
Name*
getname(Parser *p)
{
- if (p->nm >= p->nmstk + arrlen(p->nmstk)) {
- panicf("out of dtor buffer space");
- }
+ if (p->nm >= arrend(p->nmstk))
+ panicf("name stack overflow");
return p->nm++;
}
@@ -92,48 +92,44 @@ static
void
putname(Parser *p)
{
- if (p->nm == p->nmstk) {
- panicf("too many frees of dtor buffer space");
- }
+ if (p->nm <= p->nmstk)
+ panicf("name stack underflow");
+
*p->nm-- = (Name){0};
}
-#if 0
static
void
declareobj(Parser *p, Decl *d)
{
Sym *sym;
string ident;
+ uint32 kind;
struct Decls *link;
+ kind = (d->spec & Mtype) ? Stype : Svar;
+
switch (d->kind) {
case Dfunc:
- ident = nameof(&d->func.name);
- break;
-
- case Dvar:
- ident = nameof(&d->var.name);
- break;
-
- case Dtype:
- ident = nameof(&d->type.name);
+ case Dobj:
+ ident = d->name;
break;
- case Dvars:
- while (link = d->var.link, link != nil) {
- ident = nameof(&link->name);
+ case Dobjs:
+ while (link = &d->objs, link != nil) {
+ ident = link->name;
sym = lookup(&p->sp->objs, ident);
if (sym) {
errorat(peek(p, 0).pos, "redeclaration of name '%s' in object space", ident);
return;
}
- define(&p->sp->objs, ident, Sobj);
+ sym = define(&p->sp->objs, ident, kind);
+ sym->obj = d;
}
- return;
- default:
- panicf("unrecognized node kind %d inside declaraction", d->kind);
+ break;
+ default:
+ panicf("unrecognized node kind %d inside declaration", d->kind);
}
sym = lookup(&p->sp->objs, ident);
@@ -141,24 +137,43 @@ declareobj(Parser *p, Decl *d)
errorat(peek(p, 0).pos, "redeclaration of name '%s' in object space", ident);
return;
}
+ sym = define(&p->sp->objs, ident, kind);
+ sym->obj = d;
+}
- define(&p->sp->objs, ident, Sobj);
+/* enters the object identifier space */
+static
+void
+declareenum(Parser *p, int n, string *elts, Expr *vals)
+{
+ int i;
+ Sym *s;
+
+ for (i = 0; i < n; i++) {
+ s = lookup(&p->sp->objs, elts[i]);
+ if (s) {
+ errorat(peek(p, 0).pos, "redeclaration of name %s in object space", elts[i]);
+ continue;
+ }
+ s = define(&p->sp->objs, elts[i], Senum);
+ s->val = vals + i;
+ }
}
static
-Sym *
-declaretag(Parser *p, Type *t)
+void
+declaretag(Parser *p, Type *t, string name)
{
Sym *sym;
- sym = lookup(&p->sp->tags, t->ident);
+ sym = lookup(&p->sp->tags, name);
if (sym) {
- errorat(peek(p, 0).pos, "redeclaration of name '%s' in tag space", t->ident);
- return sym;
+ errorat(peek(p, 0).pos, "redeclaration of name '%s' in tag space", name);
+ return;
}
- return define(&p->sp->tags, t->ident, Stype);
+ sym = define(&p->sp->tags, name, Stype);
+ sym->typ = t;
}
-#endif
static
Sym *
@@ -206,7 +221,6 @@ nomatch(Token t, vlong kind)
static error spec(Parser *, Lexer *, uint64 *);
static error dtor(Parser *p, Lexer *lx, Dtor *d, int ab);
-static Type *typeofspec(Parser *, Lexer *, uint64 *);
static Type *typeofdtor(Dtor *, Type *);
static Decl *decl(Parser *, Lexer *);
@@ -1014,29 +1028,149 @@ Bad:
}
// -----------------------------------------------------------------------
-// declarations
+// types
+
+Type *
+ptrtype(Type *base, uint32 qual)
+{
+ Type *t;
+
+ t = type();
+ t->kind = Tptr;
+ t->ptr.base = base;
+ t->ptr.qual = qual;
+ t->size = pointer.size;
+ t->align = pointer.align;
+ t->sign = pointer.sign;
+
+ return t;
+}
+
+Type*
+arraytype(Type *base, uint32 qual, Expr *ix)
+{
+ int n;
+ Type *t;
+
+ /* TODO: evaluate the length */
+ n = 10;
+ t = type();
+ t->kind = Tarray;
+ t->ptr.base = base;
+ t->size = n * base->size;
+ t->align = base->align;
+ t->sign = 0;
+
+ return t;
+}
+
+Type*
+functype(Type *ret, int n, Field *args, int dots)
+{
+ int i;
+ Type *t;
+
+ t = type();
+ t->kind = Tfunc;
+ t->size = pointer.size;
+ t->align = pointer.align;
+ t->sign = pointer.sign;
+
+ t->func.ret = ret;
+ t->func.n = n;
+ t->func.arg = args;
+ t->func.dots = dots;
+
+ return t;
+}
+
+#define ALIGN_DOWN(n, a) ((n) & ~((a)-1))
+#define ALIGN_UP(n, a) ALIGN_DOWN((n) + (a)-1, (a))
+Type *
+structtype(int n, Field *field, Expr *bits)
+{
+ Type *t;
+ Field *f, *e;
+
+ t = type();
+ t->kind = Tstruct;
+ t->size = 0;
+ t->align = 0;
+ for (f = field, e = field+n; f != e; ++f) {
+ t->size += f->type->size + ALIGN_UP(t->size, f->type->align);
+ t->align = MAX(t->align, f->type->align);
+ }
+ t->aggr.len = n;
+ t->aggr.f = field;
+ t->aggr.x = bits;
+ return t;
+}
+
+Type *
+uniontype(int n, Field *field, Expr *bits)
+{
+ Type *t;
+ Field *f, *e;
+
+ t = type();
+ t->kind = Tstruct;
+ t->size = 0;
+ t->align = 0;
+ for (f = field, e = field+n; f != e; ++f) {
+ t->size = MAX(t->size, f->type->size);
+ t->align = MAX(t->align, f->type->align);
+ }
+ t->aggr.len = n;
+ t->aggr.f = field;
+ t->aggr.x = bits;
+
+ return t;
+}
+
+Type *
+enumtype(int n, string *elts, Expr *vals)
+{
+ Type *t;
+ Field *f, *e;
+
+ t = type();
+ t->kind = Tenum;
+ /* TODO: dont hardcode int32 */
+ t->size = 4;
+ t->align = 4;
+ t->enm.len = n;
+ t->enm.elt = elts;
+ t->enm.val = vals;
+
+ return t;
+}
+#undef ALIGN_UP
+#undef ALIGN_DOWN
+
+/* unpacking C declarations into sensible types */
static
Type *
-typeofname(Name *name, Type *type)
+typeofname(Name *name, Type *base)
{
switch (name->kind) {
case Nident:
- return type;
+ return base;
case Nparen:
- return typeofdtor(name->paren, type);
+ return typeofdtor(name->paren, base);
case Nindex:
- return typeofname(name->sfx.name, array(type, name->sfx.idx.q, name->sfx.idx.x));
+ return typeofname(name->sfx.name, arraytype(base, name->sfx.idx.q, name->sfx.idx.x));
case Ncall:
- return typeofname(name->sfx.name, func(type, name->sfx.call.n, name->sfx.call.arg, name->sfx.call.dots));
+ return typeofname(name->sfx.name, functype(base, name->sfx.call.n, name->sfx.call.arg, name->sfx.call.dots));
default:
panicf("unreachable");
}
+ return nil;
}
static
Type *
-typeofdtor(Dtor *decl, Type* type)
+typeofdtor(Dtor *decl, Type* base)
{
int n;
Ptr *p;
@@ -1046,7 +1180,7 @@ typeofdtor(Dtor *decl, Type* type)
p = &decl->ptr;
b = p->kind;
while (b & 1) {
- type = ptr(type, b >> 1);
+ base = ptrtype(base, b >> 1);
if (++n >= 8) {
p = p->link;
b = p->kind;
@@ -1055,34 +1189,124 @@ typeofdtor(Dtor *decl, Type* type)
}
}
- return typeofname(decl->name, type);
+ return typeofname(decl->name, base);
}
static
-Type *
-aggr(Parser *p, Lexer *lx, string name, int kind)
+Type*
+basetype(Parser *p, Lexer *lx, uint64 *s)
{
int n;
+ uint64 m;
+
+ if (spec(p, lx, s)) {
+ errorat(lx->pos, "failed to parse type specifier");
+ return nil;
+ }
+
+ m = (((*s<<32)>>32) & ~(MaskQul | MaskMem));
+ for (n = 0; n < arrlen(validtypespec); n++) {
+ if (validtypespec[n] == m)
+ if (indextypespec < 0) {
+ m = *s >> 32;
+ if (!m) {
+ errorat(lx->pos, "not a valid type identifier");
+ return nil;
+ }
+ return C.type.info + m;
+ }
+ return C.type.info + indextypespec[n];
+ }
+
+ errorat(lx->pos, "invalid type specifier");
+ return nil;
+}
+
+static
+string
+namedecl(Parser *p, Lexer *lx, Type **base)
+{
+ Dtor *dt;
+ string name;
+ Type *t;
+
+ dt = getdtor(p);
+ name = nil;
+ if (dtor(p, lx, dt, 0)) {
+ errorat(lx->pos, "invalid declarator");
+ goto End;
+ }
+ name = nameof(dt->name);
+ *base = typeofdtor(dt, *base);
+End:
+ putdtor(p);
+ return nil;
+}
+
+// -----------------------------------------------------------------------
+// declarations
+
+static
+Type *
+enumerate(Parser *p, Lexer *lx, string name)
+{
+ int i, n;
uint64 s;
- Dtor *dt;
Token tk;
Type *t;
- Type *fs[1024];
- byte *nm[1024];
- Expr *cx[1024];
+ /* TODO: think of a better soln */
+ string nm[1024], *elts;
+ Expr *cx[1024], *vals;
- n = -1;
- for (;tk.kind != Arbrace && n < arrlen(fs); n++) {
- t = typeofspec(p, lx, &s);
+ for (n = 0; tk.kind != Arbrace && n < arrlen(nm); n++) {
+ if (tk.kind != Aident) {
+ errorat(tk.pos, "invalid token %s in enum declaration", tokens[tk.kind]);
+ goto Bad;
+ }
+ nm[n] = tk.val.s;
+ cx[n] = nil;
- Field:
- dt = getdtor(p);
- dtor(p, lx, dt, 0);
- fs[n] = typeofdtor(dt, t);
- nm[n] = nameof(dt->name);
- putdtor(p);
+ tk = advance(p, lx);
+ switch(tk.kind) {
+ case Aeq:
+ advance(p, lx);
+ cx[n] = expr(p, lx);
+ tk = peek(p, 0);
+ if (tk.kind != Acomma)
+ continue;
+ /* fallthrough */
+ case Acomma:
+ tk = advance(p, lx);
+ }
+ }
+ copyarray(elts, nm, n);
+ copyarray(vals, cx, n);
- tk = peek(p, 0);
+ t = enumtype(n, elts, vals);
+ declareenum(p, n, elts, vals);
+ return t;
+Bad:
+ errorat(tk.pos, "failed to parse enum declaration");
+ return nil;
+}
+
+static
+Type *
+aggregate(Parser *p, Lexer *lx, string name, int kind)
+{
+ int n;
+ uint64 s;
+ Token tk;
+ /* TODO: think of a better soln */
+ Field fs[1024], *f;
+ Expr *cx[1024], *x;
+
+ for (n = 0; tk.kind != Arbrace && n < arrlen(fs); n++) {
+ fs[n].type = basetype(p, lx, &s);
+ fs[n].qual = (uint32)s;
+ Field:
+ fs[n].name = namedecl(p, lx, &fs[n].type);
+ tk = peek(p, 0);
switch (tk.kind) {
case Acolon:
advance(p, lx);
@@ -1111,7 +1335,9 @@ aggr(Parser *p, Lexer *lx, string name, int kind)
goto Bad;
}
}
-
+ copyarray(f, fs, n);
+ copyarray(x, cx, n);
+ return structtype(n, f, x);
Bad:
errorat(tk.pos, "failed to parse aggregate declaration");
return nil;
@@ -1198,7 +1424,7 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
s += Bit(n);
t = advance(p, lx);
if (t.kind != Aident && t.kind != Albrace) {
- errorat(t.pos, "struct specifier missing valid declaration");
+ errorat(t.pos, "aggregate specifier missing valid declaration");
goto Bad;
}
@@ -1210,13 +1436,15 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
}
if (t.kind == Albrace) {
t = advance(p, lx);
- tag = aggr(p, lx, name, s & (Tstruct | Tunion));
+ tag = aggregate(p, lx, name, s & (Tstruct | Tunion));
if (nomatch(t, Arbrace)) {
errorat(t.pos, "invalid token %s in struct/union declaration", tokens[t.kind]);
goto Bad;
}
}
+ if (name)
+ declaretag(p, tag, name);
break;
case Kenum:
@@ -1225,6 +1453,32 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
goto Bad;
}
s += Bit(n);
+ t = advance(p, lx);
+ if (t.kind != Aident && t.kind != Albrace) {
+ errorat(t.pos, "enum specifier missing valid declaration");
+ goto Bad;
+ }
+
+ name = nil;
+ tag = nil;
+ if (t.kind == Aident) {
+ name = t.val.s;
+ t = advance(p, lx);
+ }
+ if (t.kind == Albrace) {
+ t = advance(p, lx);
+ tag = enumerate(p, lx, name);
+
+ if (nomatch(t, Arbrace)) {
+ errorat(t.pos, "invalid token %s in enum declaration", tokens[t.kind]);
+ goto Bad;
+ }
+ }
+ if (name)
+ declaretag(p, tag, name);
+ break;
+
+
panicf("need to implement");
break;
@@ -1247,37 +1501,6 @@ Bad:
return 1;
}
-static
-Type*
-typeofspec(Parser *p, Lexer *lx, uint64 *s)
-{
- int n;
- uint64 m;
-
- if (spec(p, lx, s)) {
- errorat(lx->pos, "failed to parse type specifier");
- return nil;
- }
-
- m = (((*s<<32)>>32) & ~(MaskQul | MaskMem));
- for (n = 0; n < arrlen(validtypespec); n++) {
- if (validtypespec[n] == m)
- if (indextypespec < 0) {
- m = *s >> 32;
- if (!m) {
- errorat(lx->pos, "not a valid type identifier");
- return nil;
- }
- return C.type.info + m;
- }
- return C.type.info + indextypespec[n];
- }
-
- errorat(lx->pos, "invalid type specifier");
- return nil;
-}
-
-
/* name declaration */
static
error
@@ -1286,12 +1509,11 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
Token t;
int n, k;
uint64 s;
- Sym *sym;
- Dtor *dt;
+ Sym *sym;
Name *nm, *tmp;
/* max args = 100 */
- struct Obj args[100];
+ struct Field args[100];
nm = *nmp;
t = peek(p, 0);
@@ -1408,8 +1630,8 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
if (!sym || (sym && sym->kind != Stype)) {
while (t.kind == Aident) {
if (nm->sfx.call.n >= arrlen(args))
- panicf("out of ident buffer");
- args[nm->sfx.call.n++] = (struct Obj) {
+ panicf("ident stack overflow");
+ args[nm->sfx.call.n++] = (struct Field) {
.qual = 0,
.type = nil,
.name = t.val.s,
@@ -1430,25 +1652,21 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
errorat(t.pos, "invalid keyword %s inside function signature");
goto Bad;
}
+
Params:
do {
if (nm->sfx.call.n >= arrlen(args)-1)
panicf("out of argument buffer");
- if (spec(p, lx, &s)) {
- errorat(lx->pos, "invalid type qualifier list in function signature");
- goto Bad;
- }
-
- dt = getdtor(p);
- if (dtor(p, lx, dt, 0)) {
- errorat(lx->pos, "could not parse declarator of function argument");
- putdtor(p);
+ args[nm->sfx.call.n].type = basetype(p, lx, &s);
+ if (!args[nm->sfx.call.n].type) {
+ errorat(lx->pos, "could not parse base type in function call");
goto Bad;
}
+ args[nm->sfx.call.n].qual = (uint32)s;
+ args[nm->sfx.call.n].name = namedecl(p, lx, &args[nm->sfx.call.n].type);
- pack(s, dt, &args[nm->sfx.call.n++]);
- putdtor(p);
+ nm->sfx.call.n++;
} while (t = peek(p, 0), t.kind == Acomma);
if (t.kind == Aellip) {
@@ -1554,58 +1772,60 @@ decl(Parser *p, Lexer *lx)
Token t;
Decl *d;
Expr *x;
- Dtor *dt, *dt0;
+ Type *base, *type;
+ string name;
struct Decls *ds;
alloc(d);
+
d->kind = 0;
d->pos.beg = lx->pos;
- if (spec(p, lx, &s)) {
- errorat(lx->pos, "invalid declaration specifier");
- goto Bad;
- }
-
- dt = getdtor(p);
- dt0 = dt;
- if (dtor(p, lx, dt, 0)) {
- errorat(lx->pos, "invalid declarator");
+ base = basetype(p, lx, &s);
+ if (!base) {
+ errorat(lx->pos, "could not parse type declaration");
goto Bad;
}
x = nil;
- ds = &d->vars;
d->spec = (uint32)s;
+ d->type = base;
+ d->name = namedecl(p, lx, &d->type);
switch (t = peek(p, 0), t.kind) {
case Aeq:
t = advance(p, lx);
x = expr(p, lx);
if (t.kind != Acomma) {
- d->kind = Dvar;
+ d->kind = Dobj;
d->init = x;
break;
}
/* fallthrough */
case Acomma:
- d->kind = Dvars;
- d->vars.init = x;
+ d->kind = Dobjs;
+ d->objs.init = x;
+ /* move singleton data over */
+ name = d->name;
+ type = d->type;
+ d->objs.name = name;
+ d->objs.type = type;
+ ds = &d->objs;
+ /* iterate until we hit end of list */
while (t.kind == Acomma) {
+ t = advance(p, lx);
+
alloc(ds->link);
ds = ds->link;
-
- t = advance(p, lx);
- dt = getdtor(p);
- if (dtor(p, lx, dt, 0)) {
- errorat(lx->pos, "invalid declarator");
- goto Bad;
- }
+ ds->type = base;
+ ds->name = namedecl(p, lx, &ds->type);
t = peek(p, 0);
if (t.kind == Aeq) {
t = advance(p, lx);
ds->init = expr(p, lx);
- }
+ } else
+ ds->init = nil;
}
break;
@@ -1634,13 +1854,9 @@ decl(Parser *p, Lexer *lx)
}
d->pos.end = lx->pos;
- // declareobj(p, d);
- while (dt-- >= dt0)
- putdtor(p);
+ declareobj(p, d);
return d;
Bad:
- while (dt-- >= dt0)
- putdtor(p);
errorat(lx->pos, "failed to parse top level declaration");
return nil;
}
diff --git a/sys/cmd/cc/bits.c b/sys/cmd/cc/bits.c
index 19adf52..a13938c 100644
--- a/sys/cmd/cc/bits.c
+++ b/sys/cmd/cc/bits.c
@@ -5,7 +5,7 @@
enum
{
- arch·x64,
+ archx64,
numarch,
};
@@ -46,47 +46,47 @@ enum
#define IMAGINARY X(Timag, 21)
/* fixed width definitions */
-#define DEF(name, sz, aln, mx, sgn) {.ident=#name, .size=sz, .align=aln, .max=mx, .sign=sgn }
+#define DEF(sz, aln, mx, sgn) {.size=sz, .align=aln, .max=mx, .sign=sgn }
-#define INT8(name) DEF(name, 1, 1, 0x7f, 0)
-#define UINT8(name) DEF(name, 1, 1, 0xff, 1)
+#define INT8 DEF(1, 1, 0x7fff, 0)
+#define UINT8 DEF(1, 1, 0xffff, 1)
-#define INT16(name) DEF(name, 2, 2, 0x7fff, 0)
-#define UINT16(name) DEF(name, 2, 2, 0xffff, 1)
+#define INT16 DEF(2, 2, 0x7fff, 0)
+#define UINT16 DEF(2, 2, 0xffff, 1)
-#define INT32(name) DEF(name, 4, 4, 0x7fffffff, 0)
-#define UINT32(name) DEF(name, 4, 4, 0xffffffff, 1)
+#define INT32 DEF(4, 4, 0x7fffffff, 0)
+#define UINT32 DEF(4, 4, 0xffffffff, 1)
-#define INT64(name) DEF(name, 8, 8, 0x7fffffffffffffff, 0)
-#define UINT64(name) DEF(name, 8, 8, 0xffffffffffffffff, 1)
+#define INT64 DEF(8, 8, 0x7fffffffffffffff, 0)
+#define UINT64 DEF(8, 8, 0xffffffffffffffff, 1)
/* architecture specific definitions */
// TODO: max value should be able to take floats
-#define TYPES \
- TYPE(DEF(void, 0, 0, 0, 0), VOID) \
- TYPE(INT8(bool), BOOL) \
- TYPE(UINT8(char), CHAR) \
- TYPE(INT8(signed char), SCHAR) \
- TYPE(UINT8(unsigned char), UCHAR) \
- TYPE(INT16(short), SHORT) \
- TYPE(INT16(signed short), SSHORT) \
- TYPE(UINT16(unsigned short), USHORT) \
- TYPE(INT32(int), INT) \
- TYPE(INT32(signed int), SINT) \
- TYPE(UINT32(unsigned int), UINT) \
- TYPE(INT64(long), LONG) \
- TYPE(INT64(signed long), SLONG) \
- TYPE(UINT64(unsigned long), ULONG) \
- TYPE(INT64(long long), VLONG) \
- TYPE(INT64(signed long long), SVLONG) \
- TYPE(UINT64(unsigned long long), UVLONG) \
- TYPE(DEF(float, 4, 4, 0, 0), FLOAT) \
- TYPE(DEF(double, 8, 8, 0, 0), DOUBLE) \
- TYPE(DEF(long double, 16, 16, 0, 0), LONGDB) \
- TYPE(DEF(complex, 8, 8, 0, 0), COMPLEX) \
- TYPE(DEF(imaginary, 4, 4, 0, 0), IMAGINARY) \
-
-Type pointer = {.ident = "<pointer>", .size=8, .align=8, .max=0xffffffffffffffff, .sign=0};
+#define TYPES \
+ TYPE(DEF(0, 0, 0, 0), VOID) \
+ TYPE(INT8, BOOL) \
+ TYPE(UINT8, CHAR) \
+ TYPE(INT8, SCHAR) \
+ TYPE(UINT8, UCHAR) \
+ TYPE(INT16, SHORT) \
+ TYPE(INT16, SSHORT) \
+ TYPE(UINT16, USHORT) \
+ TYPE(INT32, INT) \
+ TYPE(INT32, SINT) \
+ TYPE(UINT32, UINT) \
+ TYPE(INT64, LONG) \
+ TYPE(INT64, SLONG) \
+ TYPE(UINT64, ULONG) \
+ TYPE(INT64, VLONG) \
+ TYPE(INT64, SVLONG) \
+ TYPE(UINT64, UVLONG) \
+ TYPE(DEF(4, 4, 0, 0), FLOAT) \
+ TYPE(DEF(8, 8, 0, 0), DOUBLE) \
+ TYPE(DEF(16, 16, 0, 0), LONGDB) \
+ TYPE(DEF(8, 8, 0, 0), COMPLEX) \
+ TYPE(DEF(4, 4, 0, 0), IMAGINARY) \
+
+Type pointer = {.size=8, .align=8, .max=0xffffffffffffffff, .sign=0};
/* pack architecture specific definitions into exported arrays */
#define TYPE(a, ...) a,
diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c
index d5cd995..a25fd69 100644
--- a/sys/cmd/cc/cc.c
+++ b/sys/cmd/cc/cc.c
@@ -94,6 +94,19 @@ END:
// -----------------------------------------------------------------------
// type interning
+Type *
+type()
+{
+ Type *t;
+
+ if (C.type.len >= C.type.cap) {
+ C.type.cap += 100;
+ C.type.info = realloc(C.type.info, C.type.cap * sizeof(*C.type.info));
+ }
+
+ return C.type.info + C.type.len++;
+}
+
// -----------------------------------------------------------------------
// universal compiler builtins
diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h
index ce7eca7..e711770 100644
--- a/sys/cmd/cc/cc.h
+++ b/sys/cmd/cc/cc.h
@@ -22,7 +22,7 @@ typedef struct Parser Parser;
typedef struct Ptr Ptr;
typedef struct Name Name;
typedef struct Dtor Dtor;
-typedef struct Obj Obj;
+typedef struct Field Field;
typedef struct Node Node;
typedef struct Decl Decl;
@@ -229,12 +229,13 @@ struct Token
enum
{
- Sobj = iota(0),
- Stype = iota(2),
- Stag = iota(3),
- Senum = iota(4),
- Sstmt = iota(5),
- Smacro = iota(6),
+ Svar = iota(1),
+ Sfunc = iota(2),
+ Stype = iota(3),
+ Stag = iota(4),
+ Senum = iota(5),
+ Slabl = iota(6),
+ Smacro = iota(7),
};
struct Sym
@@ -246,6 +247,7 @@ struct Sym
Decl *obj;
Type *typ;
Stmt *blk;
+ Expr *val;
};
};
@@ -260,7 +262,7 @@ struct SymTab
Sym **vals;
};
-Sym *define(SymTab *tab, string ident, int kind);
+Sym *define(SymTab *tab, string ident, uint32 kind);
Sym *lookup(SymTab *tab, string ident);
error forget(SymTab *tab, string ident);
void forgetall(SymTab *tab);
@@ -370,9 +372,8 @@ enum
Dfunc,
- Dtype,
- Dvar,
- Dvars,
+ Dobj,
+ Dobjs,
/* names */
Nident,
@@ -578,7 +579,7 @@ struct Name
struct {
int n;
int dots : 1;
- Obj *arg;
+ Field *arg;
} call;
};
} sfx;
@@ -591,22 +592,24 @@ struct Dtor
Name *name;
};
-struct Decls
-{
- Type *type;
- Expr *init;
- struct Decls *link;
-};
-
/* final ast node */
-struct Obj
+struct Field
{
uint32 qual;
Type *type;
string name;
};
+struct Decls
+{
+ string name;
+ Type *type;
+ Expr *init;
+ struct Decls *link;
+};
+
+
struct Decl
{
struct Node;
@@ -620,7 +623,7 @@ struct Decl
Expr *init;
};
};
- struct Decls vars;
+ struct Decls objs;
};
};
@@ -628,15 +631,16 @@ enum
{
Tbad,
Tbase,
- Tarray,
+ Tdef,
Tptr,
+ Tarray,
+ Tfunc,
};
/* types */
struct Type
{
uint32 kind;
- string ident;
Sym *sym;
uintptr size;
uintptr max;
@@ -648,23 +652,25 @@ struct Type
Type *base;
} ptr;
struct {
- int len;
- Type *elt;
+ int len;
+ uint32 qual;
+ Type *elt;
} arr;
struct {
- int len;
- Obj *f;
- Expr *x;
+ int len;
+ Field *f;
+ Expr *x;
} aggr;
struct {
- int len;
- string *s;
- Expr *x;
+ int len;
+ string *elt;
+ Expr *val;
} enm;
struct {
Type *ret;
int n;
- Type **arg;
+ int dots : 1;
+ Field *arg;
} func;
};
};
@@ -719,6 +725,7 @@ struct StrTab
int32 *vals;
};
+#if 0
struct TypeSet
{
int32 n_buckets;
@@ -728,6 +735,7 @@ struct TypeSet
int32 *flags;
Type **keys;
};
+#endif
/* main data */
struct Compiler
@@ -749,13 +757,6 @@ struct Compiler
} inc;
struct {
- struct TypeSet p; // pointer
- struct TypeSet a; // array
- struct TypeSet f; // funcs
- struct TypeSet s; // structs
- struct TypeSet u; // unions
- struct TypeSet e; // enums
-
int cap;
int len;
Type *info;
@@ -767,5 +768,6 @@ extern Compiler C;
/* cc.c functions */
void init();
int32 intern(byte **str);
+Type *type();
#undef iota
diff --git a/sys/cmd/cc/scratch.c b/sys/cmd/cc/scratch.c
new file mode 100644
index 0000000..b37d9a5
--- /dev/null
+++ b/sys/cmd/cc/scratch.c
@@ -0,0 +1,7 @@
+#define XXX(a, b, c) a ## b ## c
+
+int
+main()
+{
+ XXX(d, e, f);
+}