Implement support for indirect macro expansions in the preprocessor. This closes #36

This commit is contained in:
Dale Weiler 2014-09-27 01:48:03 -04:00
parent faacfa018a
commit 2208136403
7 changed files with 64 additions and 4 deletions

View file

@ -426,6 +426,25 @@ M_SQRT2
M_SQRT1_2
M_TAU
.Ed
.It Fl f Ns Cm ftepp-indirect-expansion
Enable indirect macro expansion. This only works in combination
with '-fftepp' and is currently not included by '-std=fteqcc'.
Enabling this behavior will allow the preprocessor to operate more
like the standard C preprocessor in that it will allow arguments
of macros which are macro-expanded to be substituted into the
definition of the macro.
.Pp
As an example:
.Bd -literal -offset indent
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
.Ed
With this enabled, an expansion of THE_ANSWER_STR will yield
the string "42". With this disabled an expansion of THE_ANSWER_STR
will yield "THE_ANSWER"
.It Fl f Ns Cm relaxed-switch
Allow switch cases to use non constant variables.
.It Fl f Ns Cm short-logic

10
ftepp.c
View file

@ -734,6 +734,7 @@ static void ftepp_recursion_footer(ftepp_t *ftepp)
ftepp_out(ftepp, "\n#pragma pop(line)\n", false);
}
static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params, bool resetline);
static void ftepp_param_out(ftepp_t *ftepp, macroparam *param)
{
size_t i;
@ -742,8 +743,13 @@ static void ftepp_param_out(ftepp_t *ftepp, macroparam *param)
out = param->tokens[i];
if (out->token == TOKEN_EOL)
ftepp_out(ftepp, "\n", false);
else
ftepp_out(ftepp, out->value, false);
else {
ppmacro *find = ftepp_macro_find(ftepp, out->value);
if (OPTS_FLAG(FTEPP_INDIRECT_EXPANSION) && find && !find->has_params)
ftepp_macro_expand(ftepp, find, NULL, false);
else
ftepp_out(ftepp, out->value, false);
}
}
}

View file

@ -84,6 +84,25 @@
FTEPP_MATHDEFS = false
#Enable indirect macro expansion. This only works in combination
#with '-fftepp' and is currently not included by '-std=fteqcc'.
#Enabling this behavior will allow the preprocessor to operate more
#like the standard C preprocessor in that it will allow arguments
#of macros which are macro-expanded to be substituted into the
#definition of the macro. As an example:
#
# #define STR1(x) #x
# #define STR2(x) STR1(x)
# #define THE_ANSWER 42
# #define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
#
#With this enabled, an expansion of THE_ANSWER_STR will yield
#the string "42". With this disabled an expansion of THE_ANSWER_STR
#will yield "THE_ANSWER"
FTEPP_INDIRECT_EXPANSION = false
#Allow switch cases to use non constant variables.
RELAXED_SWITCH = true

View file

@ -32,6 +32,7 @@
GMQCC_DEFINE_FLAG(FTEPP)
GMQCC_DEFINE_FLAG(FTEPP_PREDEFS)
GMQCC_DEFINE_FLAG(FTEPP_MATHDEFS)
GMQCC_DEFINE_FLAG(FTEPP_INDIRECT_EXPANSION)
GMQCC_DEFINE_FLAG(RELAXED_SWITCH)
GMQCC_DEFINE_FLAG(SHORT_LOGIC)
GMQCC_DEFINE_FLAG(PERL_LOGIC)

6
test.c
View file

@ -806,19 +806,21 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
} else {
/* Preprocessing (qcflags mean shit all here we don't allow them) */
if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
util_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s -o %s",
task_bins[TASK_COMPILE],
directories[i],
tmpl->sourcefile,
tmpl->compileflags,
tmpl->tempfilename
);
} else {
util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s %s -o %s",
task_bins[TASK_COMPILE],
curdir,
defs,
directories[i],
tmpl->sourcefile,
tmpl->compileflags,
tmpl->tempfilename
);
}

View file

@ -0,0 +1,6 @@
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER)
THE_ANSWER_STR

View file

@ -0,0 +1,7 @@
I: ppindirectexpand.qc
D: test preprocessor indirect macro expansion
T: -pp
C: -fftepp-indirect-expansion -std=gmqcc
F: -no-defs
M: "42"