aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-05-18 20:28:51 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-05-18 20:28:51 -0700
commit7ea7654db6e827038e38c3589c8d5b314db3fcb2 (patch)
treeb9b28558b6aee70c57bd2ff14ea10896c4840b29 /sys/cmd
parent73c04db73163d1d2719bb97a6b8c133065df75c3 (diff)
fix: line accounting is less buggy
Diffstat (limited to 'sys/cmd')
-rw-r--r--sys/cmd/cc/cc.c55
-rw-r--r--sys/cmd/cc/cc.h18
-rw-r--r--sys/cmd/cc/lex.c70
-rw-r--r--sys/cmd/cc/pp.c33
4 files changed, 118 insertions, 58 deletions
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)