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.
This commit is contained in:
Jared Casper 2013-05-16 23:33:07 -07:00 committed by Cary R
parent 34643d9628
commit ec8081f983
1 changed files with 24 additions and 8 deletions

View File

@ -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);
}
}
<MA_START>\( { BEGIN(MA_ADD); macro_start_args(); }