From 13772a8a2120017981d280bfe120fdbb74f27860 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 19 May 2020 16:37:23 -0700 Subject: fix: many bug fixes to number parsing --- sys/cmd/cc/pp.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'sys/cmd/cc/pp.c') diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c index 16fac29..2aa1291 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 = %s, ON LINE %d\n", name, macro+1, lx->pos.line); + printf("DEFINING MACRO %s = %s, ON LINE %d\n", name, macro+2, lx->pos.line); mac = define(&lx->sym, name, Smacro); mac->macro = macro; @@ -187,7 +187,10 @@ evalmacro(Lexer *lx, byte prec) l = opand(lx); for (;;) { b = getnsbyte(lx); - if (b == '\n') { + // NOTE: Either this or we pass in what are stopping byte is + // New line should always stop us... + // Is there any case where we SHOULDN'T STOP ON ')'? + if (b == '\n' || b == ')') { ungetbyte(lx); break; } @@ -196,7 +199,6 @@ evalmacro(Lexer *lx, byte prec) tok = lex(lx); // simplified jump table of precedence // unpacked to evaluate inline - // NOTE: You might have to unget bytes to replace token on stack switch (tok.kind & Vmask) { case Astar: if (prec > 10) { @@ -451,12 +453,14 @@ ppdef(Lexer *lx) sym = lookup(&lx->sym, s); if (sym) { + // TODO: should be a warning... errorat(lx->pos, "macro redefined: '%s'", sym->name); // goto Bad; } - n = 0; - b = getbyte(lx); + n = 0; + dot = 0; + b = getbyte(lx); if (b == '(') { b = getnsbyte(lx); if (b != ')') { @@ -490,7 +494,7 @@ ppdef(Lexer *lx) if (b != '\n') b = getnsbyte(lx); - buf = str·makef("%d%c", n, PPbeg); + buf = str·makef("%c%c", n, PPbeg); for (;;) { if (isalpha(b) || b == '_') { lx->b = lx->buf; @@ -512,7 +516,8 @@ ppdef(Lexer *lx) continue; Args: /* Check for argx ## argy OR argx##argy */ - if (isspace(b)) { + f = 0; + if (b != '\n' && isspace(b)) { b = getnsbyte(lx); f = 1; } @@ -550,6 +555,7 @@ ppdef(Lexer *lx) str·appendbyte(&buf, 'a' + i); continue; } + if (b == '/') { b = getbyte(lx); if (b == '/') { @@ -577,6 +583,7 @@ ppdef(Lexer *lx) str·appendbyte(&buf, '/'); continue; } + if (b == '\\') { b = getbyte(lx); /* unix */ @@ -607,6 +614,7 @@ ppdef(Lexer *lx) errorat(lx->pos, "macro operator '##' must be proceeded by a valid variable identifier"); goto Bad; } + lx->b = lx->buf; while (isalnum(b) || b == '_') { *lx->b++ = b; @@ -654,17 +662,25 @@ expandmacro(Lexer *lx, Sym *s, byte *dst) byte b, *it, *e, *arg[PPnarg]; /* not a function macro */ - if (*s->macro == '\0') { - strcpy(dst, s->macro + 1); - return 0; + if (s->macro[0] == '\0') { + if (s->macro[1] != PPbeg) { + errorat(lx->pos, "malformed macro"); + goto Bad; + } + strcpy(dst, s->macro + 2); + return str·len(s->macro)-2; } + printf("%c\n", s->macro[0]); + printf("%c\n", s->macro[1]); dots = *s->macro & PPvar; nargs = (*s->macro & ~PPvar) - 1; b = getnsbyte(lx); - if (b != '(') + if (b != '(') { + errorat(lx->pos, "macro function not given arguments"); goto Bad; + } n = 0; b = getbyte(lx); if (b != ')') { @@ -791,23 +807,39 @@ expandmacro(Lexer *lx, Sym *s, byte *dst) } strcpy(dst, arg[b]); dst += strlen(arg[b]); + break; case PPstr: b = *it++; b -= 'a'; + if (b < 0 && b > n) { + errorat(lx->pos, "malformed macro index: %s", s->name); + goto Bad; + } *dst++ = '"'; strcpy(dst, arg[b]); *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; case '\0': @@ -822,10 +854,10 @@ End: *dst = '\0'; return dst - e; Nospace: - errorf("out of memory during macro expansion %s", s->name); + errorat(lx->pos, "out of memory during macro expansion %s", s->name); Bad: ppend(lx); - errorf("failed to expand macro %s", s->name); + errorat(lx->pos, "failed to expand macro %s", s->name); return -1; } -- cgit v1.2.1