d3dcompiler: Make declaration_statement return a list.
[wine] / dlls / d3dcompiler_43 / hlsl.y
1 /*
2  * HLSL parser
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2012 Matteo Bruni for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 %{
22 #include "config.h"
23 #include "wine/debug.h"
24
25 #include <stdio.h>
26
27 #include "d3dcompiler_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
30
31 int hlsl_lex(void);
32
33 struct hlsl_parse_ctx hlsl_ctx;
34
35 void hlsl_message(const char *fmt, ...)
36 {
37     va_list args;
38
39     va_start(args, fmt);
40     compilation_message(&hlsl_ctx.messages, fmt, args);
41     va_end(args);
42 }
43
44 static void hlsl_error(const char *s)
45 {
46     hlsl_message("Line %u: %s\n", hlsl_ctx.line_no, s);
47     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
48 }
49
50 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
51 {
52     TRACE("Line %u: ", line_no);
53     if (modifiers)
54         TRACE("%s ", debug_modifiers(modifiers));
55     TRACE("%s %s;\n", debug_hlsl_type(type), declname);
56 }
57
58 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
59 {
60     BOOL ret;
61
62     TRACE("Declaring variable %s.\n", decl->name);
63     if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
64     {
65         if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
66         {
67             decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
68                     ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
69         }
70     }
71     if (local)
72     {
73         DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
74                 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
75         if (invalid)
76         {
77             hlsl_message("Line %u: modifier '%s' invalid for local variables.\n",
78                     hlsl_ctx.line_no, debug_modifiers(invalid));
79             set_parse_status(&hlsl_ctx.status, PARSE_ERR);
80         }
81     }
82     ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
83     if (ret == FALSE)
84     {
85         struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
86
87         hlsl_message("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no, decl->name);
88         hlsl_message("Line %u: \"%s\" was previously declared here.\n", old->node.line, decl->name);
89         set_parse_status(&hlsl_ctx.status, PARSE_ERR);
90         return FALSE;
91     }
92     return TRUE;
93 }
94
95 static DWORD add_modifier(DWORD modifiers, DWORD mod)
96 {
97     if (modifiers & mod)
98     {
99         hlsl_message("Line %u: modifier '%s' already specified.\n",
100                      hlsl_ctx.line_no, debug_modifiers(mod));
101         set_parse_status(&hlsl_ctx.status, PARSE_ERR);
102         return modifiers;
103     }
104     if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
105             && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
106     {
107         hlsl_message("Line %u: more than one matrix majority keyword.\n",
108                 hlsl_ctx.line_no);
109         set_parse_status(&hlsl_ctx.status, PARSE_ERR);
110         return modifiers;
111     }
112     return modifiers | mod;
113 }
114
115 static unsigned int components_count_expr_list(struct list *list)
116 {
117     struct hlsl_ir_node *node;
118     unsigned int count = 0;
119
120     LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
121     {
122         count += components_count_type(node->data_type);
123     }
124     return count;
125 }
126
127 %}
128
129 %error-verbose
130
131 %union
132 {
133     struct hlsl_type *type;
134     INT intval;
135     FLOAT floatval;
136     BOOL boolval;
137     char *name;
138     DWORD modifiers;
139     struct hlsl_ir_var *var;
140     struct hlsl_ir_node *instr;
141     struct list *list;
142     struct hlsl_ir_function_decl *function;
143     struct parse_parameter parameter;
144     struct parse_variable_def *variable_def;
145 }
146
147 %token KW_BLENDSTATE
148 %token KW_BREAK
149 %token KW_BUFFER
150 %token KW_CBUFFER
151 %token KW_COLUMN_MAJOR
152 %token KW_COMPILE
153 %token KW_CONST
154 %token KW_CONTINUE
155 %token KW_DEPTHSTENCILSTATE
156 %token KW_DEPTHSTENCILVIEW
157 %token KW_DISCARD
158 %token KW_DO
159 %token KW_DOUBLE
160 %token KW_ELSE
161 %token KW_EXTERN
162 %token KW_FALSE
163 %token KW_FOR
164 %token KW_GEOMETRYSHADER
165 %token KW_GROUPSHARED
166 %token KW_IF
167 %token KW_IN
168 %token KW_INLINE
169 %token KW_INOUT
170 %token KW_MATRIX
171 %token KW_NAMESPACE
172 %token KW_NOINTERPOLATION
173 %token KW_OUT
174 %token KW_PASS
175 %token KW_PIXELSHADER
176 %token KW_PRECISE
177 %token KW_RASTERIZERSTATE
178 %token KW_RENDERTARGETVIEW
179 %token KW_RETURN
180 %token KW_REGISTER
181 %token KW_ROW_MAJOR
182 %token KW_SAMPLER
183 %token KW_SAMPLER1D
184 %token KW_SAMPLER2D
185 %token KW_SAMPLER3D
186 %token KW_SAMPLERCUBE
187 %token KW_SAMPLER_STATE
188 %token KW_SAMPLERCOMPARISONSTATE
189 %token KW_SHARED
190 %token KW_STATEBLOCK
191 %token KW_STATEBLOCK_STATE
192 %token KW_STATIC
193 %token KW_STRING
194 %token KW_STRUCT
195 %token KW_SWITCH
196 %token KW_TBUFFER
197 %token KW_TECHNIQUE
198 %token KW_TECHNIQUE10
199 %token KW_TEXTURE
200 %token KW_TEXTURE1D
201 %token KW_TEXTURE1DARRAY
202 %token KW_TEXTURE2D
203 %token KW_TEXTURE2DARRAY
204 %token KW_TEXTURE2DMS
205 %token KW_TEXTURE2DMSARRAY
206 %token KW_TEXTURE3D
207 %token KW_TEXTURE3DARRAY
208 %token KW_TEXTURECUBE
209 %token KW_TRUE
210 %token KW_TYPEDEF
211 %token KW_UNIFORM
212 %token KW_VECTOR
213 %token KW_VERTEXSHADER
214 %token KW_VOID
215 %token KW_VOLATILE
216 %token KW_WHILE
217
218 %token OP_INC
219 %token OP_DEC
220 %token OP_AND
221 %token OP_OR
222 %token OP_EQ
223 %token OP_LEFTSHIFT
224 %token OP_LEFTSHIFTASSIGN
225 %token OP_RIGHTSHIFT
226 %token OP_RIGHTSHIFTASSIGN
227 %token OP_ELLIPSIS
228 %token OP_LE
229 %token OP_GE
230 %token OP_NE
231 %token OP_ADDASSIGN
232 %token OP_SUBASSIGN
233 %token OP_MULASSIGN
234 %token OP_DIVASSIGN
235 %token OP_MODASSIGN
236 %token OP_ANDASSIGN
237 %token OP_ORASSIGN
238 %token OP_XORASSIGN
239 %token OP_UNKNOWN1
240 %token OP_UNKNOWN2
241 %token OP_UNKNOWN3
242 %token OP_UNKNOWN4
243
244 %token <intval> PRE_LINE
245
246 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
247 %type <name> any_identifier var_identifier
248 %token <name> STRING
249 %token <floatval> C_FLOAT
250 %token <intval> C_INTEGER
251 %type <boolval> boolean
252 %type <type> base_type
253 %type <type> type
254 %type <list> declaration_statement
255 %type <list> complex_initializer
256 %type <list> initializer_expr_list
257 %type <instr> initializer_expr
258 %type <modifiers> var_modifiers
259 %type <list> parameters
260 %type <list> param_list
261 %type <instr> expr
262 %type <var> variable
263 %type <intval> array
264 %type <list> statement
265 %type <list> statement_list
266 %type <list> compound_statement
267 %type <function> func_declaration
268 %type <function> func_prototype
269 %type <parameter> parameter
270 %type <name> semantic
271 %type <variable_def> variable_def
272 %type <list> variables_def
273 %type <instr> primary_expr
274 %type <instr> postfix_expr
275 %type <instr> unary_expr
276 %type <instr> mul_expr
277 %type <instr> add_expr
278 %type <instr> shift_expr
279 %type <instr> relational_expr
280 %type <instr> equality_expr
281 %type <instr> bitand_expr
282 %type <instr> bitxor_expr
283 %type <instr> bitor_expr
284 %type <instr> logicand_expr
285 %type <instr> logicor_expr
286 %type <instr> conditional_expr
287 %type <instr> assignment_expr
288 %type <list> expr_statement
289 %type <modifiers> input_mod
290 %%
291
292 hlsl_prog:                /* empty */
293                             {
294                             }
295                         | hlsl_prog func_declaration
296                             {
297                                 FIXME("Check that the function doesn't conflict with an already declared one.\n");
298                                 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
299                             }
300                         | hlsl_prog declaration_statement
301                             {
302                                 TRACE("Declaration statement parsed.\n");
303                             }
304                         | hlsl_prog preproc_directive
305                             {
306                             }
307
308 preproc_directive:        PRE_LINE STRING
309                             {
310                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
311                                 hlsl_ctx.line_no = $1;
312                                 d3dcompiler_free(hlsl_ctx.source_file);
313                                 hlsl_ctx.source_file = $2;
314                             }
315
316 any_identifier:           VAR_IDENTIFIER
317                         | TYPE_IDENTIFIER
318                         | NEW_IDENTIFIER
319
320 func_declaration:         func_prototype compound_statement
321                             {
322                                 TRACE("Function %s parsed.\n", $1->name);
323                                 $$ = $1;
324                                 $$->body = $2;
325                                 pop_scope(&hlsl_ctx);
326                             }
327                         | func_prototype ';'
328                             {
329                                 TRACE("Function prototype for %s.\n", $1->name);
330                                 $$ = $1;
331                                 pop_scope(&hlsl_ctx);
332                             }
333
334 func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
335                             {
336                                 $$ = new_func_decl($3, $2, $5);
337                                 if (!$$)
338                                 {
339                                     ERR("Out of memory.\n");
340                                     return -1;
341                                 }
342                                 $$->semantic = $7;
343                             }
344
345 compound_statement:       '{' '}'
346                             {
347                                 $$ = d3dcompiler_alloc(sizeof(*$$));
348                                 list_init($$);
349                             }
350                         | '{' scope_start statement_list '}'
351                             {
352                                 pop_scope(&hlsl_ctx);
353                                 $$ = $3;
354                             }
355
356 scope_start:              /* Empty */
357                             {
358                                 push_scope(&hlsl_ctx);
359                             }
360
361 var_identifier:           VAR_IDENTIFIER
362                         | NEW_IDENTIFIER
363
364 semantic:                 /* Empty */
365                             {
366                                 $$ = NULL;
367                             }
368                         | ':' any_identifier
369                             {
370                                 $$ = $2;
371                             }
372
373 parameters:               scope_start
374                             {
375                                 $$ = d3dcompiler_alloc(sizeof(*$$));
376                                 list_init($$);
377                             }
378                         | scope_start param_list
379                             {
380                                 $$ = $2;
381                             }
382
383 param_list:               parameter
384                             {
385                                 $$ = d3dcompiler_alloc(sizeof(*$$));
386                                 list_init($$);
387                                 if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
388                                 {
389                                     ERR("Error adding function parameter %s.\n", $1.name);
390                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
391                                     return -1;
392                                 }
393                             }
394                         | param_list ',' parameter
395                             {
396                                 $$ = $1;
397                                 if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
398                                 {
399                                     hlsl_message("Line %u: duplicate parameter %s.\n",
400                                             hlsl_ctx.line_no, $3.name);
401                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
402                                     return 1;
403                                 }
404                             }
405
406 parameter:                input_mod var_modifiers type any_identifier semantic
407                             {
408                                 $$.modifiers = $1;
409                                 $$.modifiers |= $2;
410                                 $$.type = $3;
411                                 $$.name = $4;
412                                 $$.semantic = $5;
413                             }
414
415 input_mod:                /* Empty */
416                             {
417                                 $$ = HLSL_MODIFIER_IN;
418                             }
419                         | KW_IN
420                             {
421                                 $$ = HLSL_MODIFIER_IN;
422                             }
423                         | KW_OUT
424                             {
425                                 $$ = HLSL_MODIFIER_OUT;
426                             }
427                         | KW_INOUT
428                             {
429                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
430                             }
431
432 type:                     base_type
433                             {
434                                 $$ = $1;
435                             }
436                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
437                             {
438                                 if ($3->type != HLSL_CLASS_SCALAR)
439                                 {
440                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
441                                             hlsl_ctx.line_no);
442                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
443                                     return 1;
444                                 }
445                                 if ($5 < 1 || $5 > 4)
446                                 {
447                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
448                                             hlsl_ctx.line_no);
449                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
450                                     return 1;
451                                 }
452
453                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
454                             }
455                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
456                             {
457                                 if ($3->type != HLSL_CLASS_SCALAR)
458                                 {
459                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
460                                             hlsl_ctx.line_no);
461                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
462                                     return 1;
463                                 }
464                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
465                                 {
466                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
467                                             hlsl_ctx.line_no);
468                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
469                                     return 1;
470                                 }
471
472                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
473                             }
474
475 base_type:                KW_VOID
476                             {
477                                 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
478                             }
479                         | KW_SAMPLER
480                             {
481                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
482                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
483                             }
484                         | KW_SAMPLER1D
485                             {
486                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
487                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
488                             }
489                         | KW_SAMPLER2D
490                             {
491                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
492                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
493                             }
494                         | KW_SAMPLER3D
495                             {
496                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
497                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
498                             }
499                         | KW_SAMPLERCUBE
500                             {
501                                 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
502                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
503                             }
504                         | TYPE_IDENTIFIER
505                             {
506                                 struct hlsl_type *type;
507
508                                 TRACE("Type %s.\n", $1);
509                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
510                                 $$ = type;
511                                 d3dcompiler_free($1);
512                             }
513                         | KW_STRUCT TYPE_IDENTIFIER
514                             {
515                                 struct hlsl_type *type;
516
517                                 TRACE("Struct type %s.\n", $2);
518                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
519                                 if (type->type != HLSL_CLASS_STRUCT)
520                                 {
521                                     hlsl_message("Line %u: redefining %s as a structure.\n",
522                                             hlsl_ctx.line_no, $2);
523                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
524                                 }
525                                 else
526                                 {
527                                     $$ = type;
528                                 }
529                                 d3dcompiler_free($2);
530                             }
531
532 declaration_statement:    declaration
533                             {
534                                 $$ = d3dcompiler_alloc(sizeof(*$$));
535                                 list_init($$);
536                             }
537
538 declaration:              var_modifiers type variables_def ';'
539                             {
540                                 struct parse_variable_def *v, *v_next;
541                                 struct hlsl_ir_var *var;
542                                 BOOL ret, local = TRUE;
543
544                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
545                                 {
546                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
547                                     var = d3dcompiler_alloc(sizeof(*var));
548                                     var->node.type = HLSL_IR_VAR;
549                                     if (v->array_size)
550                                         var->node.data_type = new_array_type($2, v->array_size);
551                                     else
552                                         var->node.data_type = $2;
553                                     var->name = v->name;
554                                     var->modifiers = $1;
555                                     var->semantic = v->semantic;
556                                     var->node.line = hlsl_ctx.line_no;
557                                     if (v->initializer)
558                                     {
559                                         FIXME("Variable with an initializer.\n");
560                                         free_instr_list(v->initializer);
561                                     }
562
563                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
564                                     {
565                                         var->modifiers |= HLSL_STORAGE_UNIFORM;
566                                         local = FALSE;
567                                     }
568
569                                     ret = declare_variable(var, local);
570                                     if (ret == FALSE)
571                                         free_declaration(var);
572                                     else
573                                         TRACE("Declared variable %s.\n", var->name);
574                                     d3dcompiler_free(v);
575                                 }
576                                 d3dcompiler_free($3);
577                             }
578
579 variables_def:            variable_def
580                             {
581                                 $$ = d3dcompiler_alloc(sizeof(*$$));
582                                 list_init($$);
583                                 list_add_head($$, &$1->entry);
584                             }
585                         | variables_def ',' variable_def
586                             {
587                                 $$ = $1;
588                                 list_add_tail($$, &$3->entry);
589                             }
590
591                           /* FIXME: Local variables can't have semantics. */
592 variable_def:             any_identifier array semantic
593                             {
594                                 $$ = d3dcompiler_alloc(sizeof(*$$));
595                                 $$->name = $1;
596                                 $$->array_size = $2;
597                                 $$->semantic = $3;
598                             }
599                         | any_identifier array semantic '=' complex_initializer
600                             {
601                                 TRACE("Declaration with initializer.\n");
602                                 $$ = d3dcompiler_alloc(sizeof(*$$));
603                                 $$->name = $1;
604                                 $$->array_size = $2;
605                                 $$->semantic = $3;
606                                 $$->initializer = $5;
607                             }
608
609 array:                    /* Empty */
610                             {
611                                 $$ = 0;
612                             }
613                         | '[' expr ']'
614                             {
615                                 FIXME("Array.\n");
616                                 $$ = 0;
617                                 free_instr($2);
618                             }
619
620 var_modifiers:            /* Empty */
621                             {
622                                 $$ = 0;
623                             }
624                         | KW_EXTERN var_modifiers
625                             {
626                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN);
627                             }
628                         | KW_NOINTERPOLATION var_modifiers
629                             {
630                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION);
631                             }
632                         | KW_PRECISE var_modifiers
633                             {
634                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE);
635                             }
636                         | KW_SHARED var_modifiers
637                             {
638                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED);
639                             }
640                         | KW_GROUPSHARED var_modifiers
641                             {
642                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED);
643                             }
644                         | KW_STATIC var_modifiers
645                             {
646                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC);
647                             }
648                         | KW_UNIFORM var_modifiers
649                             {
650                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM);
651                             }
652                         | KW_VOLATILE var_modifiers
653                             {
654                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE);
655                             }
656                         | KW_CONST var_modifiers
657                             {
658                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST);
659                             }
660                         | KW_ROW_MAJOR var_modifiers
661                             {
662                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR);
663                             }
664                         | KW_COLUMN_MAJOR var_modifiers
665                             {
666                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
667                             }
668
669 complex_initializer:      initializer_expr
670                             {
671                                 $$ = d3dcompiler_alloc(sizeof(*$$));
672                                 list_init($$);
673                                 list_add_head($$, &$1->entry);
674                             }
675                         | '{' initializer_expr_list '}'
676                             {
677                                 $$ = $2;
678                             }
679
680 initializer_expr:         assignment_expr
681                             {
682                                 $$ = $1;
683                             }
684
685 initializer_expr_list:    initializer_expr
686                             {
687                                 $$ = d3dcompiler_alloc(sizeof(*$$));
688                                 list_init($$);
689                                 list_add_head($$, &$1->entry);
690                             }
691                         | initializer_expr_list ',' initializer_expr
692                             {
693                                 $$ = $1;
694                                 list_add_tail($$, &$3->entry);
695                             }
696
697 boolean:                  KW_TRUE
698                             {
699                                 $$ = TRUE;
700                             }
701                         | KW_FALSE
702                             {
703                                 $$ = FALSE;
704                             }
705
706 statement_list:           statement
707                             {
708                                 $$ = $1;
709                             }
710                         | statement_list statement
711                             {
712                                 $$ = $1;
713                                 list_move_tail($$, $2);
714                                 d3dcompiler_free($2);
715                             }
716
717 statement:                declaration_statement
718                             {
719                                 $$ = $1;
720                             }
721                         | expr_statement
722                             {
723                                 $$ = $1;
724                             }
725                         | compound_statement
726                             {
727                                 $$ = $1;
728                             }
729
730 expr_statement:           ';'
731                             {
732                                 $$ = d3dcompiler_alloc(sizeof(*$$));
733                                 list_init($$);
734                             }
735                         | expr ';'
736                             {
737                                 $$ = d3dcompiler_alloc(sizeof(*$$));
738                                 list_init($$);
739                                 if ($1)
740                                     list_add_head($$, &$1->entry);
741                             }
742
743 primary_expr:             C_FLOAT
744                             {
745                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
746                                 if (!c)
747                                 {
748                                     ERR("Out of memory.\n");
749                                     return -1;
750                                 }
751                                 c->node.type = HLSL_IR_CONSTANT;
752                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
753                                 c->v.value.f[0] = $1;
754                                 $$ = &c->node;
755                             }
756                         | C_INTEGER
757                             {
758                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
759                                 if (!c)
760                                 {
761                                     ERR("Out of memory.\n");
762                                     return -1;
763                                 }
764                                 c->node.type = HLSL_IR_CONSTANT;
765                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
766                                 c->v.value.i[0] = $1;
767                                 $$ = &c->node;
768                             }
769                         | boolean
770                             {
771                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
772                                 if (!c)
773                                 {
774                                     ERR("Out of memory.\n");
775                                     return -1;
776                                 }
777                                 c->node.type = HLSL_IR_CONSTANT;
778                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
779                                 c->v.value.b[0] = $1;
780                                 $$ = &c->node;
781                             }
782                         | variable
783                             {
784                                 struct hlsl_ir_deref *deref = new_var_deref($1);
785                                 $$ = deref ? &deref->node : NULL;
786                             }
787                         | '(' expr ')'
788                             {
789                                 $$ = $2;
790                             }
791
792 variable:                 VAR_IDENTIFIER
793                             {
794                                 struct hlsl_ir_var *var;
795                                 var = get_variable(hlsl_ctx.cur_scope, $1);
796                                 if (!var)
797                                 {
798                                     hlsl_message("Line %d: variable '%s' not declared\n",
799                                             hlsl_ctx.line_no, $1);
800                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
801                                     return 1;
802                                 }
803                                 $$ = var;
804                             }
805
806 postfix_expr:             primary_expr
807                             {
808                                 $$ = $1;
809                             }
810                           /* "var_modifiers" doesn't make sense in this case, but it's needed
811                              in the grammar to avoid shift/reduce conflicts. */
812                         | var_modifiers type '(' initializer_expr_list ')'
813                             {
814                                 struct hlsl_ir_constructor *constructor;
815
816                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
817                                 if ($1)
818                                 {
819                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
820                                             hlsl_ctx.line_no);
821                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
822                                     return -1;
823                                 }
824                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
825                                 {
826                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
827                                             hlsl_ctx.line_no);
828                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
829                                     return -1;
830                                 }
831                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
832                                 {
833                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
834                                             hlsl_ctx.line_no);
835                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
836                                     return -1;
837                                 }
838
839                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
840                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
841                                 constructor->node.data_type = $2;
842                                 constructor->arguments = $4;
843
844                                 $$ = &constructor->node;
845                             }
846
847 unary_expr:               postfix_expr
848                             {
849                                 $$ = $1;
850                             }
851
852 mul_expr:                 unary_expr
853                             {
854                                 $$ = $1;
855                             }
856
857 add_expr:                 mul_expr
858                             {
859                                 $$ = $1;
860                             }
861
862 shift_expr:               add_expr
863                             {
864                                 $$ = $1;
865                             }
866
867 relational_expr:          shift_expr
868                             {
869                                 $$ = $1;
870                             }
871
872 equality_expr:            relational_expr
873                             {
874                                 $$ = $1;
875                             }
876
877 bitand_expr:              equality_expr
878                             {
879                                 $$ = $1;
880                             }
881
882 bitxor_expr:              bitand_expr
883                             {
884                                 $$ = $1;
885                             }
886
887 bitor_expr:               bitxor_expr
888                             {
889                                 $$ = $1;
890                             }
891
892 logicand_expr:            bitor_expr
893                             {
894                                 $$ = $1;
895                             }
896
897 logicor_expr:             logicand_expr
898                             {
899                                 $$ = $1;
900                             }
901
902 conditional_expr:         logicor_expr
903                             {
904                                 $$ = $1;
905                             }
906
907 assignment_expr:          conditional_expr
908                             {
909                                 $$ = $1;
910                             }
911
912 expr:                     assignment_expr
913                             {
914                                 $$ = $1;
915                             }
916                         | expr ',' assignment_expr
917                             {
918                                 FIXME("Comma expression\n");
919                             }
920
921 %%
922
923 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
924         const char *entrypoint, char **messages)
925 {
926     struct hlsl_ir_function_decl *function;
927     struct hlsl_scope *scope, *next_scope;
928     struct hlsl_type *hlsl_type, *next_type;
929     struct hlsl_ir_var *var, *next_var;
930
931     hlsl_ctx.status = PARSE_SUCCESS;
932     hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
933     hlsl_ctx.line_no = 1;
934     hlsl_ctx.source_file = d3dcompiler_strdup("");
935     hlsl_ctx.cur_scope = NULL;
936     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
937     list_init(&hlsl_ctx.scopes);
938     list_init(&hlsl_ctx.types);
939     list_init(&hlsl_ctx.functions);
940
941     push_scope(&hlsl_ctx);
942     hlsl_ctx.globals = hlsl_ctx.cur_scope;
943
944     hlsl_parse();
945
946     if (TRACE_ON(hlsl_parser))
947     {
948         struct hlsl_ir_function_decl *func;
949
950         TRACE("IR dump.\n");
951         LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
952         {
953             if (func->body)
954                 debug_dump_ir_function(func);
955         }
956     }
957
958     TRACE("Compilation status = %d\n", hlsl_ctx.status);
959     if (messages)
960     {
961         if (hlsl_ctx.messages.size)
962             *messages = hlsl_ctx.messages.string;
963         else
964             *messages = NULL;
965     }
966     else
967     {
968         if (hlsl_ctx.messages.capacity)
969             d3dcompiler_free(hlsl_ctx.messages.string);
970     }
971
972     d3dcompiler_free(hlsl_ctx.source_file);
973     TRACE("Freeing functions IR.\n");
974     LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
975         free_function(function);
976
977     TRACE("Freeing variables.\n");
978     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
979     {
980         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
981         {
982             free_declaration(var);
983         }
984         d3dcompiler_free(scope);
985     }
986
987     TRACE("Freeing types.\n");
988     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
989     {
990         free_hlsl_type(hlsl_type);
991     }
992
993     return NULL;
994 }