glsl: Add support for C-style initializers.
[mesa.git] / src / glsl / glsl_parser.yy
index afbafce4cba449c5b2b9b31516c628f3025395f2..78f5bf6f4f2038e318e09f2b27a9c4713136b278 100644 (file)
@@ -221,6 +221,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
 %type <declarator_list> init_declarator_list
 %type <declarator_list> single_declaration
 %type <expression> initializer
+%type <expression> initializer_list
 %type <node> declaration
 %type <node> declaration_statement
 %type <node> jump_statement
@@ -961,6 +962,11 @@ init_declarator_list:
           $$ = $1;
           $$->declarations.push_tail(&decl->link);
           state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+          if ($7->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$7;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, NULL);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | init_declarator_list ',' any_identifier '[' constant_expression ']' '=' initializer
        {
@@ -971,6 +977,11 @@ init_declarator_list:
           $$ = $1;
           $$->declarations.push_tail(&decl->link);
           state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+          if ($8->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$8;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->type->specifier, true, $5);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | init_declarator_list ',' any_identifier '=' initializer
        {
@@ -981,6 +992,10 @@ init_declarator_list:
           $$ = $1;
           $$->declarations.push_tail(&decl->link);
           state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+          if ($5->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$5;
+             _mesa_ast_set_aggregate_type($1->type->specifier, ai, state);
+          }
        }
        ;
 
@@ -1028,6 +1043,11 @@ single_declaration:
           $$ = new(ctx) ast_declarator_list($1);
           $$->set_location(yylloc);
           $$->declarations.push_tail(&decl->link);
+          if ($6->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$6;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, NULL);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | fully_specified_type any_identifier '[' constant_expression ']' '=' initializer
        {
@@ -1037,6 +1057,11 @@ single_declaration:
           $$ = new(ctx) ast_declarator_list($1);
           $$->set_location(yylloc);
           $$->declarations.push_tail(&decl->link);
+          if ($7->oper == ast_aggregate) {
+             ast_aggregate_initializer *ai = (ast_aggregate_initializer *)$7;
+             ast_type_specifier *type = new(ctx) ast_type_specifier($1->specifier, true, $4);
+             _mesa_ast_set_aggregate_type(type, ai, state);
+          }
        }
        | fully_specified_type any_identifier '=' initializer
        {
@@ -1046,6 +1071,9 @@ single_declaration:
           $$ = new(ctx) ast_declarator_list($1);
           $$->set_location(yylloc);
           $$->declarations.push_tail(&decl->link);
+          if ($4->oper == ast_aggregate) {
+              _mesa_ast_set_aggregate_type($1->specifier, $4, state);
+          }
        }
        | INVARIANT variable_identifier // Vertex only.
        {
@@ -1506,6 +1534,7 @@ struct_specifier:
           $$ = new(ctx) ast_struct_specifier($2, $4);
           $$->set_location(yylloc);
           state->symbols->add_type($2, glsl_type::void_type);
+           state->symbols->add_type_ast($2, new(ctx) ast_type_specifier($$));
        }
        | STRUCT '{' struct_declaration_list '}'
        {
@@ -1573,6 +1602,28 @@ struct_declarator:
 
 initializer:
        assignment_expression
+       | '{' initializer_list '}'
+       {
+          $$ = $2;
+       }
+       | '{' initializer_list ',' '}'
+       {
+          $$ = $2;
+       }
+       ;
+
+initializer_list:
+       initializer
+       {
+          void *ctx = state;
+          $$ = new(ctx) ast_aggregate_initializer();
+          $$->set_location(yylloc);
+          $$->expressions.push_tail(& $1->link);
+       }
+       | initializer_list ',' initializer
+       {
+          $1->expressions.push_tail(& $3->link);
+       }
        ;
 
 declaration_statement: