From 08a4e1ef256167ec8c763217a69365385f1da8f2 Mon Sep 17 00:00:00 2001 From: lemon Date: Wed, 15 Oct 2025 10:38:19 +0200 Subject: c: concatenate adjacent string literal tokens --- c.c | 25 ++++++++++++++++++++++--- test/pp.c | 5 ++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/c.c b/c.c index b232ba4..7eae3e6 100644 --- a/c.c +++ b/c.c @@ -18,7 +18,27 @@ struct comp { /** Parsing helper functions **/ #define peek(Cm,Tk) lexpeek(&(Cm)->lx,Tk) -#define lex(Cm,Tk) lex(&(Cm)->lx,Tk) +static int +lexc(struct comp *cm, struct token *tk) +{ + int t = lex(&cm->lx, tk); + if (t == TKSTRLIT && peek(cm, NULL) == TKSTRLIT) { + /* 5.1.1.2 Translation phase 6: concatenate adjacent string literal tokens */ + static char buf[200]; + struct token tk2; + vec_of(char) rest = VINIT(buf, sizeof buf); + do { + lex(&cm->lx, &tk2); + vpushn(&rest, tk2.s, tk2.len); + } while (peek(cm, NULL) == TKSTRLIT); + tk->s = memcpy(alloc(&cm->exarena, tk->len + rest.n, 0), tk->s, tk->len); + memcpy((char *)tk->s + tk->len, rest.p, rest.n); + tk->len += rest.n; + vfree(&rest); + } + return t; +} +#define lex(Cm,Tk) lexc(Cm,Tk) static bool match(struct comp *cm, struct token *tk, enum toktag t) { @@ -744,8 +764,7 @@ Unary: ex.ty.t = ty.t ? ty.t : TYINT; break; case TKSTRLIT: - ex = mkexpr(ESTRLIT, tk.span, - mkarrtype(mktype(TYCHAR), 0, tk.len+1), .s = { (uchar *)tk.s, tk.len }); + ex = mkexpr(ESTRLIT, tk.span, mkarrtype(mktype(TYCHAR), 0, tk.len+1), .s = { (uchar *)tk.s, tk.len }); break; case TKIDENT: Ident: diff --git a/test/pp.c b/test/pp.c index 7c34542..51cf70f 100644 --- a/test/pp.c +++ b/test/pp.c @@ -7,6 +7,7 @@ #define CATl(a) a##bar #define CATr(a) foo##a #define CAT(a,b) a##b +#define foobar() foo##bar #define hash_hash # ## # #define mkstr(a) # a @@ -21,11 +22,13 @@ main(void) ++foobar; --CATr(bar); CAT(foo,bar) += 3; + foobar() /=2; printf("%s %s\n",STR ( ok /1 "\n"n ;.& 05.5), STR(ADD(1,2))); hi(ADD(Foo, SQR(Bar+1))); int foo123 = 77; - printf("%s %s %g\n", str(Foo,5), xstr(Foo), CAT(1.5,e3f) + CAT(7,)-CAT(,1)); + printf("%s " + "%s %g\n", str(Foo,5), xstr(Foo), CAT(1.5,e3f) + CAT(7,)-CAT(,1)); printf("join: \"%s\"\n", p); CAT(ret,urn) 0; } -- cgit v1.2.3