aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/cc/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/cc/lex.c')
-rw-r--r--sys/cmd/cc/lex.c147
1 files changed, 110 insertions, 37 deletions
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
@@ -23,6 +23,115 @@ puttok(Token tok)
}
// -----------------------------------------------------------------------
+// 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 = "<empty>";
+}
+
+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
int
@@ -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);
@@ -676,42 +785,6 @@ Nospace:
#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
#define PTR_HASH(p) (uintptr)(p)