[PATCH vkd3d 3/4] vkd3d-shader: Implement #else.
Zebediah Figura
zfigura at codeweavers.com
Thu Dec 10 14:56:49 CST 2020
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
libs/vkd3d-shader/preproc.h | 4 ++++
libs/vkd3d-shader/preproc.l | 3 +++
libs/vkd3d-shader/preproc.y | 25 +++++++++++++++++++++++++
3 files changed, 32 insertions(+)
diff --git a/libs/vkd3d-shader/preproc.h b/libs/vkd3d-shader/preproc.h
index 224ae5b2..c05e3f6d 100644
--- a/libs/vkd3d-shader/preproc.h
+++ b/libs/vkd3d-shader/preproc.h
@@ -33,6 +33,10 @@ struct preproc_if_state
{
/* Are we currently in a "true" block? */
bool current_true;
+ /* Have we seen a "true" block in this #if..#endif yet? */
+ bool seen_true;
+ /* Have we seen an #else yet? */
+ bool seen_else;
};
struct preproc_ctx
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
index dd2b9c0a..fc3c5fa2 100644
--- a/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d-shader/preproc.l
@@ -100,6 +100,8 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
for (p = yytext + 1; strchr(" \t", *p); ++p)
;
+ if (!strcmp(p, "else"))
+ return T_ELSE;
if (!strcmp(p, "endif"))
return T_ENDIF;
if (!strcmp(p, "if"))
@@ -190,6 +192,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
switch (token)
{
+ case T_ELSE:
case T_ENDIF:
case T_IF:
ctx->current_directive = token;
diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y
index fda04a07..add39735 100644
--- a/libs/vkd3d-shader/preproc.y
+++ b/libs/vkd3d-shader/preproc.y
@@ -105,6 +105,8 @@ static bool preproc_push_if(struct preproc_ctx *ctx, bool condition)
return false;
state = &ctx->if_stack[ctx->if_count++];
state->current_true = condition && preproc_was_writing(ctx);
+ state->seen_true = condition;
+ state->seen_else = false;
return true;
}
@@ -161,6 +163,7 @@ static uint32_t preproc_parse_integer(const char *s)
%token T_NEWLINE
+%token T_ELSE "#else"
%token T_ENDIF "#endif"
%token T_IF "#if"
@@ -181,6 +184,28 @@ directive
if (!preproc_push_if(ctx, !!$2))
YYABORT;
}
+ | T_ELSE T_NEWLINE
+ {
+ if (ctx->if_count)
+ {
+ struct preproc_if_state *state = &ctx->if_stack[ctx->if_count - 1];
+
+ if (state->seen_else)
+ {
+ preproc_warning(ctx, &@$, VKD3D_SHADER_WARNING_PP_INVALID_DIRECTIVE, "Ignoring #else after #else.");
+ }
+ else
+ {
+ state->current_true = !state->seen_true && preproc_was_writing(ctx);
+ state->seen_else = true;
+ }
+ }
+ else
+ {
+ preproc_warning(ctx, &@$, VKD3D_SHADER_WARNING_PP_INVALID_DIRECTIVE,
+ "Ignoring #else without prior #if.");
+ }
+ }
| T_ENDIF T_NEWLINE
{
if (ctx->if_count)
--
2.29.2
More information about the wine-devel
mailing list