From cf65141f154651115028d6456a1d7582d30b2083 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 30 May 2020 15:09:33 -0700 Subject: many bug fixes --- sys/cmd/cc/ast.c | 320 +++++++++++++++++++++++++++++++++--------------------- sys/cmd/cc/bits.c | 45 ++++---- sys/cmd/cc/cc.c | 24 +++- sys/cmd/cc/cc.h | 23 ++-- sys/cmd/cc/pp.c | 5 +- 5 files changed, 260 insertions(+), 157 deletions(-) (limited to 'sys/cmd/cc') 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 = "", + }, + .end = { + .col = 0, + .line = 0, + .path = "", + }, + }, + .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); -- cgit v1.2.1