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