From ec8081f983ad490e8488e3b479ae25690fa45ec0 Mon Sep 17 00:00:00 2001 From: Jared Casper Date: Thu, 16 May 2013 23:33:07 -0700 Subject: [PATCH] Handle `", `\`", and `` in macro definitions. Implements page 644 of IEEE 1800-2012. `` is now overloaded with the Icarus-specific "stringify" expansions. It is now used as indicated in 1800-2012 when appearing inside a macro definition, and the Icarus way when not. To do so, it uses the fact that istack->file is NULL iff we are processing expanded macro text, which is a bit of hack but works as is. `" and `\`" on the other hand are treated the same inside and outside of macro definitions. --- ivlpp/lexor.lex | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index 90843829a..8e8167c77 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -255,6 +255,12 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0); } + /* `" overrides the usual lexical meaning of " and `\`" indicates + that the expansion should include the escape sequence \". + */ +`\" { fputc('"', yyout); } +`\\`\" { fprintf(yyout, "\\\""); } + /* Strings do not contain preprocessor directives, but can expand * macros. If that happens, they get expanded in the context of the * string. @@ -551,15 +557,25 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) do_expand(0); } - /* Stringified version of macro expansion. */ + /* Stringified version of macro expansion. If the sequence `` is + * encountered inside a macro definition, we use the SystemVerilog + * handling of ignoring it so that identifiers can be constructed + * from arguments. If istack->file is NULL, we are reading text + * produced from a macro, so use SystemVerilog's handling; + * otherwise, use the special Icarus handling. + */ ``[a-zA-Z_][a-zA-Z0-9_$]* { - assert(do_expand_stringify_flag == 0); - do_expand_stringify_flag = 1; - fputc('"', yyout); - if (macro_needs_args(yytext+2)) - yy_push_state(MA_START); - else - do_expand(0); + if (istack->file == NULL) + fprintf(yyout, "%s", yytext+2); + else { + assert(do_expand_stringify_flag == 0); + do_expand_stringify_flag = 1; + fputc('"', yyout); + if (macro_needs_args(yytext+2)) + yy_push_state(MA_START); + else + do_expand(0); + } } \( { BEGIN(MA_ADD); macro_start_args(); }