On 10/03/2011 05:03 PM, Eric Anholt wrote:
> From page 22 (28 of PDF) of GLSL 1.30 spec:
>     It is an error to provide a literal integer whose magnitude is too
>     large to store in a variable of matching signed or unsigned type.
> 
>     Unsigned integers have exactly 32 bits of precision.  Signed integers
>     use 32 bits, including a sign bit, in two's complement form.
> ---
> 
> Others read this as "0xffffffff" being a valid literal integer of -1,
> like in C, right?

I would assume so.  I suppose I could check other implementations, but
I'm not sure I care enough to bother.  It's completely reasonable.

>  src/glsl/glsl_lexer.ll |   38 ++++++++++++++++++++++++++++++--------
>  1 files changed, 30 insertions(+), 8 deletions(-)
> 
> diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll
> index cfd8926..b01dcde 100644
> --- a/src/glsl/glsl_lexer.ll
> +++ b/src/glsl/glsl_lexer.ll
> @@ -22,6 +22,7 @@
>   * DEALINGS IN THE SOFTWARE.
>   */
>  #include <ctype.h>
> +#include <limits.h>
>  #include "strtod.h"
>  #include "ast.h"
>  #include "glsl_parser_extras.h"
> @@ -43,8 +44,6 @@ static int classify_identifier(struct 
> _mesa_glsl_parse_state *, const char *);
>  
>  #define YY_USER_INIT yylineno = 0; yycolumn = 0;
>  
> -#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U')
> -
>  /* A macro for handling reserved words and keywords across language versions.
>   *
>   * Certain words start out as identifiers, become reserved words in
> @@ -81,6 +80,32 @@ static int classify_identifier(struct 
> _mesa_glsl_parse_state *, const char *);
>   * ...means the word is a legal keyword in GLSL ES 1.00.
>   */
>  #define ES yyextra->es_shader
> +
> +#define LITERAL_INTEGER(base)                                                
> \
> +do {                                                                 \

I might just use a function for this...

> +   bool is_uint = (yytext[yyleng - 1] == 'u' ||                              
> \
> +                yytext[yyleng - 1] == 'U');                          \
> +   const char *digits = yytext;                                              
> \
> +                                                                     \
> +   if (base == 16)                                                   \
> +      digits += 2;                                                   \
> +   long long value = strtoll(digits, NULL, base);                    \
> +                                                                     \
> +   yylval->n = (int)value;                                           \
> +                                                                     \
> +   if (value > UINT_MAX) {                                           \

Won't this give a signed/unsigned comparison warning?  I think this is
the right thing to do though.

> +      /* Note that signed 0xffffffff is valid, not out of range! */  \
> +      if (yyextra->language_version >= 130) {                                
> \
> +      _mesa_glsl_error(yylloc, yyextra,                              \
> +                       "Literal value `%s' out of range", yytext);   \
> +      } else {                                                               
> \
> +      _mesa_glsl_warning(yylloc, yyextra,                            \
> +                        "Literal value `%s' out of range", yytext);  \
> +      }                                                                      
> \
> +   }                                                                 \
> +   return is_uint ? UINTCONSTANT : INTCONSTANT;                              
> \
> +} while (0)
> +
>  %}
>  
>  %option bison-bridge bison-locations reentrant noyywrap
> @@ -292,16 +317,13 @@ layout          {
>  -=           return SUB_ASSIGN;
>  
>  [1-9][0-9]*[uU]?     {
> -                         yylval->n = strtol(yytext, NULL, 10);
> -                         return IS_UINT ? UINTCONSTANT : INTCONSTANT;
> +                         LITERAL_INTEGER(10);
>                       }
>  0[xX][0-9a-fA-F]+[uU]?       {
> -                         yylval->n = strtol(yytext + 2, NULL, 16);
> -                         return IS_UINT ? UINTCONSTANT : INTCONSTANT;
> +                         LITERAL_INTEGER(16);
>                       }
>  0[0-7]*[uU]?         {
> -                         yylval->n = strtol(yytext, NULL, 8);
> -                         return IS_UINT ? UINTCONSTANT : INTCONSTANT;
> +                         LITERAL_INTEGER(8);
>                       }
>  
>  [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]?        {
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to