From 69487ed29aed49ca0e3481e9783e02e9156258b2 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Fri, 22 May 2020 17:14:48 -0700 Subject: fix: encapsulated the IO stack into the lexer --- sys/cmd/cc/ast.c | 6 +- sys/cmd/cc/cc.c | 182 +++++++++++++++++++------------------------------------ sys/cmd/cc/cc.h | 123 +++++++++++++++++++------------------ sys/cmd/cc/lex.c | 147 +++++++++++++++++++++++++++++++++----------- sys/cmd/cc/pp.c | 13 +++- 5 files changed, 249 insertions(+), 222 deletions(-) (limited to 'sys/cmd') diff --git a/sys/cmd/cc/ast.c b/sys/cmd/cc/ast.c index 4553b96..184ddaf 100644 --- a/sys/cmd/cc/ast.c +++ b/sys/cmd/cc/ast.c @@ -1275,12 +1275,10 @@ Bad: // ----------------------------------------------------------------------- // top level api -void +error parse(Parser *p, Lexer *lx) { Token tok; - p->sp = p->spstk; - while ((tok = peek(p, 0)), tok.kind > Aeof) { if (p->ast.len >= p->ast.cap) { p->ast.cap += 20; @@ -1288,4 +1286,6 @@ parse(Parser *p, Lexer *lx) } p->ast.decls[p->ast.len++] = decl(p, lx); } + + return 0; } diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c index cf479f8..c06d1c3 100644 --- a/sys/cmd/cc/cc.c +++ b/sys/cmd/cc/cc.c @@ -91,89 +91,6 @@ END: return C.strs.vals[i]; } -// ----------------------------------------------------------------------- -// io buffer management - -#define asrdr(x) (io·Reader){(int (*)(void *, int, int, void *))x} -// path should be absolute -Io* -openio(byte *path) -{ - string *it, *end; - Stream *f; - - intern(&path); - - // See if we have already opened file; - // If so, and it hasn't been flagged return it - for (it = C.omit.path, end = it + C.omit.len; it < end; ++it) { - if ((uintptr)(*it) == (uintptr)(path)) - return nil; - } - - // TODO: See if we have already loaded the file - // - if ((C.io - C.iostk) >= arrlen(C.iostk)-1) - panicf("out of I/O space!"); - - C.io->f = io·open(path, "r"); - if (!C.io->f) - panicf("file %s not found", path); - - C.io->kind = IOfile; - C.io->path = path; - bufio·initreader(&C.io->rdr, asrdr(io·read), C.io->f); - - return C.io++; -} - -Io* -makeio(byte *name) -{ - if ((C.io - C.iostk) >= arrlen(C.iostk)-1) - panicf("out of I/O space!"); - - C.io->path = name; - C.io->rdr = (io·Buffer) { - .state = bufio·rdr | bufio·end, - .runesize = 0, - .h = nil, - .size = bufio·size, - .beg = C.io->rdr.buf + bufio·ungets, - .pos = C.io->rdr.buf + bufio·ungets, - .end = C.io->rdr.buf + bufio·ungets, - }; - C.io->b = C.io->rdr.beg; - - return C.io++; -} -#undef asrdr - -void -freeio(Io *io) -{ - if (io->kind & IOfile) { - io·close(io->f); - } - - io->rdr.state = 0; - io->kind = 0; - io->link = nil; - io->path = nil; - io->store = (Pos){ 0 }; - io->path = ""; -} - -void -pushomit(string omit) -{ - if (C.omit.len == C.omit.cap) { - C.omit.cap += 20; - C.omit.path = realloc(C.omit.path, C.omit.cap*sizeof(*C.omit.path)); - } - C.omit.path[C.omit.len++] = omit; -} - // ----------------------------------------------------------------------- // universal compiler builtins @@ -227,79 +144,102 @@ init(void) { int i; - for (i = 0; i < arrlen(keywords); i++) { + for (i = 0; i < arrlen(keywords); i++) intern(&keywords[i]); - } - for (i = 0; i < arrlen(directives); i++) { + for (i = 0; i < arrlen(directives); i++) intern(&directives[i]); - } - C.heap = mem·makearena(mem·sys, nil); + C.heap = mem·makearena(mem·sys, nil); + /* compiler definitions */ + C.def.len = 0; + C.def.cap = 100; + C.def.val = calloc(C.def.cap, sizeof(*C.def.val)); + + /* compiler include paths */ C.inc.len = 0; C.inc.cap = 100; C.inc.dir = calloc(C.inc.cap, sizeof(*C.inc.dir)); C.inc.dir[C.inc.len++] = "."; - C.omit.len = 0; - C.omit.cap = 100; - C.omit.path = calloc(C.omit.cap, sizeof(*C.inc.dir)); - C.outfile = nil; - C.io = C.iostk; - C.io->link = nil; - memset(C.iostk, 0, sizeof(C.iostk)); +} - C.lxr = (Lexer){ 0 }; - C.lxr.b = C.lxr.buf; +void +initl(Lexer *lx) +{ + int i; + + *lx = (Lexer){ 0 }; + lx->b = lx->buf; /* predefine macros */ - dodefine(&C.lxr, "__LINE__"); - dodefine(&C.lxr, "__FILE__"); - C.lxr.macline = (uintptr)lookup(&C.lxr.sym, "__LINE__"); - C.lxr.macfile = (uintptr)lookup(&C.lxr.sym, "__FILE__"); + dodefine(lx, "__LINE__"); + dodefine(lx, "__FILE__"); + lx->macline = (uintptr)lookup(&lx->sym, "__LINE__"); + lx->macfile = (uintptr)lookup(&lx->sym, "__FILE__"); + + for (i = 0; i < C.def.len; i++) + dodefine(lx, C.def.val[i]); + + lx->omit.len = 0; + lx->omit.cap = 100; + lx->omit.path = calloc(lx->omit.cap, sizeof(*C.inc.dir)); + + lx->io = lx->iostk; + lx->io->link = nil; + memset(lx->iostk, 0, sizeof(lx->iostk)); +} + +void +initp(Parser *p) +{ + p->sp = p->spstk; + p->nm = p->nmstk; + p->dt = p->dtstk; } error compile(byte *path) { - Io *io; - Token tok; - byte *p, out[400]; + Lexer lx; + Parser p; + byte *sep, out[400]; intern(&path); strcpy(out, path); - p = utf8·findrrune(out, '/'); - if (p) - *p++ = '\0'; + sep = utf8·findrrune(out, '/'); + if (sep) + *sep++ = '\0'; else - p = out; + sep = out; if (!C.outfile) { - C.outfile = p; + C.outfile = sep; if (C.outfile) { - if ((p = utf8·findrrune(C.outfile, '.'))) { - p[0] = '.'; - p[1] = 'o'; - p[2] = '\0'; + if ((sep = utf8·findrrune(C.outfile, '.'))) { + sep[0] = '.'; + sep[1] = 'o'; + sep[2] = '\0'; } } else { C.outfile = "/dev/null"; } } - C.lxr.io = openio(path); - C.lxr.pos = (Pos){ + initl(&lx); + initp(&p); + + lx.io = openio(path); + lx.pos = (Pos){ .path = path, .line = 1, .col = 1, }; - parse(&C.psr, &C.lxr); - - return tok.kind != Anil; + return parse(&p, &lx); } error @@ -319,7 +259,11 @@ main(int argc, byte *argv[]) a = ARGF(); if (a) { intern(&a); - dodefine(&C.lxr, a); + if (C.def.len >= C.def.cap) { + C.def.cap += 20; + C.def.val = realloc(C.def.val, C.def.cap * sizeof(*C.def.val)); + } + C.def.val[C.def.len++] = a; } break; diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h index 0d4c876..62837c4 100644 --- a/sys/cmd/cc/cc.h +++ b/sys/cmd/cc/cc.h @@ -263,17 +263,46 @@ Sym *lookup(SymTab *tab, string ident); error forget(SymTab *tab, string ident); void forgetall(SymTab *tab); +enum +{ + IOnil = iota(0), + IOfile = iota(1), + IObuff = iota(2), +}; + +struct Io +{ + io·Buffer rdr; + string path; + uint32 kind; + union { + Stream *f; + byte *b; + }; + + Pos store; + struct Io *link; +}; + struct Lexer { Pos pos; - Io *io; - SymTab sym; + SymTab sym; byte *b; byte buf[2*1024]; /* predefined dynamic macros */ uintptr macfile; uintptr macline; + + /* i/o data */ + Io *io, *new; + Io iostk[100]; + struct { + int cap; + int len; + string *path; + } omit; }; /* lex.c functions */ @@ -285,8 +314,11 @@ rune getrune(Lexer *); byte ungetbyte(Lexer *); rune ungetrune(Lexer *, rune r); -void pushio(Lexer *lx, Io *new); -void popio(Lexer *lx); +Io* openio(Lexer *lx, byte *path); +Io* makeio(Lexer *lx, byte *name); +void freeio(Lexer *lx, Io *io); +void pushio(Lexer *lx, Io *new); +void popio(Lexer *lx); void puttok(Token); @@ -524,6 +556,7 @@ enum Sbad = -1, }; +/* intermediate nodes */ struct Ptr { uint64 kind; @@ -551,29 +584,22 @@ struct Dtor struct Decls { - union { - struct Dtor; - Dtor dtor; - }; + Type *type; Expr *init; struct Decls *link; }; +/* final ast node */ struct Decl { struct Node; - uint64 spec; + uint32 spec; + string name; + Type *type; union { - struct { - struct Dtor; - Stmt *body; - } func; - struct { - struct Dtor; - Expr *init; - struct Decls *link; - } var; - struct Dtor type; + Stmt *func; + Expr *init; + struct Decls *link; }; }; @@ -627,42 +653,23 @@ struct Parser Decl **decls; } ast; + /* static buffers */ Scope *sp; Scope spstk[20]; + + Name *nm; + Name nmstk[40]; + + Dtor *dt; + Dtor dtstk[40]; }; /* ast.c functions */ -void parse(Parser *, Lexer *); +error parse(Parser *, Lexer *); // ----------------------------------------------------------------------- // global compiler -enum -{ - IOnil = iota(0), - IOfile = iota(1), - IObuff = iota(2), -}; - -struct Io -{ - io·Buffer rdr; - string path; - uint32 kind; - union { - Stream *f; - byte *b; - }; - - Pos store; - struct Io *link; -}; - -/* cc.c io functions */ -Io* openio(byte *path); -Io* makeio(byte *name); -void freeio(Io *io); - struct StrTab { int32 n_buckets; @@ -687,35 +694,27 @@ struct Compiler string outfile; struct { - int cap; - int len; - Type *info; - } type; + int cap; + int len; + string *val; + } def; - /* i/o data */ struct { int cap; int len; string *dir; } inc; - Io *io; - Io iostk[100]; struct { - int cap; - int len; - string *path; - } omit; - - /* partitioned data for stages */ - Lexer lxr; - Parser psr; + int cap; + int len; + Type *info; + } type; }; extern Compiler C; /* cc.c compiler functions */ -void pushomit(string omit); void init(); #undef iota diff --git a/sys/cmd/cc/lex.c b/sys/cmd/cc/lex.c index a8dabec..1eb269c 100644 --- a/sys/cmd/cc/lex.c +++ b/sys/cmd/cc/lex.c @@ -22,6 +22,115 @@ puttok(Token tok) printf("ident <%s>", tok.val.s); } +// ----------------------------------------------------------------------- +// io buffer management + +#define asrdr(x) (io·Reader){(int (*)(void *, int, int, void *))x} + +// path should be absolute +Io* +openio(Lexer *lx, byte *path) +{ + string *it, *end; + Stream *f; + + intern(&path); + + // See if we have already opened file; + // If so, and it hasn't been flagged return it + for (it = lx->omit.path, end = it + lx->omit.len; it < end; ++it) { + if ((uintptr)(*it) == (uintptr)(path)) + return nil; + } + + // TODO: See if we have already loaded the file + + if ((lx->new - lx->iostk) >= arrlen(lx->iostk)-1) + panicf("out of I/O space!"); + + lx->new->f = io·open(path, "r"); + if (!lx->new->f) + panicf("file %s not found", path); + + lx->new->kind = IOfile; + lx->new->path = path; + bufio·initreader(&lx->new->rdr, asrdr(io·read), lx->new->f); + + return lx->new++; +} + +static +Io* +makeio(Lexer *lx, byte *name) +{ + if ((lx->new - lx->iostk) >= arrlen(lx->iostk)-1) + panicf("out of I/O space!"); + + lx->new->path = name; + lx->new->rdr = (io·Buffer) { + .state = bufio·rdr | bufio·end, + .runesize = 0, + .h = nil, + .size = bufio·size, + .beg = lx->new->rdr.buf + bufio·ungets, + .pos = lx->new->rdr.buf + bufio·ungets, + .end = lx->new->rdr.buf + bufio·ungets, + }; + lx->new->b = lx->new->rdr.beg; + + return lx->new++; +} +#undef asrdr + +static +void +freeio(Lexer *lx, Io *io) +{ + if (io->kind & IOfile) { + io·close(io->f); + } + + io->rdr.state = 0; + io->kind = 0; + io->link = nil; + io->path = nil; + io->store = (Pos){ 0 }; + io->path = ""; +} + +void +pushio(Lexer *lx, Io *new) +{ + new->link = lx->io; + lx->io->store = lx->pos; + lx->io = new; + + lx->pos = (Pos){ + .line = 1, + .col = 1, + .path = new->path, + }; +} + +void +popio(Lexer *lx) +{ + Io *prev; + + assert(lx->io == lx->new-1); + --lx->new; + + prev = lx->io->link; + freeio(lx, lx->io); + + lx->io = prev; + if (!prev) { + return; + } + + lx->pos = prev->store; +} + // ----------------------------------------------------------------------- // simple wrappers @@ -648,7 +757,7 @@ Dispatch: tok.val.s = lx->pos.path; goto Return; } - io = makeio(sym->name); + io = makeio(lx, sym->name); io->rdr.end += expandmacro(lx, sym, io->b); *io->rdr.end++ = EOF; pushio(lx, io); @@ -675,42 +784,6 @@ Nospace: #undef CASE2 #undef CASE1 -// ----------------------------------------------------------------------- -// push/pop io objects - -void -pushio(Lexer *lx, Io *new) -{ - new->link = lx->io; - lx->io->store = lx->pos; - lx->io = new; - - lx->pos = (Pos){ - .line = 1, - .col = 1, - .path = new->path, - }; -} - -void -popio(Lexer *lx) -{ - Io *prev; - - assert(lx->io == C.io-1); - --C.io; - - prev = lx->io->link; - freeio(lx->io); - - lx->io = prev; - if (!prev) { - return; - } - - lx->pos = prev->store; -} - // ----------------------------------------------------------------------- // symbol tables diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c index 30a162b..5eed4b2 100644 --- a/sys/cmd/cc/pp.c +++ b/sys/cmd/cc/pp.c @@ -3,6 +3,17 @@ // ----------------------------------------------------------------------- // helper functions +static +void +pushomit(Lexer *lx, string omit) +{ + if (lx->omit.len == lx->omit.cap) { + lx->omit.cap += 20; + lx->omit.path = realloc(lx->omit.path, lx->omit.cap*sizeof(*lx->omit.path)); + } + lx->omit.path[lx->omit.len++] = omit; +} + // NOTE: The iterator of lexer lx->b IS NOT reset. // Its the caller's responsibility. static @@ -910,7 +921,7 @@ ppprag(Lexer *lx) } lx->b = lx->buf; if (strcmp(s, "once") == 0) { - pushomit(lx->io->path); + pushomit(lx, lx->io->path); return 0; } Bad: -- cgit v1.2.1