From 7ea7654db6e827038e38c3589c8d5b314db3fcb2 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Mon, 18 May 2020 20:28:51 -0700 Subject: fix: line accounting is less buggy --- sys/cmd/cc/cc.c | 55 +++++++++++++++++++++++++++++--------------- sys/cmd/cc/cc.h | 18 +++++++++++---- sys/cmd/cc/lex.c | 70 +++++++++++++++++++++++++++++++++++++------------------- sys/cmd/cc/pp.c | 33 ++++++++++++++++---------- 4 files changed, 118 insertions(+), 58 deletions(-) (limited to 'sys/cmd/cc') diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c index 6bc363c..87d9a35 100644 --- a/sys/cmd/cc/cc.c +++ b/sys/cmd/cc/cc.c @@ -99,30 +99,28 @@ END: Io* openio(byte *path) { - Io *it; + 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.iostk; it != C.io; ++it) { - if ((uintptr)it->path == (uintptr)path) { - if (it->kind & IOonce) { - return nil; - } - return it; - } + for (it = C.omit.path, end = it + C.omit.len; it < end; ++it) { + if ((uintptr)(*it) == (uintptr)(path)) + return nil; } + printf("OPENING PATH %s\n", path); 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) { + 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->buf, asrdr(io·read), C.io->f); @@ -151,21 +149,28 @@ makeio() } #undef asrdr -// TODO: Think about if this is always at the _end_ of the stack. -// Right now we don't have access to it. void freeio(Io *io) { - if (io->kind & ~IOmac) { - free(io->b); - } else { + if (io->kind & IOfile) { io·close(io->f); } + io->kind = 0; io->link = nil; io->path = nil; io->store = (Pos){ 0 }; } +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 @@ -234,8 +239,13 @@ init(void) C.inc.dir = calloc(C.inc.cap, sizeof(*C.inc.dir)); C.inc.dir[C.inc.len++] = "."; - C.outfile = nil; - C.io = C.iostk; + 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 }; @@ -248,7 +258,9 @@ compile(byte *path) Token tok; byte *p, out[400]; + intern(&path); strcpy(out, path); + p = utf8·findrrune(out, '/'); if (p) *p++ = '\0'; @@ -268,7 +280,12 @@ compile(byte *path) } } - C.lxr.io = openio(path); + C.lxr.io = openio(path); + C.lxr.pos = (Pos){ + .path = path, + .line = 1, + .col = 1, + }; while (tok = lex(&C.lxr), tok.kind > Aeof) { puttok(tok); } diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h index 84f173f..0e525be 100644 --- a/sys/cmd/cc/cc.h +++ b/sys/cmd/cc/cc.h @@ -235,8 +235,9 @@ struct SymTab Sym **vals; }; -Sym *lookup(SymTab *tab, string ident); Sym *define(SymTab *tab, string ident, int kind); +Sym *lookup(SymTab *tab, string ident); +error forget(SymTab *tab, string ident); struct Lexer { @@ -363,8 +364,8 @@ struct Decl enum { IOnil = iota(0), - IOonce = iota(1), - IOmac = iota(2), + IOfile = iota(1), + IObuff = iota(2), }; struct Io @@ -381,6 +382,7 @@ struct Io struct Io *link; }; +/* cc.c io functions */ Io* openio(byte *path); Io* makeio(); void freeio(Io *io); @@ -396,6 +398,7 @@ struct StrTab int32 *vals; }; +/* cc.c string functions */ int32 intern(byte **str); string internview(byte* beg, byte *end); @@ -413,6 +416,11 @@ struct Compiler Io *io; Io iostk[100]; + struct { + int cap; + int len; + string *path; + } omit; string outfile; @@ -420,6 +428,8 @@ struct Compiler }; extern Compiler C; -void init(); +/* 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 90f282a..20c6f9c 100644 --- a/sys/cmd/cc/lex.c +++ b/sys/cmd/cc/lex.c @@ -39,10 +39,8 @@ getnsbyte(Lexer *lx) for (;;) { if (b >= RuneSelf || !isspace(b)) return b; - if (b == '\n') { - lx->pos.line++; + if (b == '\n') return b; - } b = getbyte(lx); } return b; @@ -257,9 +255,12 @@ Dispatch: goto TNum; switch (b) { - case ' ': case '\n': case '\r': case '\t': case '\v': case '\f': + case '\n': + lx->pos.line++; + case ' ': case '\r': case '\t': case '\v': case '\f': while (b = getbyte(lx), isspace(b)) - if (b == '\n') lx->pos.line++; + if (b == '\n') + lx->pos.line++; goto Dispatch; case '\'': @@ -363,7 +364,6 @@ Dispatch: else if (b == '/') { while (b != EOF && b != '\n') b = getbyte(lx); - lx->pos.line++; goto Dispatch; } else if (b == '*') { int level = 1; @@ -378,7 +378,8 @@ Dispatch: if (b == '/') level--; } - if (b == '\n') lx->pos.line++; + if (b == '\n') + lx->pos.line++; b = getbyte(lx); } goto Dispatch; @@ -396,7 +397,11 @@ Dispatch: break; case EOF: - panicf("need to implement popio"); + popio(lx); + if (lx->io) + goto GetByte; + tok.kind = Aeof; + return tok; CASE1('(', Alparen) CASE1(')', Arparen) @@ -593,8 +598,8 @@ pushio(Lexer *lx, Io *new) lx->io = new; lx->pos = (Pos){ - .line = 0, - .col = 0, + .line = 1, + .col = 1, .path = new->path, }; } @@ -608,6 +613,11 @@ popio(Lexer *lx) if (!prev) { panicf("no buffer left"); } + /* + * NOTE: should we copy over unget bytes here? + * would modify the buffer... + */ + freeio(lx->io); lx->pos = prev->store; lx->io = prev; @@ -619,18 +629,6 @@ popio(Lexer *lx) #define PTR_HASH(p) (uintptr)(p) #define PTR_EQUAL(p1, p2) ((uintptr)(p1) == (uintptr)(p2)) -Sym* -lookup(SymTab *tab, string ident) -{ - int idx; - MAP_GET(idx, tab, ident, PTR_HASH, PTR_EQUAL); - - if (idx < tab->n_buckets) - return tab->vals[idx]; - - return nil; -} - static int moresymtab(SymTab *tab, int n) @@ -662,6 +660,32 @@ define(SymTab *tab, string name, int kind) return sym; } +Sym* +lookup(SymTab *tab, string ident) +{ + int idx; + MAP_GET(idx, tab, ident, PTR_HASH, PTR_EQUAL); + + if (idx < tab->n_buckets) + return tab->vals[idx]; + + return nil; +} + + +error +forget(SymTab *tab, string ident) +{ + int idx; + MAP_GET(idx, tab, ident, PTR_HASH, PTR_EQUAL); + + if (idx < tab->n_buckets) { + MAP_DEL(tab, idx); + return 0; + } + return 1; +} + // ----------------------------------------------------------------------- // error reporting @@ -671,7 +695,7 @@ errorat(Pos x, byte *fmt, ...) va_list args; va_start(args, fmt); - printf("error %d: ", x.line); + printf("error:%s:%d:%d: ", os·basename(x.path), x.line, x.col); vprintf(fmt, args); printf("\n"); diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c index ceb9d66..30bb3d4 100644 --- a/sys/cmd/cc/pp.c +++ b/sys/cmd/cc/pp.c @@ -62,7 +62,7 @@ defmacro(Lexer *lx, string name, string macro) { Sym *mac; - printf("DEFINING MACRO %s\n", name); + printf("DEFINING MACRO %s, ON LINE %d\n", name, lx->pos.line); mac = define(&lx->sym, name, Smacro); mac->macro = macro; @@ -400,6 +400,9 @@ ppend(Lexer *lx) b = getnsbyte(lx); } while (b > 0 && b != '\n'); + if (b == '\n') + lx->pos.line++; + return 0; } @@ -409,15 +412,17 @@ static error ppund(Lexer *lx) { - Sym *sym; string s; + error err; s = ident(lx); intern(&s); - sym = lookup(&lx->sym, s); - if (!sym) { + printf("FORGETTING %s\n", s); + err = forget(&lx->sym, s); + if (err) { errorat(lx->pos, "attempting to undefine unrecognized symbol '%s'", s); + return err; } ppend(lx); return 0; @@ -443,7 +448,7 @@ ppdef(Lexer *lx) sym = lookup(&lx->sym, s); if (sym) { errorat(lx->pos, "macro redefined: '%s'", sym->name); - goto Bad; + // goto Bad; } n = 0; @@ -537,6 +542,7 @@ ppdef(Lexer *lx) b = getbyte(lx); /* unix */ if (b == '\n') { + lx->pos.line++; b = getbyte(lx); continue; } @@ -544,23 +550,24 @@ ppdef(Lexer *lx) if (b == '\r') { b = getbyte(lx); if (b == '\n') { + lx->pos.line++; b = getbyte(lx); continue; } } str·appendbyte(&buf, '\\'); } - if (b == '\n') + if (b == '\n') { + lx->pos.line++; break; + } if (b == '#' && n > 0) { - panicf("needs implementation"); + panicf("tokenizer needs implementation"); } str·appendbyte(&buf, b); b = getbyte(lx); - if (b == '\n') - lx->pos.line++; if (b == EOF) { errorat(lx->pos, "eof found in macro '%s'", s); goto Bad; @@ -797,7 +804,7 @@ ppinc(Lexer *lx) lx->buf[0] = '\0'; strcat(lx->buf, s); - if (io·exists(lx->buf, ReadOK)) { + if (os·exists(lx->buf, ReadOK)) { break; } } @@ -833,7 +840,7 @@ ppprag(Lexer *lx) goto Bad; } if (strcmp(s, "once") == 0) { - lx->io->kind |= IOonce; + pushomit(lx->io->path); return 0; } Bad: @@ -882,8 +889,10 @@ Skip: if (c != '#') { if (!isspace(c)) b = 0; - if (c == '\n') + if (c == '\n') { + lx->pos.line++; b = 1; + } continue; } if (!b) -- cgit v1.2.1