d3dcompiler: Parse constructors.
[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> complex_initializer
255 %type <list> initializer_expr_list
256 %type <instr> initializer_expr
257 %type <modifiers> var_modifiers
258 %type <list> parameters
259 %type <list> param_list
260 %type <instr> expr
261 %type <var> variable
262 %type <intval> array
263 %type <list> statement
264 %type <list> statement_list
265 %type <list> compound_statement
266 %type <function> func_declaration
267 %type <function> func_prototype
268 %type <parameter> parameter
269 %type <name> semantic
270 %type <variable_def> variable_def
271 %type <list> variables_def
272 %type <instr> primary_expr
273 %type <instr> postfix_expr
274 %type <instr> unary_expr
275 %type <instr> mul_expr
276 %type <instr> add_expr
277 %type <instr> shift_expr
278 %type <instr> relational_expr
279 %type <instr> equality_expr
280 %type <instr> bitand_expr
281 %type <instr> bitxor_expr
282 %type <instr> bitor_expr
283 %type <instr> logicand_expr
284 %type <instr> logicor_expr
285 %type <instr> conditional_expr
286 %type <instr> assignment_expr
287 %type <list> expr_statement
288 %type <modifiers> input_mod
289 %%
290
291 hlsl_prog:                /* empty */
292                             {
293                             }
294                         | hlsl_prog func_declaration
295                             {
296                                 FIXME("Check that the function doesn't conflict with an already declared one.\n");
297                                 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
298                             }
299                         | hlsl_prog declaration_statement
300                             {
301                                 TRACE("Declaration statement parsed.\n");
302                             }
303                         | hlsl_prog preproc_directive
304                             {
305                             }
306
307 preproc_directive:        PRE_LINE STRING
308                             {
309                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
310                                 hlsl_ctx.line_no = $1 - 1;
311                                 d3dcompiler_free(hlsl_ctx.source_file);
312                                 hlsl_ctx.source_file = $2;
313                             }
314
315 any_identifier:           VAR_IDENTIFIER
316                         | TYPE_IDENTIFIER
317                         | NEW_IDENTIFIER
318
319 func_declaration:         func_prototype compound_statement
320                             {
321                                 TRACE("Function %s parsed.\n", $1->name);
322                                 $$ = $1;
323                                 $$->body = $2;
324                                 pop_scope(&hlsl_ctx);
325                             }
326                         | func_prototype ';'
327                             {
328                                 TRACE("Function prototype for %s.\n", $1->name);
329                                 $$ = $1;
330                                 pop_scope(&hlsl_ctx);
331                             }
332
333 func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
334                             {
335                                 $$ = new_func_decl($3, $2, $5);
336                                 if (!$$)
337                                 {
338                                     ERR("Out of memory.\n");
339                                     return -1;
340                                 }
341                                 $$->semantic = $7;
342                             }
343
344 compound_statement:       '{' '}'
345                             {
346                                 $$ = d3dcompiler_alloc(sizeof(*$$));
347                                 list_init($$);
348                             }
349                         | '{' scope_start statement_list '}'
350                             {
351                                 pop_scope(&hlsl_ctx);
352                                 $$ = $3;
353                             }
354
355 scope_start:              /* Empty */
356                             {
357                                 push_scope(&hlsl_ctx);
358                             }
359
360 var_identifier:           VAR_IDENTIFIER
361                         | NEW_IDENTIFIER
362
363 semantic:                 /* Empty */
364                             {
365                                 $$ = NULL;
366                             }
367                         | ':' any_identifier
368                             {
369                                 $$ = $2;
370                             }
371
372 parameters:               scope_start
373                             {
374                                 $$ = d3dcompiler_alloc(sizeof(*$$));
375                                 list_init($$);
376                             }
377                         | scope_start param_list
378                             {
379                                 $$ = $2;
380                             }
381
382 param_list:               parameter
383                             {
384                                 $$ = d3dcompiler_alloc(sizeof(*$$));
385                                 list_init($$);
386                                 if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
387                                 {
388                                     ERR("Error adding function parameter %s.\n", $1.name);
389                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
390                                     return -1;
391                                 }
392                             }
393                         | param_list ',' parameter
394                             {
395                                 $$ = $1;
396                                 if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
397                                 {
398                                     hlsl_message("Line %u: duplicate parameter %s.\n",
399                                             hlsl_ctx.line_no, $3.name);
400                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
401                                     return 1;
402                                 }
403                             }
404
405 parameter:                input_mod var_modifiers type any_identifier semantic
406                             {
407                                 $$.modifiers = $1;
408                                 $$.modifiers |= $2;
409                                 $$.type = $3;
410                                 $$.name = $4;
411                                 $$.semantic = $5;
412                             }
413
414 input_mod:                /* Empty */
415                             {
416                                 $$ = HLSL_MODIFIER_IN;
417                             }
418                         | KW_IN
419                             {
420                                 $$ = HLSL_MODIFIER_IN;
421                             }
422                         | KW_OUT
423                             {
424                                 $$ = HLSL_MODIFIER_OUT;
425                             }
426                         | KW_INOUT
427                             {
428                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
429                             }
430
431 type:                     base_type
432                             {
433                                 $$ = $1;
434                             }
435                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
436                             {
437                                 if ($3->type != HLSL_CLASS_SCALAR)
438                                 {
439                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
440                                             hlsl_ctx.line_no);
441                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
442                                     return 1;
443                                 }
444                                 if ($5 < 1 || $5 > 4)
445                                 {
446                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
447                                             hlsl_ctx.line_no);
448                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
449                                     return 1;
450                                 }
451
452                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
453                             }
454                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
455                             {
456                                 if ($3->type != HLSL_CLASS_SCALAR)
457                                 {
458                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
459                                             hlsl_ctx.line_no);
460                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
461                                     return 1;
462                                 }
463                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
464                                 {
465                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
466                                             hlsl_ctx.line_no);
467                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
468                                     return 1;
469                                 }
470
471                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
472                             }
473
474 base_type:                KW_VOID
475                             {
476                                 $$ = new_hlsl_type("void", HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
477                             }
478                         | KW_SAMPLER
479                             {
480                                 $$ = new_hlsl_type("sampler", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
481                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
482                             }
483                         | KW_SAMPLER1D
484                             {
485                                 $$ = new_hlsl_type("sampler1D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
486                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
487                             }
488                         | KW_SAMPLER2D
489                             {
490                                 $$ = new_hlsl_type("sampler2D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
491                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
492                             }
493                         | KW_SAMPLER3D
494                             {
495                                 $$ = new_hlsl_type("sampler3D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
496                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
497                             }
498                         | KW_SAMPLERCUBE
499                             {
500                                 $$ = new_hlsl_type("samplerCUBE", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
501                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
502                             }
503                         | TYPE_IDENTIFIER
504                             {
505                                 struct hlsl_type *type;
506
507                                 TRACE("Type %s.\n", $1);
508                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
509                                 $$ = type;
510                                 d3dcompiler_free($1);
511                             }
512                         | KW_STRUCT TYPE_IDENTIFIER
513                             {
514                                 struct hlsl_type *type;
515
516                                 TRACE("Struct type %s.\n", $2);
517                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
518                                 if (type->type != HLSL_CLASS_STRUCT)
519                                 {
520                                     hlsl_message("Line %u: redefining %s as a structure.\n",
521                                             hlsl_ctx.line_no, $2);
522                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
523                                 }
524                                 else
525                                 {
526                                     $$ = type;
527                                 }
528                                 d3dcompiler_free($2);
529                             }
530
531 declaration_statement:    declaration
532                             {
533                             }
534
535 declaration:              var_modifiers type variables_def ';'
536                             {
537                                 struct parse_variable_def *v, *v_next;
538                                 struct hlsl_ir_var *var;
539                                 BOOL ret, local = TRUE;
540
541                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
542                                 {
543                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
544                                     var = d3dcompiler_alloc(sizeof(*var));
545                                     var->node.type = HLSL_IR_VAR;
546                                     if (v->array_size)
547                                         var->node.data_type = new_array_type($2, v->array_size);
548                                     else
549                                         var->node.data_type = $2;
550                                     var->name = v->name;
551                                     var->modifiers = $1;
552                                     var->semantic = v->semantic;
553                                     var->node.line = hlsl_ctx.line_no;
554                                     if (v->initializer)
555                                     {
556                                         FIXME("Variable with an initializer.\n");
557                                         free_instr_list(v->initializer);
558                                     }
559
560                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
561                                     {
562                                         var->modifiers |= HLSL_STORAGE_UNIFORM;
563                                         local = FALSE;
564                                     }
565
566                                     ret = declare_variable(var, local);
567                                     if (ret == FALSE)
568                                         free_declaration(var);
569                                     else
570                                         TRACE("Declared variable %s.\n", var->name);
571                                     d3dcompiler_free(v);
572                                 }
573                                 d3dcompiler_free($3);
574                             }
575
576 variables_def:            variable_def
577                             {
578                                 $$ = d3dcompiler_alloc(sizeof(*$$));
579                                 list_init($$);
580                                 list_add_head($$, &$1->entry);
581                             }
582                         | variables_def ',' variable_def
583                             {
584                                 $$ = $1;
585                                 list_add_tail($$, &$3->entry);
586                             }
587
588                           /* FIXME: Local variables can't have semantics. */
589 variable_def:             any_identifier array semantic
590                             {
591                                 $$ = d3dcompiler_alloc(sizeof(*$$));
592                                 $$->name = $1;
593                                 $$->array_size = $2;
594                                 $$->semantic = $3;
595                             }
596                         | any_identifier array semantic '=' complex_initializer
597                             {
598                                 TRACE("Declaration with initializer.\n");
599                                 $$ = d3dcompiler_alloc(sizeof(*$$));
600                                 $$->name = $1;
601                                 $$->array_size = $2;
602                                 $$->semantic = $3;
603                                 $$->initializer = $5;
604                             }
605
606 array:                    /* Empty */
607                             {
608                                 $$ = 0;
609                             }
610                         | '[' expr ']'
611                             {
612                                 FIXME("Array.\n");
613                                 $$ = 0;
614                                 free_instr($2);
615                             }
616
617 var_modifiers:            /* Empty */
618                             {
619                                 $$ = 0;
620                             }
621                         | KW_EXTERN var_modifiers
622                             {
623                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN);
624                             }
625                         | KW_NOINTERPOLATION var_modifiers
626                             {
627                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION);
628                             }
629                         | KW_PRECISE var_modifiers
630                             {
631                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE);
632                             }
633                         | KW_SHARED var_modifiers
634                             {
635                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED);
636                             }
637                         | KW_GROUPSHARED var_modifiers
638                             {
639                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED);
640                             }
641                         | KW_STATIC var_modifiers
642                             {
643                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC);
644                             }
645                         | KW_UNIFORM var_modifiers
646                             {
647                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM);
648                             }
649                         | KW_VOLATILE var_modifiers
650                             {
651                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE);
652                             }
653                         | KW_CONST var_modifiers
654                             {
655                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST);
656                             }
657                         | KW_ROW_MAJOR var_modifiers
658                             {
659                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR);
660                             }
661                         | KW_COLUMN_MAJOR var_modifiers
662                             {
663                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
664                             }
665
666 complex_initializer:      initializer_expr
667                             {
668                                 $$ = d3dcompiler_alloc(sizeof(*$$));
669                                 list_init($$);
670                                 list_add_head($$, &$1->entry);
671                             }
672                         | '{' initializer_expr_list '}'
673                             {
674                                 $$ = $2;
675                             }
676
677 initializer_expr:         assignment_expr
678                             {
679                                 $$ = $1;
680                             }
681
682 initializer_expr_list:    initializer_expr
683                             {
684                                 $$ = d3dcompiler_alloc(sizeof(*$$));
685                                 list_init($$);
686                                 list_add_head($$, &$1->entry);
687                             }
688                         | initializer_expr_list ',' initializer_expr
689                             {
690                                 $$ = $1;
691                                 list_add_tail($$, &$3->entry);
692                             }
693
694 boolean:                  KW_TRUE
695                             {
696                                 $$ = TRUE;
697                             }
698                         | KW_FALSE
699                             {
700                                 $$ = FALSE;
701                             }
702
703 statement_list:           statement
704                             {
705                                 $$ = $1;
706                             }
707                         | statement_list statement
708                             {
709                                 $$ = $1;
710                                 list_move_tail($$, $2);
711                                 d3dcompiler_free($2);
712                             }
713
714 statement:                declaration_statement
715                             {
716                                 $$ = d3dcompiler_alloc(sizeof(*$$));
717                                 list_init($$);
718                             }
719                         | expr_statement
720                             {
721                                 $$ = $1;
722                             }
723                         | compound_statement
724                             {
725                                 $$ = $1;
726                             }
727
728 expr_statement:           ';'
729                             {
730                                 $$ = d3dcompiler_alloc(sizeof(*$$));
731                                 list_init($$);
732                             }
733                         | expr ';'
734                             {
735                                 $$ = d3dcompiler_alloc(sizeof(*$$));
736                                 list_init($$);
737                                 if ($1)
738                                     list_add_head($$, &$1->entry);
739                             }
740
741 primary_expr:             C_FLOAT
742                             {
743                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
744                                 if (!c)
745                                 {
746                                     ERR("Out of memory.\n");
747                                     return -1;
748                                 }
749                                 c->node.type = HLSL_IR_CONSTANT;
750                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
751                                 c->v.value.f[0] = $1;
752                                 $$ = &c->node;
753                             }
754                         | C_INTEGER
755                             {
756                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
757                                 if (!c)
758                                 {
759                                     ERR("Out of memory.\n");
760                                     return -1;
761                                 }
762                                 c->node.type = HLSL_IR_CONSTANT;
763                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
764                                 c->v.value.i[0] = $1;
765                                 $$ = &c->node;
766                             }
767                         | boolean
768                             {
769                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
770                                 if (!c)
771                                 {
772                                     ERR("Out of memory.\n");
773                                     return -1;
774                                 }
775                                 c->node.type = HLSL_IR_CONSTANT;
776                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
777                                 c->v.value.b[0] = $1;
778                                 $$ = &c->node;
779                             }
780                         | variable
781                             {
782                                 struct hlsl_ir_deref *deref = new_var_deref($1);
783                                 $$ = deref ? &deref->node : NULL;
784                             }
785                         | '(' expr ')'
786                             {
787                                 $$ = $2;
788                             }
789
790 variable:                 VAR_IDENTIFIER
791                             {
792                                 struct hlsl_ir_var *var;
793                                 var = get_variable(hlsl_ctx.cur_scope, $1);
794                                 if (!var)
795                                 {
796                                     hlsl_message("Line %d: variable '%s' not declared\n",
797                                             hlsl_ctx.line_no, $1);
798                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
799                                     return 1;
800                                 }
801                                 $$ = var;
802                             }
803
804 postfix_expr:             primary_expr
805                             {
806                                 $$ = $1;
807                             }
808                           /* "var_modifiers" doesn't make sense in this case, but it's needed
809                              in the grammar to avoid shift/reduce conflicts. */
810                         | var_modifiers type '(' initializer_expr_list ')'
811                             {
812                                 struct hlsl_ir_constructor *constructor;
813
814                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
815                                 if ($1)
816                                 {
817                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
818                                             hlsl_ctx.line_no);
819                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
820                                     return -1;
821                                 }
822                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
823                                 {
824                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
825                                             hlsl_ctx.line_no);
826                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
827                                     return -1;
828                                 }
829                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
830                                 {
831                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
832                                             hlsl_ctx.line_no);
833                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
834                                     return -1;
835                                 }
836
837                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
838                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
839                                 constructor->node.data_type = $2;
840                                 constructor->arguments = $4;
841
842                                 $$ = &constructor->node;
843                             }
844
845 unary_expr:               postfix_expr
846                             {
847                                 $$ = $1;
848                             }
849
850 mul_expr:                 unary_expr
851                             {
852                                 $$ = $1;
853                             }
854
855 add_expr:                 mul_expr
856                             {
857                                 $$ = $1;
858                             }
859
860 shift_expr:               add_expr
861                             {
862                                 $$ = $1;
863                             }
864
865 relational_expr:          shift_expr
866                             {
867                                 $$ = $1;
868                             }
869
870 equality_expr:            relational_expr
871                             {
872                                 $$ = $1;
873                             }
874
875 bitand_expr:              equality_expr
876                             {
877                                 $$ = $1;
878                             }
879
880 bitxor_expr:              bitand_expr
881                             {
882                                 $$ = $1;
883                             }
884
885 bitor_expr:               bitxor_expr
886                             {
887                                 $$ = $1;
888                             }
889
890 logicand_expr:            bitor_expr
891                             {
892                                 $$ = $1;
893                             }
894
895 logicor_expr:             logicand_expr
896                             {
897                                 $$ = $1;
898                             }
899
900 conditional_expr:         logicor_expr
901                             {
902                                 $$ = $1;
903                             }
904
905 assignment_expr:          conditional_expr
906                             {
907                                 $$ = $1;
908                             }
909
910 expr:                     assignment_expr
911                             {
912                                 $$ = $1;
913                             }
914                         | expr ',' assignment_expr
915                             {
916                                 FIXME("Comma expression\n");
917                             }
918
919 %%
920
921 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
922 {
923     struct hlsl_ir_function_decl *function;
924     struct hlsl_scope *scope, *next_scope;
925     struct hlsl_type *hlsl_type, *next_type;
926     struct hlsl_ir_var *var, *next_var;
927
928     hlsl_ctx.line_no = 1;
929     hlsl_ctx.source_file = d3dcompiler_strdup("");
930     hlsl_ctx.cur_scope = NULL;
931     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
932     list_init(&hlsl_ctx.scopes);
933     list_init(&hlsl_ctx.types);
934     list_init(&hlsl_ctx.functions);
935
936     push_scope(&hlsl_ctx);
937     hlsl_ctx.globals = hlsl_ctx.cur_scope;
938
939     hlsl_parse();
940
941     if (TRACE_ON(hlsl_parser))
942     {
943         struct hlsl_ir_function_decl *func;
944
945         TRACE("IR dump.\n");
946         LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
947         {
948             if (func->body)
949                 debug_dump_ir_function(func);
950         }
951     }
952
953     d3dcompiler_free(hlsl_ctx.source_file);
954     TRACE("Freeing functions IR.\n");
955     LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
956         free_function(function);
957
958     TRACE("Freeing variables.\n");
959     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
960     {
961         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
962         {
963             free_declaration(var);
964         }
965         d3dcompiler_free(scope);
966     }
967
968     TRACE("Freeing types.\n");
969     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
970     {
971         free_hlsl_type(hlsl_type);
972     }
973
974     return NULL;
975 }