Module: vkd3d Branch: master Commit: 0f80ac09759936a8074ca691ecd8e5034bfaccf1 URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=0f80ac09759936a8074ca691...
Author: Zebediah Figura zfigura@codeweavers.com Date: Tue Jan 12 16:14:18 2021 -0600
vkd3d-shader: Parse function-like macro definitions.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
libs/vkd3d-shader/preproc.l | 5 +++- libs/vkd3d-shader/preproc.y | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l index 86ca473..77f4f0dc 100644 --- a/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d-shader/preproc.l @@ -70,6 +70,7 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* <C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);} <C_COMMENT,CXX_COMMENT>. {}
+<INITIAL>{IDENTIFIER}/( {return T_IDENTIFIER_PAREN;} <INITIAL>{IDENTIFIER} {return T_IDENTIFIER;}
/* We have no use for floats, but shouldn't parse them as integers. */ @@ -141,6 +142,7 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]* }
<INITIAL>{WS}+ {} +<INITIAL>[(),] {return yytext[0];} <INITIAL>. {return T_TEXT;}
%% @@ -221,6 +223,7 @@ static int return_token(int token, YYSTYPE *lval, const char *text) switch (token) { case T_IDENTIFIER: + case T_IDENTIFIER_PAREN: case T_INTEGER: case T_STRING: case T_TEXT: @@ -321,7 +324,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) continue; }
- if (token == T_IDENTIFIER) + if (token == T_IDENTIFIER || token == T_IDENTIFIER_PAREN) { struct preproc_macro *macro;
diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y index 17bc649..3cb7de6 100644 --- a/libs/vkd3d-shader/preproc.y +++ b/libs/vkd3d-shader/preproc.y @@ -28,6 +28,12 @@
#define PREPROC_YYLTYPE struct vkd3d_shader_location
+struct parse_arg_names +{ + char **args; + size_t count; +}; + }
%code provides @@ -254,6 +260,15 @@ static const void *get_parent_data(struct preproc_ctx *ctx) return preproc_get_top_file(ctx)->code.code; }
+static void free_parse_arg_names(struct parse_arg_names *args) +{ + unsigned int i; + + for (i = 0; i < args->count; ++i) + vkd3d_free(args->args[i]); + vkd3d_free(args->args); +} + }
%define api.prefix {preproc_yy} @@ -268,11 +283,14 @@ static const void *get_parent_data(struct preproc_ctx *ctx) %union { char *string; + const char *const_string; uint32_t integer; struct vkd3d_string_buffer string_buffer; + struct parse_arg_names arg_names; }
%token <string> T_IDENTIFIER +%token <string> T_IDENTIFIER_PAREN %token <string> T_INTEGER %token <string> T_STRING %token <string> T_TEXT @@ -291,7 +309,9 @@ static const void *get_parent_data(struct preproc_ctx *ctx)
%type <integer> expr %type <string> body_token +%type <const_string> body_token_const %type <string_buffer> body_text +%type <arg_names> identifier_list
%%
@@ -302,6 +322,28 @@ shader_text vkd3d_string_buffer_printf(&ctx->buffer, "\n"); }
+identifier_list + : T_IDENTIFIER + { + if (!($$.args = vkd3d_malloc(sizeof(*$$.args)))) + YYABORT; + $$.args[0] = $1; + $$.count = 1; + } + | identifier_list ',' T_IDENTIFIER + { + char **new_array; + + if (!(new_array = vkd3d_realloc($1.args, ($1.count + 1) * sizeof(*$$.args)))) + { + free_parse_arg_names(&$1); + YYABORT; + } + $$.args = new_array; + $$.count = $1.count + 1; + $$.args[$1.count] = $3; + } + body_text : %empty { @@ -316,12 +358,32 @@ body_text } vkd3d_free($2); } + | body_text body_token_const + { + if (vkd3d_string_buffer_printf(&$$, "%s ", $2) < 0) + YYABORT; + }
body_token : T_IDENTIFIER + | T_IDENTIFIER_PAREN | T_INTEGER | T_TEXT
+body_token_const + : '(' + { + $$ = "("; + } + | ')' + { + $$ = ")"; + } + | ',' + { + $$ = ","; + } + directive : T_DEFINE T_IDENTIFIER body_text T_NEWLINE { @@ -332,6 +394,16 @@ directive YYABORT; } } + | T_DEFINE T_IDENTIFIER_PAREN '(' identifier_list ')' body_text T_NEWLINE + { + free_parse_arg_names(&$4); + if (!preproc_add_macro(ctx, &@6, $2, &@6, &$6)) + { + vkd3d_free($2); + vkd3d_string_buffer_cleanup(&$6); + YYABORT; + } + } | T_UNDEF T_IDENTIFIER T_NEWLINE { struct preproc_macro *macro;