From: Carl Worth Date: Mon, 24 May 2010 17:37:38 +0000 (-0700) Subject: Implement all operators specified for GLSL #if expressions (with tests). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bcbd587b0f5312d85307785ee2df6e5906af4f7b;p=mesa.git 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. --- diff --git a/glcpp-lex.l b/glcpp-lex.l index 825ce3d3709..84166fb76fc 100644 --- a/glcpp-lex.l +++ b/glcpp-lex.l @@ -66,6 +66,51 @@ TOKEN [^[:space:](),]+ return INTEGER; } +"defined" { + return DEFINED; +} + +"<<" { + return LEFT_SHIFT; +} + +">>" { + return RIGHT_SHIFT; +} + +"<=" { + return LESS_OR_EQUAL; +} + +">=" { + return GREATER_OR_EQUAL; +} + +"==" { + return EQUAL; +} + +"!=" { + return NOT_EQUAL; +} + +"&&" { + return AND; +} + +"||" { + return OR; +} + +[-+*/%<>&^|()] { + return yytext[0]; +} + +{IDENTIFIER} { + yylval.str = xtalloc_strdup (yyextra, yytext); + return IDENTIFIER; +} + {HSPACE}+ \n { diff --git a/glcpp-parse.y b/glcpp-parse.y index 26432f20325..0d3afa7af64 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -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 expression INTEGER punctuator %type content FUNC_MACRO IDENTIFIER IDENTIFIER_FINALIZED OBJ_MACRO %type argument_list %type macro parameter_list %type TOKEN argument_word argument_word_or_comma %type 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: diff --git a/tests/049-if-expression-precedence.c b/tests/049-if-expression-precedence.c new file mode 100644 index 00000000000..cea935220fd --- /dev/null +++ b/tests/049-if-expression-precedence.c @@ -0,0 +1,6 @@ +#if 1 + 2 * 3 + - (25 % 17 - + 1) +failure with operator precedence +#else +success +#endif + diff --git a/tests/050-if-defined.c b/tests/050-if-defined.c new file mode 100644 index 00000000000..9838cc747d5 --- /dev/null +++ b/tests/050-if-defined.c @@ -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 + + diff --git a/tests/051-if-relational.c b/tests/051-if-relational.c new file mode 100644 index 00000000000..c3db488e0de --- /dev/null +++ b/tests/051-if-relational.c @@ -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