Browse Source

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.
tags/mesa-7.9-rc1
Carl Worth 15 years ago
parent
commit
bcbd587b0f
5 changed files with 195 additions and 7 deletions
  1. 45
    0
      glcpp-lex.l
  2. 90
    7
      glcpp-parse.y
  3. 6
    0
      tests/049-if-expression-precedence.c
  4. 19
    0
      tests/050-if-defined.c
  5. 35
    0
      tests/051-if-relational.c

+ 45
- 0
glcpp-lex.l View File

@@ -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 {

+ 90
- 7
glcpp-parse.y View File

@@ -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
- 0
tests/049-if-expression-precedence.c View File

@@ -0,0 +1,6 @@
#if 1 + 2 * 3 + - (25 % 17 - + 1)
failure with operator precedence
#else
success
#endif


+ 19
- 0
tests/050-if-defined.c View 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
- 0
tests/051-if-relational.c View 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…
Cancel
Save