Zebediah Figura : vkd3d-shader: Parse function-like macro definitions.

Alexandre Julliard julliard at winehq.org
Thu Jan 14 14:37:02 CST 2021


Module: vkd3d
Branch: master
Commit: 0f80ac09759936a8074ca691ecd8e5034bfaccf1
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=0f80ac09759936a8074ca691ecd8e5034bfaccf1

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Tue Jan 12 16:14:18 2021 -0600

vkd3d-shader: Parse function-like macro definitions.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list