diff options
author | Ian Romanick <[email protected]> | 2010-04-07 16:46:25 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-04-07 16:49:25 -0700 |
commit | e701761cc84a136c2e1b3cf341bc0edb90492278 (patch) | |
tree | 808b619ec9bb320eaf77b5343c2dbdc8da8ab3b2 | |
parent | ae4c4c07959f059e557ea44e98552ced1fec9f47 (diff) |
Begin processing #extension directive
Nowhere near complete. It just parses correctly at this point.
-rw-r--r-- | glsl_parser.ypp | 18 | ||||
-rw-r--r-- | glsl_parser_extras.cpp | 47 | ||||
-rw-r--r-- | glsl_parser_extras.h | 12 |
3 files changed, 75 insertions, 2 deletions
diff --git a/glsl_parser.ypp b/glsl_parser.ypp index b8c01b508d0..250c51c7ee3 100644 --- a/glsl_parser.ypp +++ b/glsl_parser.ypp @@ -190,13 +190,13 @@ translation_unit: { _mesa_glsl_initialize_types(state); } - external_declaration_list + extension_statement_list external_declaration_list | { state->language_version = 110; _mesa_glsl_initialize_types(state); } - external_declaration_list + extension_statement_list external_declaration_list ; version_statement: @@ -217,6 +217,20 @@ version_statement: } ; +extension_statement_list: + + | extension_statement_list extension_statement + ; + +extension_statement: + EXTENSION IDENTIFIER COLON IDENTIFIER EOL + { + if (!_mesa_glsl_process_extension($2, & @2, $4, & @4, state)) { + YYERROR; + } + } + ; + external_declaration_list: external_declaration { diff --git a/glsl_parser_extras.cpp b/glsl_parser_extras.cpp index 335a058b965..1eac1890afe 100644 --- a/glsl_parser_extras.cpp +++ b/glsl_parser_extras.cpp @@ -71,6 +71,53 @@ _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, } +bool +_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, + const char *behavior, YYLTYPE *behavior_locp, + _mesa_glsl_parse_state *state) +{ + enum { + extension_disable, + extension_enable, + extension_require, + extension_warn + } ext_mode; + bool error = false; + + if (strcmp(behavior, "warn") == 0) { + ext_mode = extension_warn; + } else if (strcmp(behavior, "require") == 0) { + ext_mode = extension_require; + } else if (strcmp(behavior, "enable") == 0) { + ext_mode = extension_enable; + } else if (strcmp(behavior, "disable") == 0) { + ext_mode = extension_disable; + } else { + _mesa_glsl_error(behavior_locp, state, + "Unknown extension behavior `%s'", + behavior); + return false; + } + + if (strcmp(name, "all") == 0) { + if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { + _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", + (ext_mode == extension_enable) + ? "enable" : "require"); + return false; + } + } else { + if (ext_mode == extension_require) { + _mesa_glsl_error(name_locp, state, "Unknown extension `%s'", + name); + return false; + } + } + + return true; +} + + ast_node::~ast_node() { /* empty */ diff --git a/glsl_parser_extras.h b/glsl_parser_extras.h index 2f33bea0534..15667ebb689 100644 --- a/glsl_parser_extras.h +++ b/glsl_parser_extras.h @@ -86,6 +86,18 @@ extern int _mesa_glsl_lex(union YYSTYPE *yylval, YYLTYPE *yylloc, extern int _mesa_glsl_parse(struct _mesa_glsl_parse_state *); /** + * Process elements of the #extension directive + * + * \return + * If \c name and \c behavior are valid, \c true is returned. Otherwise + * \c false is returned. + */ +extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, + const char *behavior, + YYLTYPE *behavior_locp, + _mesa_glsl_parse_state *state); + +/** * Get the textual name of the specified shader target */ extern const char * |