Zebediah Figura : vkd3d-shader: Implement #else.
Module: vkd3d Branch: master Commit: 78e31bff163940620f58c592b222148b20981f9f URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=78e31bff163940620f58c592... Author: Zebediah Figura <zfigura(a)codeweavers.com> Date: Tue Dec 15 17:13:22 2020 -0600 vkd3d-shader: Implement #else. Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com> Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- 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 0f494fc..effcd99 100644 --- a/libs/vkd3d-shader/preproc.h +++ b/libs/vkd3d-shader/preproc.h @@ -27,6 +27,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 c60970c..33860d3 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")) @@ -187,6 +189,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 3dc7e7c..fc50860 100644 --- a/libs/vkd3d-shader/preproc.y +++ b/libs/vkd3d-shader/preproc.y @@ -81,6 +81,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; } @@ -138,6 +140,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" @@ -158,6 +161,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)
participants (1)
-
Alexandre Julliard