aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/cc
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-05-30 15:09:33 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-05-30 15:09:33 -0700
commitcf65141f154651115028d6456a1d7582d30b2083 (patch)
tree731b1b1fe7e513e8e9410ad090687fa203838f43 /sys/cmd/cc
parent038ea2d0a34fb362f577e6c9884c710ebaf4042e (diff)
many bug fixes
Diffstat (limited to 'sys/cmd/cc')
-rw-r--r--sys/cmd/cc/ast.c320
-rw-r--r--sys/cmd/cc/bits.c45
-rw-r--r--sys/cmd/cc/cc.c24
-rw-r--r--sys/cmd/cc/cc.h23
-rw-r--r--sys/cmd/cc/pp.c5
5 files changed, 260 insertions, 157 deletions
diff --git a/sys/cmd/cc/ast.c b/sys/cmd/cc/ast.c
index df390ba..f5d7a42 100644
--- a/sys/cmd/cc/ast.c
+++ b/sys/cmd/cc/ast.c
@@ -22,6 +22,9 @@ string
nameof(Name *n)
{
switch (n->kind) {
+ /* 0 corresponds to no state - i.e. an abstract name */
+ case Nnil:
+ return nil;
case Nident:
return n->ident;
case Nparen:
@@ -61,43 +64,64 @@ closescope(Parser *p)
/* temporary stack helpers */
static
-Dtor*
-getdtor(Parser *p)
+Name*
+getname(Parser *p)
{
- if (p->dt >= arrend(p->dtstk))
- panicf("dtor stack overflow");
-
- return p->dt++;
+ if (p->nm >= arrend(p->nmstk))
+ panicf("name stack overflow");
+ return p->nm++;
}
+static void putdtor(Parser *p, Dtor *dt);
+
static
void
-putdtor(Parser *p)
+putname(Parser *p, Name *n)
{
- if (p->dt <= p->dtstk)
- panicf("dtor stack underflow");
- *p->dt-- = (Dtor){0};
+ if (p->nm <= p->nmstk)
+ panicf("name stack underflow");
+
+ switch (n->kind) {
+ case Nnil:
+ case Nident:
+ break;
+ case Nparen:
+ putdtor(p, n->paren);
+ break;
+ case Nindex:
+ case Ncall:
+ putname(p, n->sfx.name);
+ break;
+ default:
+ panicf("unrecognized name kind");
+ }
+ *p->nm-- = (Name){0};
}
static
-Name*
-getname(Parser *p)
+Dtor*
+getdtor(Parser *p)
{
- if (p->nm >= arrend(p->nmstk))
- panicf("name stack overflow");
- return p->nm++;
+ if (p->dt >= arrend(p->dtstk))
+ panicf("dtor stack overflow");
+
+ p->dt->name = getname(p);
+ return p->dt++;
}
static
void
-putname(Parser *p)
+putdtor(Parser *p, Dtor *dt)
{
- if (p->nm <= p->nmstk)
- panicf("name stack underflow");
+ if (p->dt <= p->dtstk)
+ panicf("dtor stack underflow");
- *p->nm-- = (Name){0};
+ /* the dtor could encompass multiple names hierarchically */
+ putname(p, dt->name);
+ *p->dt-- = (Dtor){0};
}
+/* TODO: This will fail for forward declarations */
static
void
declareobj(Parser *p, Decl *d)
@@ -107,16 +131,24 @@ declareobj(Parser *p, Decl *d)
uint32 kind;
struct Decls *link;
- kind = (d->spec & Mtype) ? Stype : Svar;
-
switch (d->kind) {
case Dfunc:
- case Dobj:
+ case Dvar:
+ kind = Svar;
+ goto one;
+ case Dtype:
+ kind = Stype;
+ one:
ident = d->name;
break;
- case Dobjs:
- while (link = &d->objs, link != nil) {
+ case Dvars:
+ kind = Svar;
+ goto many;
+ case Dtypes:
+ kind = Stype;
+ many:
+ while (link = &d->list, link != nil) {
ident = link->name;
sym = lookup(&p->sp->objs, ident);
if (sym) {
@@ -124,21 +156,26 @@ declareobj(Parser *p, Decl *d)
return;
}
sym = define(&p->sp->objs, ident, kind);
- sym->obj = d;
+ if (kind == Svar)
+ sym->obj = d;
+ else
+ sym->type = d->type;
}
break;
default:
- panicf("unrecognized node kind %d inside declaration", d->kind);
+ panicf("unrecognized node kind %d. expected declaration", d->kind);
}
-
sym = lookup(&p->sp->objs, ident);
if (sym) {
errorat(peek(p, 0).pos, "redeclaration of name '%s' in object space", ident);
return;
}
sym = define(&p->sp->objs, ident, kind);
- sym->obj = d;
+ if (kind == Svar)
+ sym->obj = d;
+ else
+ sym->type = d->type;
}
/* enters the object identifier space */
@@ -212,7 +249,10 @@ nomatch(Token t, vlong kind)
if (t.kind == kind)
return 0;
- errorat(t.pos, "expected token '%s', instead found '%s'", tokens[t.kind], tokens[kind]);
+ if (t.kind == Akeywd)
+ errorat(t.pos, "expected token '%s', instead found keyword '%s'", tokens[kind], keywords[t.val.i]);
+ else
+ errorat(t.pos, "expected token '%s', instead found '%s'", tokens[kind], tokens[t.kind]);
return 1;
}
@@ -1275,6 +1315,8 @@ uint32
typeofname(Name *name, uint32 base)
{
switch (name->kind) {
+ /* Nnil corresponds to an abstract declarator (i.e. no identifier) */
+ case Nnil:
case Nident:
return base;
case Nparen:
@@ -1325,10 +1367,10 @@ basetype(Parser *p, Lexer *lx, uint64 *s)
return 0;
}
- m = (((*s<<32)>>32) & ~(MaskQul | MaskMem));
+ m = (((*s<<32)>>32) & ~(MaskQul | MaskMem | MaskFcn));
for (n = 0; n < arrlen(validtypespec); n++) {
- if (validtypespec[n] == m)
- if (indextypespec < 0) {
+ if (validtypespec[n] == m) {
+ if (indextypespec[n] < 0) {
m = *s >> 32;
if (!m) {
errorat(lx->pos, "not a valid type identifier");
@@ -1337,6 +1379,7 @@ basetype(Parser *p, Lexer *lx, uint64 *s)
return m;
}
return indextypespec[n];
+ }
}
errorat(lx->pos, "invalid type specifier");
@@ -1357,10 +1400,14 @@ namedecl(Parser *p, Lexer *lx, uint32 *base, int noname)
errorat(lx->pos, "invalid declarator");
goto End;
}
- name = nameof(dt->name);
+ if (!noname || noname == 2 && dt->name->kind)
+ name = nameof(dt->name);
+
*base = typeofdtor(dt, *base);
+ putdtor(p, dt);
+ return name;
End:
- putdtor(p);
+ putdtor(p, dt);
return nil;
}
@@ -1369,7 +1416,7 @@ End:
static
uint32
-enumerate(Parser *p, Lexer *lx, string name)
+enumerate(Parser *p, Lexer *lx, string name, int kind)
{
int i, n;
uint64 s;
@@ -1419,12 +1466,14 @@ aggregate(Parser *p, Lexer *lx, string name, int kind)
uint64 s;
Token tk;
/* TODO: think of a better soln */
- Field fs[1024], *f;
- Expr *cx[1024], *x;
+ static Field fs[1024];
+ Field *f;
+ static Expr *cx[1024];
+ Expr *x;
- for (n = 0; tk.kind != Arbrace && n < arrlen(fs); n++) {
+ for (n = 0, tk = peek(p, 0); tk.kind != Arbrace && n < arrlen(fs); n++) {
fs[n].type = basetype(p, lx, &s);
- fs[n].qual = (uint32)s;
+ fs[n].qual = (uint32)(s & ~(MaskTyp|MaskInt|MaskFlt));
Field:
fs[n].name = namedecl(p, lx, &fs[n].type, 0);
tk = peek(p, 0);
@@ -1458,7 +1507,7 @@ aggregate(Parser *p, Lexer *lx, string name, int kind)
}
copyarray(f, fs, n);
copyarray(x, cx, n);
- return structtype(n, f, x);
+ return (kind == Tstruct) ? structtype(n, f, x) : uniontype(n, f, x);
Bad:
errorat(tk.pos, "failed to parse aggregate declaration");
return 0;
@@ -1469,35 +1518,41 @@ error
spec(Parser *p, Lexer *lx, uint64 *spec)
{
Token t;
- int n;
+ int n, i;
Sym *typ;
string name;
uint32 tag;
uint64 s, sm;
+ static uint32 (*aggrfunc[2])(Parser *, Lexer *, string , int) = {aggregate, enumerate};
s = 0;
while (t = peek(p, 0), t.kind >= Aident) {
/* typename */
if (t.kind == Aident) {
typ = lookupobj(p, t.val.s);
- if (!typ || typ->kind != Stype) {
- errorat(t.pos, "invalid type name '%s' in specifier", t.val.s);
- goto Bad;
- }
+ if (!typ || (typ && typ->kind != Stype))
+ break;
+
sm = typ->type;
- s |= sm << 32;
+ s |= (sm << 32 | Tname);
+ advance(p, lx);
continue;
}
/* keyword */
switch (n = t.val.i) {
- case Kauto: case Kregister: case Kstatic: case Kextern: case Ktypedef:
+ case Kauto: case Kregister: case Kstatic: case Kextern: case Ktypedef: case Ktls:
if (s & MaskMem) {
errorat(lx->pos, "multiple storage class specifiers: second was %s", keywords[n]);
goto Bad;
}
break;
+ case Kinline: case Knoret:
+ if (s & Bit(n))
+ warnat(lx->pos, "duplicate %s function specifier", keywords[n]);
+ break;
+
case Kconst: case Kvolatile:
if (s & Bit(n))
warnat(lx->pos, "duplicate %s specifier found in declaration", keywords[n]);
@@ -1527,6 +1582,7 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
goto Bad;
}
s += Bit(n);
+ t = advance(p, lx);
continue;
case Kvoid: case Kchar: case Kint: case Kfloat: case Kdouble:
@@ -1534,46 +1590,18 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
errorat(lx->pos, "more than one base type specified");
goto Bad;
}
- s += Bit(n);
break;
case Kstruct: case Kunion:
- if (s & (Tstruct | Tunion)) {
- errorat(lx->pos, "more than one aggregate type specified");
- goto Bad;
- }
- s += Bit(n);
- t = advance(p, lx);
- if (t.kind != Aident && t.kind != Albrace) {
- errorat(t.pos, "aggregate specifier missing valid declaration");
- goto Bad;
- }
-
- name = nil;
- tag = 0;
- if (t.kind == Aident) {
- name = t.val.s;
- t = advance(p, lx);
- }
- if (t.kind == Albrace) {
- t = advance(p, lx);
- 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;
-
+ i = 0;
+ goto Aggr;
case Kenum:
- if (s & Tenum) {
- errorat(lx->pos, "more than one enum type specifier found");
+ i = 1;
+ Aggr:
+ if (s & (Tstruct | Tunion | Tenum)) {
+ errorat(lx->pos, "more than one aggregate/enum type specified");
goto Bad;
}
- s += Bit(n);
t = advance(p, lx);
if (t.kind != Aident && t.kind != Albrace) {
errorat(t.pos, "enum specifier missing valid declaration");
@@ -1588,10 +1616,11 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
}
if (t.kind == Albrace) {
t = advance(p, lx);
- tag = enumerate(p, lx, name);
+ /* NOTE: This depends on the enum order. KEEP IN SYNC */
+ tag = aggrfunc[i](p, lx, name, 1 << (n+1));
- if (nomatch(t, Arbrace)) {
- errorat(t.pos, "invalid token %s in enum declaration", tokens[t.kind]);
+ if (t = peek(p, 0), nomatch(t, Arbrace)) {
+ errorat(t.pos, "invalid token %s in aggregate/enum declaration", tokens[t.kind]);
goto Bad;
}
}
@@ -1599,10 +1628,6 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
declaretag(p, tag, name);
break;
-
- panicf("need to implement");
- break;
-
default:
errorat(t.pos, "invalid keyword '%s' found in declaration specifier", keywords[n]);
}
@@ -1614,15 +1639,17 @@ spec(Parser *p, Lexer *lx, uint64 *spec)
*spec = s;
return 0;
- /* TODO: serialize bitflags to string for nice error message */
- errorat(lx->pos, "invalid type specifier: ''");
Bad:
+ /* TODO: serialize bitflags to string for nice error message */
errorat(lx->pos, "ignoring specifier");
*spec = Sbad;
return 1;
}
-/* name declaration */
+/*
+ * name declaration
+ * see dtor for valid values of ab
+ */
static
error
name(Parser *p, Lexer *lx, Name **nmp, int ab)
@@ -1640,7 +1667,7 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
t = peek(p, 0);
switch (k = t.kind) {
case Aident:
- if (ab) {
+ if (ab == 1) {
errorat(t.pos, "identifier not allowed in abstract declarator");
goto Bad;
}
@@ -1649,17 +1676,19 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
break;
case Alparen:
+ advance(p, lx);
nm->kind = Nparen;
nm->paren = getdtor(p);
if (dtor(p, lx, nm->paren, ab)) {
- putdtor(p);
+ putdtor(p, nm->paren);
nm->paren = nil;
errorat(lx->pos, "invalid declarator in parenthesis");
goto Bad;
}
+
t = peek(p, 0);
- if (t.kind != Arparen) {
- putdtor(p);
+ if (nomatch(t, Arparen)) {
+ putdtor(p, nm->paren);
nm->paren = nil;
errorat(lx->pos, "missing closing paren in declarator");
goto Bad;
@@ -1668,15 +1697,18 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
case Albrakt:
if (ab)
- break;
-
+ goto Sfx;
errorat(lx->pos, "missing identifier in non-abstract declarator");
+ /* fallthrough */
default:
+ if (ab)
+ goto Sfx;
errorat(lx->pos, "invalid token '%s' in name declaration", tokens[k]);
goto Bad;
}
t = advance(p, lx);
+Sfx:
for (;;) {
switch (k = t.kind) {
case Albrakt:
@@ -1725,7 +1757,7 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
t = peek(p, 0);
if (nomatch(t, Arbrakt)) {
- errorat(lx->pos, "unterminated index expression");
+ errorat(t.pos, "unterminated index expression");
goto Bad;
}
@@ -1766,7 +1798,7 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
copyarray(nm->sfx.call.arg, args, nm->sfx.call.n);
break;
}
- goto Params;
+ goto ParamLoop;
case Akeywd:
if (t.val.i < Kconst || t.val.i > Kenum) {
@@ -1774,21 +1806,24 @@ name(Parser *p, Lexer *lx, Name **nmp, int ab)
goto Bad;
}
- Params:
- do {
- if (nm->sfx.call.n >= arrlen(args)-1)
- panicf("out of argument buffer");
+ ParamLoop:
+ if (nm->sfx.call.n >= arrlen(args)-1)
+ panicf("out of argument buffer");
- 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, 0);
+ 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;
+ }
- nm->sfx.call.n++;
- } while (t = peek(p, 0), t.kind == Acomma);
+ args[nm->sfx.call.n].qual = (uint32)s & ~(MaskTyp|MaskInt|MaskFlt);
+ args[nm->sfx.call.n].name = namedecl(p, lx, &args[nm->sfx.call.n].type, 2);
+
+ nm->sfx.call.n++;
+ if ((t = peek(p, 0)).kind == Acomma) {
+ advance(p, lx);
+ goto ParamLoop;
+ }
if (t.kind == Aellip) {
nm->sfx.call.dots = 1;
@@ -1822,7 +1857,13 @@ Bad:
return 1;
}
-/* pointer kind is partitioned into 8x6 regions */
+/* pointer kind is partitioned into 8x6 regions
+ * ab => abstract
+ * @ 0: must have identifier
+ * @ 1: must not have identifier
+ * @ 2: don't care
+ * else: undefined
+ */
static
error
dtor(Parser *p, Lexer *lx, Dtor *d, int ab)
@@ -1840,10 +1881,11 @@ dtor(Parser *p, Lexer *lx, Dtor *d, int ab)
ptr->link = nil;
t = peek(p, 0);
- if (t.kind != Astar)
- if (t.kind == Aident || t.kind == Arparen)
+ if (t.kind != Astar) {
+ if (ab || t.kind == Aident || t.kind == Arparen)
goto Name;
goto Bad;
+ }
Ptr:
ptr->kind |= Bit(n);
advance(p, lx);
@@ -1851,7 +1893,7 @@ Key:
t = peek(p, 0);
switch (k = t.kind) {
case Akeywd:
- if (Kconst <= k && k <= Katomic)
+ if (Kconst <= t.val.i && t.val.i <= Katomic)
ptr->kind |= Bit(6*n + (t.val.i - Kconst + 1));
else {
errorat(lx->pos, "invalid keyword '%s' modifies pointer", keywords[t.val.i]);
@@ -1876,6 +1918,8 @@ Key:
goto Name;
default:
+ if (ab)
+ goto Name;
errorat(lx->pos, "invalid token '%s' modifies pointer specification", tokens[t.kind]);
goto Bad;
}
@@ -1909,29 +1953,35 @@ decl(Parser *p, Lexer *lx)
}
x = nil;
- d->spec = (uint32)s;
+ d->spec = (uint32)s & ~(MaskInt|MaskFlt|MaskTyp);
d->type = base;
d->name = namedecl(p, lx, &d->type, 0);
+ /* TODO: think about functions (both decls and defs) */
+ d->kind = (s & Mtype) ? Dtype : Dvar;
switch (t = peek(p, 0), t.kind) {
case Aeq:
+ if (s & Mtype) {
+ errorat(d->pos.beg, "initialization of type not allowed");
+ goto Bad;
+ }
t = advance(p, lx);
x = initx(p, lx);
+ d->kind = Dvar;
if (t.kind != Acomma) {
- d->kind = Dobj;
d->init = x;
- break;
+ goto Semi;
}
/* fallthrough */
case Acomma:
- d->kind = Dobjs;
- d->objs.init = x;
+ d->kind |= Dlist;
+ d->list.init = x;
/* move singleton data over */
name = d->name;
type = d->type;
- d->objs.name = name;
- d->objs.type = type;
- ds = &d->objs;
+ d->list.name = name;
+ d->list.type = type;
+ ds = &d->list;
/* iterate until we hit end of list */
while (t.kind == Acomma) {
t = advance(p, lx);
@@ -1948,7 +1998,7 @@ decl(Parser *p, Lexer *lx)
} else
ds->init = nil;
}
- break;
+ goto Semi;
case Albrace:
d->kind = Dfunc;
@@ -1969,9 +2019,15 @@ decl(Parser *p, Lexer *lx)
goto Bad;
}
closescope(p);
+ break;
default:
- ;
+ Semi:
+ if (nomatch(t, Asemi)) {
+ errorat(t.pos, "no semicolon after declaration");
+ goto Bad;
+ }
+ t = advance(p, lx);
}
d->pos.end = lx->pos;
@@ -1985,10 +2041,22 @@ Bad:
// -----------------------------------------------------------------------
// top level api
+void
+setup(Parser *p, Lexer *lx)
+{
+ advance(p,lx);
+ advance(p,lx);
+
+ /* define all builtin typedefs */
+ declareobj(p, &C.builtin.vargs);
+}
+
error
parse(Parser *p, Lexer *lx)
{
Token tok;
+
+ setup(p, lx);
while ((tok = peek(p, 0)), tok.kind > Aeof) {
if (p->ast.len >= p->ast.cap) {
p->ast.cap += 20;
diff --git a/sys/cmd/cc/bits.c b/sys/cmd/cc/bits.c
index 2fe7295..479ddbb 100644
--- a/sys/cmd/cc/bits.c
+++ b/sys/cmd/cc/bits.c
@@ -16,34 +16,34 @@ enum
* enumerated type specifers
* see https://en.wikipedia.org/wiki/C_data_types
*/
-#define VOID X(Tvoid, 1)
+#define VOID X(Tvoid, 2)
-#define BOOL X(Tbool, 2)
-#define CHAR X(Tchar, 3)
-#define SCHAR X(Tsign|Tchar, 4)
-#define UCHAR X(Tunsign|Tchar, 5)
+#define BOOL X(Tbool, 3)
+#define CHAR X(Tchar, 4)
+#define SCHAR X(Tsign|Tchar, 5)
+#define UCHAR X(Tunsign|Tchar, 6)
-#define SHORT X(Tshort, 6), X(Tshort|Tint, 6)
-#define SSHORT X(Tsign|Tshort, 7), X(Tsign|Tshort|Tint, 7)
-#define USHORT X(Tunsign|Tshort, 8), X(Tunsign|Tshort|Tint, 8)
+#define SHORT X(Tshort, 7), X(Tshort|Tint, 7)
+#define SSHORT X(Tsign|Tshort, 8), X(Tsign|Tshort|Tint, 8)
+#define USHORT X(Tunsign|Tshort, 9), X(Tunsign|Tshort|Tint, 9)
-#define INT X(0, 9), X(Tint, 9)
-#define SINT X(Tsign, 10), X(Tsign|Tint, 10)
-#define UINT X(Tunsign, 11), X(Tunsign|Tint, 11)
+#define INT X(0, 10), X(Tint, 10)
+#define SINT X(Tsign, 11), X(Tsign|Tint, 11)
+#define UINT X(Tunsign, 12), X(Tunsign|Tint, 12)
-#define LONG X(Tlong, 12), X(Tlong|Tint, 12)
-#define SLONG X(Tsign|Tlong, 13), X(Tsign|Tlong|Tint, 13)
-#define ULONG X(Tunsign|Tlong, 14), X(Tunsign|Tlong|Tint, 14)
+#define LONG X(Tlong, 13), X(Tlong|Tint, 13)
+#define SLONG X(Tsign|Tlong, 14), X(Tsign|Tlong|Tint, 14)
+#define ULONG X(Tunsign|Tlong, 15), X(Tunsign|Tlong|Tint, 15)
-#define VLONG X(Tvlong, 15), X(Tvlong|Tint, 15)
-#define SVLONG X(Tsign|Tvlong, 16), X(Tsign|Tvlong|Tint, 16)
-#define UVLONG X(Tunsign|Tvlong, 16), X(Tunsign|Tvlong|Tint, 17)
+#define VLONG X(Tvlong, 16), X(Tvlong|Tint, 16)
+#define SVLONG X(Tsign|Tvlong, 17), X(Tsign|Tvlong|Tint, 17)
+#define UVLONG X(Tunsign|Tvlong, 18), X(Tunsign|Tvlong|Tint, 18)
-#define FLOAT X(Tfloat, 18)
-#define DOUBLE X(Tdouble, 19)
-#define LONGDB X(Tlong|Tdouble, 20)
-#define COMPLEX X(Tcmplx, 21)
-#define IMAGINARY X(Timag, 22)
+#define FLOAT X(Tfloat, 19)
+#define DOUBLE X(Tdouble, 20)
+#define LONGDB X(Tlong|Tdouble, 21)
+#define COMPLEX X(Tcmplx, 22)
+#define IMAGINARY X(Timag, 23)
/* fixed width definitions */
#define DEF(sz, aln, mx, sgn) {.size=sz, .align=aln, .max=mx, .sign=sgn }
@@ -92,6 +92,7 @@ Type pointer = {.size=8, .align=8, .max=0xffffffffffffffff, .sign=0};
#define TYPE(a, ...) a,
Type basetypes[] = {
{ 0 }, /* sentinel value for bad types */
+ { 0 }, /* sentinel value for variadic args */
TYPES
};
#undef TYPE
diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c
index 796d3a8..24bc9e0 100644
--- a/sys/cmd/cc/cc.c
+++ b/sys/cmd/cc/cc.c
@@ -215,6 +215,28 @@ init(void)
C.type.info = calloc(C.type.cap, sizeof(*C.type.info));
memcpy(C.type.info, basetypes, C.type.len * sizeof(*C.type.info));
+
+ /* builtins */
+ C.builtin.vargs = (Decl) {
+ .pos = (Range) {
+ .beg = {
+ .col = 0,
+ .line = 0,
+ .path = "<builtin>",
+ },
+ .end = {
+ .col = 0,
+ .line = 0,
+ .path = "<builtin>",
+ },
+ },
+ .kind = Dtype,
+ .spec = Mtype,
+ .type = 1,
+ .name = "__builtin_va_list",
+ };
+
+ intern(&C.builtin.vargs.name);
}
void
@@ -287,8 +309,8 @@ compile(byte *path)
}
}
- initp(&p);
initlx(&lx);
+ initp(&p);
lx.io = openio(&lx, path);
lx.pos = (Pos){
diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h
index cf97233..da45b18 100644
--- a/sys/cmd/cc/cc.h
+++ b/sys/cmd/cc/cc.h
@@ -371,11 +371,15 @@ enum
Xcomma,
+ Dvar,
Dfunc,
- Dobj,
- Dobjs,
+ Dtype,
+ Dlist = iota(20),
+ Dvars = Dvar | Dlist,
+ Dtypes = Dtype | Dlist,
- /* names */
+ /* names (don't interact w/ final AST) */
+ Nnil = 0,
Nident,
Nparen,
Nindex,
@@ -639,7 +643,7 @@ struct Decl
Expr *init;
};
};
- struct Decls objs;
+ struct Decls list;
};
};
@@ -693,7 +697,7 @@ struct Type
/* platform specific */
extern Type pointer;
-extern Type basetypes[23];
+extern Type basetypes[24];
/* mandated by C standard */
extern uint64 validtypespec[40];
extern int indextypespec[40];
@@ -713,9 +717,9 @@ struct Parser
Decl **decls;
} ast;
- /* static buffers */
+ /* static buffers/stacks */
Scope *sp;
- Scope spstk[20];
+ Scope spstk[40];
Name *nm;
Name nmstk[40];
@@ -777,6 +781,11 @@ struct Compiler
int len;
Type *info;
} type;
+
+ /* TODO: make array */
+ struct {
+ Decl vargs;
+ } builtin;
};
extern Compiler C;
diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c
index e05958d..494f293 100644
--- a/sys/cmd/cc/pp.c
+++ b/sys/cmd/cc/pp.c
@@ -175,7 +175,9 @@ opand(Lexer *lx)
}
}
*s = '\0';
- return lookup(&lx->sym, lx->buf) != nil;
+ s = lx->buf;
+ intern(&s);
+ return lookup(&lx->sym, s) != nil;
}
return 0;
}
@@ -465,6 +467,7 @@ ppdef(Lexer *lx)
goto Bad;
}
intern(&s);
+ printf("DEFINING %s\n", s);
lx->b = lx->buf;
sym = lookup(&lx->sym, s);