From 480611c452e8b4dc18654545e2de4d6dde2d7b4d Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 19 May 2020 22:04:05 -0700 Subject: fix: macro expansion works! also fixed issue with iopop --- sys/cmd/cc/cc.c | 10 +++++--- sys/cmd/cc/lex.c | 4 +++ sys/cmd/cc/pp.c | 77 +++++++++----------------------------------------------- 3 files changed, 22 insertions(+), 69 deletions(-) (limited to 'sys') diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c index d7bb12c..2a61e89 100644 --- a/sys/cmd/cc/cc.c +++ b/sys/cmd/cc/cc.c @@ -155,10 +155,12 @@ freeio(Io *io) if (io->kind & IOfile) { io·close(io->f); } - io->kind = 0; - io->link = nil; - io->path = nil; - io->store = (Pos){ 0 }; + + io->buf.state = 0; + io->kind = 0; + io->link = nil; + io->path = nil; + io->store = (Pos){ 0 }; } void diff --git a/sys/cmd/cc/lex.c b/sys/cmd/cc/lex.c index 2a637da..6c57b3c 100644 --- a/sys/cmd/cc/lex.c +++ b/sys/cmd/cc/lex.c @@ -40,6 +40,7 @@ getnsbyte(Lexer *lx) if (b == EOF) { if (lx->io->link) { popio(lx); + assert(lx->io); b = getbyte(lx); continue; } else @@ -687,6 +688,9 @@ popio(Lexer *lx) { Io *prev; + assert(lx->io == C.io-1); + --C.io; + prev = lx->io->link; freeio(lx->io); diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c index 6ab4ecd..cd8e28d 100644 --- a/sys/cmd/cc/pp.c +++ b/sys/cmd/cc/pp.c @@ -445,7 +445,7 @@ ppdef(Lexer *lx) { int b; Sym *sym; - int i, j, f, n, dot; + int i, j, n, dot; string s, a, base, end, buf, args[PPnarg]; s = ident(lx); @@ -468,7 +468,8 @@ ppdef(Lexer *lx) if (b != ')') { ungetbyte(lx); for (;;) { - // NOTE: This is a pointer to the lx->buffer. + // NOTE: This is a pointer into the lx->buffer. + // Can't reset lx->b while we hold the args! a = identdots(lx, &dot); if (a == nil) { errorat(lx->pos, "macro syntax error: improper argument"); @@ -522,52 +523,12 @@ ppdef(Lexer *lx) for (i = 0; i < n; i++) { if (strcmp(base, args[i]) == 0) { - goto Args; + goto Arg; } } str·appendlen(&buf, (lx->b - base - 1), base); continue; - Args: - /* Check for argx ## argy OR argx##argy */ - f = 0; - if (b != '\n' && isspace(b)) { - b = getnsbyte(lx); - f = 1; - } - if (b == '#') { - b = getbyte(lx); - if (b != '#') { - ungetbyte(lx); - goto Arg; - } - b = getnsbyte(lx); - lx->b = base; - while (isalnum(b) || b == '_') { - *lx->b++ = b; - if (lx->b >= end) { - errorat(lx->pos, "out of macro buffer space!"); - goto Bad; - } - b = getbyte(lx); - } - *lx->b = '\0'; - - for (j = 0; j < n; j++) { - if (strcmp(base, args[j]) == 0) - goto CatArgs; - } - errorat(lx->pos, "macro operator '##' must be terminated by valid variable identifier"); - goto Bad; - CatArgs: - str·appendbyte(&buf, PPcat); - str·appendbyte(&buf, 'a' + i); - str·appendbyte(&buf, 'a' + j); - continue; - } Arg: - if (f) - ungetbyte(lx); - str·appendbyte(&buf, PParg); str·appendbyte(&buf, 'a' + i); continue; @@ -628,8 +589,9 @@ ppdef(Lexer *lx) if (b == '#') { b = getnsbyte(lx); if (b == '#') { - errorat(lx->pos, "macro operator '##' must be proceeded by a valid variable identifier"); - goto Bad; + str·appendbyte(&buf, PPcat); + b = getbyte(lx); + continue; } lx->b = base; @@ -688,13 +650,14 @@ expandmacro(Lexer *lx, Sym *s, byte *dst) return str·len(s->macro)-2; } dots = *s->macro & PPvar; - nargs = (*s->macro & ~PPvar) - 1; + nargs = (*s->macro & ~PPvar); b = getnsbyte(lx); if (b != '(') { errorat(lx->pos, "macro function not given arguments"); goto Bad; } + n = 0; b = getbyte(lx); if (b != ')') { @@ -788,7 +751,7 @@ expandmacro(Lexer *lx, Sym *s, byte *dst) if (b == '(') lv++; if (b == ')') - lx--; + lv--; } *lx->b = '\0'; } @@ -799,7 +762,7 @@ expandmacro(Lexer *lx, Sym *s, byte *dst) goto Bad; } - if (s->macro[1] & PPbeg) { + if (s->macro[1] != PPbeg) { errorat(lx->pos, "corrupted macro buffer: %s", s->name); *dst = '\0'; goto Bad; @@ -838,23 +801,7 @@ expandmacro(Lexer *lx, Sym *s, byte *dst) break; case PPcat: - b = *it++; - b -= 'a'; - if (b < 0 && b > n) { - errorat(lx->pos, "malformed macro index: %s", s->name); - goto Bad; - } - strcpy(dst, arg[b]); - - b = *it++; - b -= 'a'; - if (b < 0 && b > n) { - errorat(lx->pos, "malformed macro index: %s", s->name); - goto Bad; - } - strcpy(dst, arg[b]); - - break; + continue; case '\0': goto End; -- cgit v1.2.1