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/lex.c | 147 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 110 insertions(+), 37 deletions(-) (limited to 'sys/cmd/cc/lex.c') 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 -- cgit v1.2.1