From 08f14cba3c350d44878f6133990fa5e4aa02d8f9 Mon Sep 17 00:00:00 2001 From: lemon Date: Thu, 11 Sep 2025 17:15:41 +0200 Subject: preprocessor: more awful hacks --- io.c | 2 +- ir.c | 2 ++ lex.c | 46 ++++++++++++++++++++++++++++++---------------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/io.c b/io.c index c8e338f..aa6af3f 100644 --- a/io.c +++ b/io.c @@ -604,7 +604,7 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) n += bputc(out, ' '); } } - return buf->err ? -1 : n; + return n; } int diff --git a/ir.c b/ir.c index 3da5862..fa840cc 100644 --- a/ir.c +++ b/ir.c @@ -452,12 +452,14 @@ delnops(struct block *blk) /* delete trailing nops */ while (blk->ins.n > 0 && instrtab[t = blk->ins.p[blk->ins.n - 1]].op == Onop) { --blk->ins.n; + deluses(t); memcpy(&instrtab[t], &instrfreelist, sizeof(int)); instrfreelist = t; } /* delete rest of nops */ for (i = blk->ins.n - 2, n = 0; i >= 0; --i) { if (instrtab[t = blk->ins.p[i]].op == Onop) { + deluses(t); memcpy(&instrtab[t], &instrfreelist, sizeof(int)); instrfreelist = t; ++n; diff --git a/lex.c b/lex.c index 01fc6d7..ed58d15 100644 --- a/lex.c +++ b/lex.c @@ -1085,13 +1085,18 @@ ppinclude(struct lexer *lx, const struct span *span0) fatal(&span, "Maximum nested include depth of %d reached", includedepth); } +/* horrible kludge for proper expansion in the face of nested macros with arguments, + * stringifying, etc */ +static bool noexpandmac; + static struct macrostack { struct macrostack *link; struct rlist *args; const struct rlist *rlist; struct span0 exspan; - int macno; int idx; + int macno:30; + int prevnoexpandmac:1; } mstk[64], *mfreelist; static void @@ -1108,11 +1113,10 @@ pushmacstk(struct lexer *lx, const struct span *span, const struct macrostack *m l->args = m->args; l->idx = 0; l->exspan = span->ex; + l->prevnoexpandmac = noexpandmac; lx->macstk = l; } -static bool lexnoexpand; - static bool tryexpand(struct lexer *lx, struct token *tk) { @@ -1138,6 +1142,7 @@ tryexpand(struct lexer *lx, struct token *tk) for (l = lx->macstk; l->macno != tk->macidx; l = l->link) ; arg = &l->args[tk->argidx]; if (tk->t == TKPPMACARG && arg->n) { + noexpandmac = 0; pushmacstk(lx, &span, &(struct macrostack){ .idx = 0, .rlist = arg, @@ -1145,27 +1150,33 @@ tryexpand(struct lexer *lx, struct token *tk) }); return 1; } else { - char tmp[200]; + char tmp[100]; struct wbuf buf = MEMBUF(tmp, sizeof tmp); - //vec_of(uchar) b = VINIT(tmp, sizeof tmp); + int n = 0; // XXX this is wrong bc the string literal produced should be re-parsed later // i.e. stringifying the token sequence '\n' should ultimately produce a // string with an actual newline, not {'\\','n'} - + Redo: for (const struct token *tk = arg->tk, *end = tk + arg->n; tk != end; ++tk) { + //efmt("strify ++ (%d) %'tk\n", tk->t,tk); if (tk != arg->tk && wsseparated(tk-1, tk)) - bfmt(&buf, " "); - bfmt(&buf, "%tk", tk); + n += bfmt(&buf, " "); + n += bfmt(&buf, "%tk", tk); } ioputc(&buf, 0); - assert(!buf.err && "strify too long"); + if (buf.err) { + struct wbuf new = MEMBUF(alloc(lx->tmparena, n+1, 1), n+1); + assert(buf.buf == tmp); + memcpy(&buf, &new, sizeof buf); + goto Redo; + } tk->t = TKSTRLIT; - tk->s = alloccopy(lx->tmparena, buf.buf, buf.len, 1); + tk->s = buf.buf != tmp ? buf.buf : alloccopy(lx->tmparena, buf.buf, buf.len, 1); tk->len = buf.len; return 0; } - } else if (!isppident(*tk) || !(mac = findmac(tk->s))) + } else if (noexpandmac || !isppident(*tk) || !(mac = findmac(tk->s))) return 0; macidx = mac - macros.p; @@ -1182,9 +1193,11 @@ tryexpand(struct lexer *lx, struct token *tk) int cur, n, i, bal; struct token tk; - lexnoexpand = 1; - if (lexpeek(lx, &tk) != '(') + noexpandmac = 1; + if (lexpeek(lx, &tk) != '(') { + noexpandmac = 0; return 0; + } lex(lx, &tk); args = xcalloc((mac->nparam + mac->variadic) * sizeof *args); @@ -1214,7 +1227,7 @@ tryexpand(struct lexer *lx, struct token *tk) ++n; } } - lexnoexpand = 0; + noexpandmac = 0; if (tk.t == TKEOF) error(&span, "unterminated function-like macro invocation"); else if (i < mac->nparam) { @@ -1257,6 +1270,7 @@ popmac(struct lexer *lx) assert(stk = lx->macstk); do { + noexpandmac = stk->prevnoexpandmac; if (stk->args) { free((void *)stk->args[0].tk); free(stk->args); @@ -1348,7 +1362,7 @@ lex(struct lexer *lx, struct token *tk_) *tk = rl->tk[lx->macstk->idx++]; assert(tk->t); tk->span.ex = lx->macstk->exspan; - if (!lexnoexpand && tryexpand(lx, tk)) + if (tryexpand(lx, tk)) return lex(lx, tk_); return tk->t; } @@ -1404,7 +1418,7 @@ lex(struct lexer *lx, struct token *tk_) } else { linebegin = 0; if (skip && tk->t != TKEOF) continue; - if (!lexnoexpand && tryexpand(lx, tk)) + if (tryexpand(lx, tk)) return lex(lx, tk_); if (t == TKEOF && nppcnd) { struct span span = { ppcndstk[nppcnd-1].ifspan }; -- cgit v1.2.3