mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-23 18:20:30 +01:00
Implement all operators specified for GLSL #if expressions (with tests).
The operator coverage here is quite complete. The one big thing missing is that we are not yet doing macro expansion in #if lines. This makes the whole support fairly useless, so we plan to fix that shortcoming right away.
This commit is contained in:
parent
b20d33c5c6
commit
bcbd587b0f
5 changed files with 195 additions and 7 deletions
45
glcpp-lex.l
45
glcpp-lex.l
|
|
@ -66,6 +66,51 @@ TOKEN [^[:space:](),]+
|
|||
return INTEGER;
|
||||
}
|
||||
|
||||
<ST_IF>"defined" {
|
||||
return DEFINED;
|
||||
}
|
||||
|
||||
<ST_IF>"<<" {
|
||||
return LEFT_SHIFT;
|
||||
}
|
||||
|
||||
<ST_IF>">>" {
|
||||
return RIGHT_SHIFT;
|
||||
}
|
||||
|
||||
<ST_IF>"<=" {
|
||||
return LESS_OR_EQUAL;
|
||||
}
|
||||
|
||||
<ST_IF>">=" {
|
||||
return GREATER_OR_EQUAL;
|
||||
}
|
||||
|
||||
<ST_IF>"==" {
|
||||
return EQUAL;
|
||||
}
|
||||
|
||||
<ST_IF>"!=" {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
|
||||
<ST_IF>"&&" {
|
||||
return AND;
|
||||
}
|
||||
|
||||
<ST_IF>"||" {
|
||||
return OR;
|
||||
}
|
||||
|
||||
<ST_IF>[-+*/%<>&^|()] {
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
<ST_IF>{IDENTIFIER} {
|
||||
yylval.str = xtalloc_strdup (yyextra, yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
<ST_IF>{HSPACE}+
|
||||
|
||||
<ST_IF>\n {
|
||||
|
|
|
|||
|
|
@ -118,13 +118,24 @@ glcpp_parser_lex (glcpp_parser_t *parser);
|
|||
%parse-param {glcpp_parser_t *parser}
|
||||
%lex-param {glcpp_parser_t *parser}
|
||||
|
||||
%token DEFINE ELIF ELSE ENDIF FUNC_MACRO IDENTIFIER IDENTIFIER_FINALIZED IF IFDEF IFNDEF INTEGER OBJ_MACRO NEWLINE SEPARATOR SPACE TOKEN UNDEF
|
||||
%token DEFINE DEFINED ELIF ELSE ENDIF FUNC_MACRO IDENTIFIER IDENTIFIER_FINALIZED IF IFDEF IFNDEF INTEGER OBJ_MACRO NEWLINE SPACE TOKEN UNDEF
|
||||
%type <ival> expression INTEGER punctuator
|
||||
%type <str> content FUNC_MACRO IDENTIFIER IDENTIFIER_FINALIZED OBJ_MACRO
|
||||
%type <argument_list> argument_list
|
||||
%type <string_list> macro parameter_list
|
||||
%type <token> TOKEN argument_word argument_word_or_comma
|
||||
%type <token_list> argument argument_or_comma replacement_list pp_tokens
|
||||
%left OR
|
||||
%left AND
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%left EQUAL NOT_EQUAL
|
||||
%left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
|
||||
%left LEFT_SHIFT RIGHT_SHIFT
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right UNARY
|
||||
|
||||
/* Hard to remove shift/reduce conflicts documented as follows:
|
||||
*
|
||||
|
|
@ -142,11 +153,7 @@ glcpp_parser_lex (glcpp_parser_t *parser);
|
|||
|
||||
%%
|
||||
|
||||
/* We do all printing at the input level.
|
||||
*
|
||||
* The value for "input" is simply TOKEN or SEPARATOR so we
|
||||
* can decide whether it's necessary to print a space
|
||||
* character between any two. */
|
||||
/* We do all printing at the input level. */
|
||||
input:
|
||||
/* empty */ {
|
||||
parser->just_printed_separator = 1;
|
||||
|
|
@ -350,11 +357,87 @@ directive:
|
|||
}
|
||||
;
|
||||
|
||||
/* XXX: Need to fill out with all operators. */
|
||||
expression:
|
||||
INTEGER {
|
||||
$$ = $1;
|
||||
}
|
||||
| expression OR expression {
|
||||
$$ = $1 || $3;
|
||||
}
|
||||
| expression AND expression {
|
||||
$$ = $1 && $3;
|
||||
}
|
||||
| expression '|' expression {
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| expression '^' expression {
|
||||
$$ = $1 ^ $3;
|
||||
}
|
||||
| expression '&' expression {
|
||||
$$ = $1 & $3;
|
||||
}
|
||||
| expression NOT_EQUAL expression {
|
||||
$$ = $1 != $3;
|
||||
}
|
||||
| expression EQUAL expression {
|
||||
$$ = $1 == $3;
|
||||
}
|
||||
| expression GREATER_OR_EQUAL expression {
|
||||
$$ = $1 >= $3;
|
||||
}
|
||||
| expression LESS_OR_EQUAL expression {
|
||||
$$ = $1 <= $3;
|
||||
}
|
||||
| expression '>' expression {
|
||||
$$ = $1 > $3;
|
||||
}
|
||||
| expression '<' expression {
|
||||
$$ = $1 < $3;
|
||||
}
|
||||
| expression RIGHT_SHIFT expression {
|
||||
$$ = $1 >> $3;
|
||||
}
|
||||
| expression LEFT_SHIFT expression {
|
||||
$$ = $1 << $3;
|
||||
}
|
||||
| expression '-' expression {
|
||||
$$ = $1 - $3;
|
||||
}
|
||||
| expression '+' expression {
|
||||
$$ = $1 + $3;
|
||||
}
|
||||
| expression '%' expression {
|
||||
$$ = $1 % $3;
|
||||
}
|
||||
| expression '/' expression {
|
||||
$$ = $1 / $3;
|
||||
}
|
||||
| expression '*' expression {
|
||||
$$ = $1 * $3;
|
||||
}
|
||||
| '!' expression %prec UNARY {
|
||||
$$ = ! $2;
|
||||
}
|
||||
| '~' expression %prec UNARY {
|
||||
$$ = ~ $2;
|
||||
}
|
||||
| '-' expression %prec UNARY {
|
||||
$$ = - $2;
|
||||
}
|
||||
| '+' expression %prec UNARY {
|
||||
$$ = + $2;
|
||||
}
|
||||
| DEFINED IDENTIFIER %prec UNARY {
|
||||
string_list_t *macro = hash_table_find (parser->defines, $2);
|
||||
talloc_free ($2);
|
||||
if (macro)
|
||||
$$ = 1;
|
||||
else
|
||||
$$ = 0;
|
||||
}
|
||||
| '(' expression ')' {
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
parameter_list:
|
||||
|
|
|
|||
6
tests/049-if-expression-precedence.c
Normal file
6
tests/049-if-expression-precedence.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#if 1 + 2 * 3 + - (25 % 17 - + 1)
|
||||
failure with operator precedence
|
||||
#else
|
||||
success
|
||||
#endif
|
||||
|
||||
19
tests/050-if-defined.c
Normal file
19
tests/050-if-defined.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#if defined foo
|
||||
failure_1
|
||||
#else
|
||||
success_1
|
||||
#endif
|
||||
#define foo
|
||||
#if defined foo
|
||||
success_2
|
||||
#else
|
||||
failure_2
|
||||
#endif
|
||||
#undef foo
|
||||
#if defined foo
|
||||
failure_3
|
||||
#else
|
||||
success_3
|
||||
#endif
|
||||
|
||||
|
||||
35
tests/051-if-relational.c
Normal file
35
tests/051-if-relational.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#if 3 < 2
|
||||
failure_1
|
||||
#else
|
||||
success_1
|
||||
#endif
|
||||
|
||||
#if 3 >= 2
|
||||
success_2
|
||||
#else
|
||||
failure_2
|
||||
#endif
|
||||
|
||||
#if 2 + 3 <= 5
|
||||
success_3
|
||||
#else
|
||||
failure_3
|
||||
#endif
|
||||
|
||||
#if 3 - 2 == 1
|
||||
success_3
|
||||
#else
|
||||
failure_3
|
||||
#endif
|
||||
|
||||
#if 1 > 3
|
||||
failure_4
|
||||
#else
|
||||
success_4
|
||||
#endif
|
||||
|
||||
#if 1 != 5
|
||||
success_5
|
||||
#else
|
||||
failure_5
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue