d3dcompiler: Parse sampler declarations.
[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 %}
116
117 %error-verbose
118
119 %union
120 {
121     struct hlsl_type *type;
122     INT intval;
123     FLOAT floatval;
124     BOOL boolval;
125     char *name;
126     DWORD modifiers;
127     struct hlsl_ir_var *var;
128     struct hlsl_ir_node *instr;
129     struct list *list;
130     struct parse_variable_def *variable_def;
131 }
132
133 %token KW_BLENDSTATE
134 %token KW_BREAK
135 %token KW_BUFFER
136 %token KW_CBUFFER
137 %token KW_COLUMN_MAJOR
138 %token KW_COMPILE
139 %token KW_CONST
140 %token KW_CONTINUE
141 %token KW_DEPTHSTENCILSTATE
142 %token KW_DEPTHSTENCILVIEW
143 %token KW_DISCARD
144 %token KW_DO
145 %token KW_DOUBLE
146 %token KW_ELSE
147 %token KW_EXTERN
148 %token KW_FALSE
149 %token KW_FOR
150 %token KW_GEOMETRYSHADER
151 %token KW_GROUPSHARED
152 %token KW_IF
153 %token KW_IN
154 %token KW_INLINE
155 %token KW_INOUT
156 %token KW_MATRIX
157 %token KW_NAMESPACE
158 %token KW_NOINTERPOLATION
159 %token KW_OUT
160 %token KW_PASS
161 %token KW_PIXELSHADER
162 %token KW_PRECISE
163 %token KW_RASTERIZERSTATE
164 %token KW_RENDERTARGETVIEW
165 %token KW_RETURN
166 %token KW_REGISTER
167 %token KW_ROW_MAJOR
168 %token KW_SAMPLER
169 %token KW_SAMPLER1D
170 %token KW_SAMPLER2D
171 %token KW_SAMPLER3D
172 %token KW_SAMPLERCUBE
173 %token KW_SAMPLER_STATE
174 %token KW_SAMPLERCOMPARISONSTATE
175 %token KW_SHARED
176 %token KW_STATEBLOCK
177 %token KW_STATEBLOCK_STATE
178 %token KW_STATIC
179 %token KW_STRING
180 %token KW_STRUCT
181 %token KW_SWITCH
182 %token KW_TBUFFER
183 %token KW_TECHNIQUE
184 %token KW_TECHNIQUE10
185 %token KW_TEXTURE
186 %token KW_TEXTURE1D
187 %token KW_TEXTURE1DARRAY
188 %token KW_TEXTURE2D
189 %token KW_TEXTURE2DARRAY
190 %token KW_TEXTURE2DMS
191 %token KW_TEXTURE2DMSARRAY
192 %token KW_TEXTURE3D
193 %token KW_TEXTURE3DARRAY
194 %token KW_TEXTURECUBE
195 %token KW_TRUE
196 %token KW_TYPEDEF
197 %token KW_UNIFORM
198 %token KW_VECTOR
199 %token KW_VERTEXSHADER
200 %token KW_VOID
201 %token KW_VOLATILE
202 %token KW_WHILE
203
204 %token OP_INC
205 %token OP_DEC
206 %token OP_AND
207 %token OP_OR
208 %token OP_EQ
209 %token OP_LEFTSHIFT
210 %token OP_LEFTSHIFTASSIGN
211 %token OP_RIGHTSHIFT
212 %token OP_RIGHTSHIFTASSIGN
213 %token OP_ELLIPSIS
214 %token OP_LE
215 %token OP_GE
216 %token OP_NE
217 %token OP_ADDASSIGN
218 %token OP_SUBASSIGN
219 %token OP_MULASSIGN
220 %token OP_DIVASSIGN
221 %token OP_MODASSIGN
222 %token OP_ANDASSIGN
223 %token OP_ORASSIGN
224 %token OP_XORASSIGN
225 %token OP_UNKNOWN1
226 %token OP_UNKNOWN2
227 %token OP_UNKNOWN3
228 %token OP_UNKNOWN4
229
230 %token <intval> PRE_LINE
231
232 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
233 %type <name> any_identifier
234 %token <name> STRING
235 %token <floatval> C_FLOAT
236 %token <intval> C_INTEGER
237 %type <boolval> boolean
238 %type <type> base_type
239 %type <type> type
240 %type <list> complex_initializer
241 %type <list> initializer_expr_list
242 %type <instr> initializer_expr
243 %type <modifiers> var_modifiers
244 %type <instr> expr
245 %type <var> variable
246 %type <intval> array
247 %type <name> semantic
248 %type <variable_def> variable_def
249 %type <list> variables_def
250 %type <instr> primary_expr
251 %type <instr> postfix_expr
252 %type <instr> unary_expr
253 %type <instr> mul_expr
254 %type <instr> add_expr
255 %type <instr> shift_expr
256 %type <instr> relational_expr
257 %type <instr> equality_expr
258 %type <instr> bitand_expr
259 %type <instr> bitxor_expr
260 %type <instr> bitor_expr
261 %type <instr> logicand_expr
262 %type <instr> logicor_expr
263 %type <instr> conditional_expr
264 %type <instr> assignment_expr
265 %%
266
267 hlsl_prog:                /* empty */
268                             {
269                             }
270                         | hlsl_prog declaration_statement
271                             {
272                                 TRACE("Declaration statement parsed.\n");
273                             }
274                         | hlsl_prog preproc_directive
275                             {
276                             }
277
278 preproc_directive:        PRE_LINE STRING
279                             {
280                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
281                                 hlsl_ctx.line_no = $1 - 1;
282                                 d3dcompiler_free(hlsl_ctx.source_file);
283                                 hlsl_ctx.source_file = $2;
284                             }
285
286 any_identifier:           VAR_IDENTIFIER
287                         | TYPE_IDENTIFIER
288                         | NEW_IDENTIFIER
289
290 semantic:                 /* Empty */
291                             {
292                                 $$ = NULL;
293                             }
294                         | ':' any_identifier
295                             {
296                                 $$ = $2;
297                             }
298
299 type:                     base_type
300                             {
301                                 $$ = $1;
302                             }
303                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
304                             {
305                                 if ($3->type != HLSL_CLASS_SCALAR)
306                                 {
307                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
308                                             hlsl_ctx.line_no);
309                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
310                                     return 1;
311                                 }
312                                 if ($5 < 1 || $5 > 4)
313                                 {
314                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
315                                             hlsl_ctx.line_no);
316                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
317                                     return 1;
318                                 }
319
320                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
321                             }
322                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
323                             {
324                                 if ($3->type != HLSL_CLASS_SCALAR)
325                                 {
326                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
327                                             hlsl_ctx.line_no);
328                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
329                                     return 1;
330                                 }
331                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
332                                 {
333                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
334                                             hlsl_ctx.line_no);
335                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
336                                     return 1;
337                                 }
338
339                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
340                             }
341
342 base_type:                KW_VOID
343                             {
344                                 $$ = new_hlsl_type("void", HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
345                             }
346                         | KW_SAMPLER
347                             {
348                                 $$ = new_hlsl_type("sampler", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
349                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
350                             }
351                         | KW_SAMPLER1D
352                             {
353                                 $$ = new_hlsl_type("sampler1D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
354                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
355                             }
356                         | KW_SAMPLER2D
357                             {
358                                 $$ = new_hlsl_type("sampler2D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
359                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
360                             }
361                         | KW_SAMPLER3D
362                             {
363                                 $$ = new_hlsl_type("sampler3D", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
364                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
365                             }
366                         | KW_SAMPLERCUBE
367                             {
368                                 $$ = new_hlsl_type("samplerCUBE", HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
369                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
370                             }
371                         | TYPE_IDENTIFIER
372                             {
373                                 struct hlsl_type *type;
374
375                                 TRACE("Type %s.\n", $1);
376                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
377                                 $$ = type;
378                                 d3dcompiler_free($1);
379                             }
380                         | KW_STRUCT TYPE_IDENTIFIER
381                             {
382                                 struct hlsl_type *type;
383
384                                 TRACE("Struct type %s.\n", $2);
385                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
386                                 if (type->type != HLSL_CLASS_STRUCT)
387                                 {
388                                     hlsl_message("Line %u: redefining %s as a structure.\n",
389                                             hlsl_ctx.line_no, $2);
390                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
391                                 }
392                                 else
393                                 {
394                                     $$ = type;
395                                 }
396                                 d3dcompiler_free($2);
397                             }
398
399 declaration_statement:    declaration
400                             {
401                             }
402
403 declaration:              var_modifiers type variables_def ';'
404                             {
405                                 struct parse_variable_def *v, *v_next;
406                                 struct hlsl_ir_var *var;
407                                 BOOL ret, local = TRUE;
408
409                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
410                                 {
411                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
412                                     var = d3dcompiler_alloc(sizeof(*var));
413                                     var->node.type = HLSL_IR_VAR;
414                                     if (v->array_size)
415                                         var->node.data_type = new_array_type($2, v->array_size);
416                                     else
417                                         var->node.data_type = $2;
418                                     var->name = v->name;
419                                     var->modifiers = $1;
420                                     var->semantic = v->semantic;
421                                     var->node.line = hlsl_ctx.line_no;
422                                     if (v->initializer)
423                                     {
424                                         FIXME("Variable with an initializer.\n");
425                                         free_instr_list(v->initializer);
426                                     }
427
428                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
429                                     {
430                                         var->modifiers |= HLSL_STORAGE_UNIFORM;
431                                         local = FALSE;
432                                     }
433
434                                     ret = declare_variable(var, local);
435                                     if (ret == FALSE)
436                                         free_declaration(var);
437                                     else
438                                         TRACE("Declared variable %s.\n", var->name);
439                                     d3dcompiler_free(v);
440                                 }
441                                 d3dcompiler_free($3);
442                             }
443
444 variables_def:            variable_def
445                             {
446                                 $$ = d3dcompiler_alloc(sizeof(*$$));
447                                 list_init($$);
448                                 list_add_head($$, &$1->entry);
449                             }
450                         | variables_def ',' variable_def
451                             {
452                                 $$ = $1;
453                                 list_add_tail($$, &$3->entry);
454                             }
455
456                           /* FIXME: Local variables can't have semantics. */
457 variable_def:             any_identifier array semantic
458                             {
459                                 $$ = d3dcompiler_alloc(sizeof(*$$));
460                                 $$->name = $1;
461                                 $$->array_size = $2;
462                                 $$->semantic = $3;
463                             }
464                         | any_identifier array semantic '=' complex_initializer
465                             {
466                                 TRACE("Declaration with initializer.\n");
467                                 $$ = d3dcompiler_alloc(sizeof(*$$));
468                                 $$->name = $1;
469                                 $$->array_size = $2;
470                                 $$->semantic = $3;
471                                 $$->initializer = $5;
472                             }
473
474 array:                    /* Empty */
475                             {
476                                 $$ = 0;
477                             }
478                         | '[' expr ']'
479                             {
480                                 FIXME("Array.\n");
481                                 $$ = 0;
482                                 free_instr($2);
483                             }
484
485 var_modifiers:            /* Empty */
486                             {
487                                 $$ = 0;
488                             }
489                         | KW_EXTERN var_modifiers
490                             {
491                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN);
492                             }
493                         | KW_NOINTERPOLATION var_modifiers
494                             {
495                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION);
496                             }
497                         | KW_PRECISE var_modifiers
498                             {
499                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE);
500                             }
501                         | KW_SHARED var_modifiers
502                             {
503                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED);
504                             }
505                         | KW_GROUPSHARED var_modifiers
506                             {
507                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED);
508                             }
509                         | KW_STATIC var_modifiers
510                             {
511                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC);
512                             }
513                         | KW_UNIFORM var_modifiers
514                             {
515                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM);
516                             }
517                         | KW_VOLATILE var_modifiers
518                             {
519                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE);
520                             }
521                         | KW_CONST var_modifiers
522                             {
523                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST);
524                             }
525                         | KW_ROW_MAJOR var_modifiers
526                             {
527                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR);
528                             }
529                         | KW_COLUMN_MAJOR var_modifiers
530                             {
531                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
532                             }
533
534 complex_initializer:      initializer_expr
535                             {
536                                 $$ = d3dcompiler_alloc(sizeof(*$$));
537                                 list_init($$);
538                                 list_add_head($$, &$1->entry);
539                             }
540                         | '{' initializer_expr_list '}'
541                             {
542                                 $$ = $2;
543                             }
544
545 initializer_expr:         assignment_expr
546                             {
547                                 $$ = $1;
548                             }
549
550 initializer_expr_list:    initializer_expr
551                             {
552                                 $$ = d3dcompiler_alloc(sizeof(*$$));
553                                 list_init($$);
554                                 list_add_head($$, &$1->entry);
555                             }
556                         | initializer_expr_list ',' initializer_expr
557                             {
558                                 $$ = $1;
559                                 list_add_tail($$, &$3->entry);
560                             }
561
562 boolean:                  KW_TRUE
563                             {
564                                 $$ = TRUE;
565                             }
566                         | KW_FALSE
567                             {
568                                 $$ = FALSE;
569                             }
570
571 primary_expr:             C_FLOAT
572                             {
573                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
574                                 if (!c)
575                                 {
576                                     ERR("Out of memory.\n");
577                                     return -1;
578                                 }
579                                 c->node.type = HLSL_IR_CONSTANT;
580                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
581                                 c->v.value.f[0] = $1;
582                                 $$ = &c->node;
583                             }
584                         | C_INTEGER
585                             {
586                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
587                                 if (!c)
588                                 {
589                                     ERR("Out of memory.\n");
590                                     return -1;
591                                 }
592                                 c->node.type = HLSL_IR_CONSTANT;
593                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
594                                 c->v.value.i[0] = $1;
595                                 $$ = &c->node;
596                             }
597                         | boolean
598                             {
599                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
600                                 if (!c)
601                                 {
602                                     ERR("Out of memory.\n");
603                                     return -1;
604                                 }
605                                 c->node.type = HLSL_IR_CONSTANT;
606                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
607                                 c->v.value.b[0] = $1;
608                                 $$ = &c->node;
609                             }
610                         | variable
611                             {
612                                 struct hlsl_ir_deref *deref = new_var_deref($1);
613                                 $$ = deref ? &deref->node : NULL;
614                             }
615                         | '(' expr ')'
616                             {
617                                 $$ = $2;
618                             }
619
620 variable:                 VAR_IDENTIFIER
621                             {
622                                 struct hlsl_ir_var *var;
623                                 var = get_variable(hlsl_ctx.cur_scope, $1);
624                                 if (!var)
625                                 {
626                                     hlsl_message("Line %d: variable '%s' not declared\n",
627                                             hlsl_ctx.line_no, $1);
628                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
629                                     return 1;
630                                 }
631                                 $$ = var;
632                             }
633
634 postfix_expr:             primary_expr
635                             {
636                                 $$ = $1;
637                             }
638
639 unary_expr:               postfix_expr
640                             {
641                                 $$ = $1;
642                             }
643
644 mul_expr:                 unary_expr
645                             {
646                                 $$ = $1;
647                             }
648
649 add_expr:                 mul_expr
650                             {
651                                 $$ = $1;
652                             }
653
654 shift_expr:               add_expr
655                             {
656                                 $$ = $1;
657                             }
658
659 relational_expr:          shift_expr
660                             {
661                                 $$ = $1;
662                             }
663
664 equality_expr:            relational_expr
665                             {
666                                 $$ = $1;
667                             }
668
669 bitand_expr:              equality_expr
670                             {
671                                 $$ = $1;
672                             }
673
674 bitxor_expr:              bitand_expr
675                             {
676                                 $$ = $1;
677                             }
678
679 bitor_expr:               bitxor_expr
680                             {
681                                 $$ = $1;
682                             }
683
684 logicand_expr:            bitor_expr
685                             {
686                                 $$ = $1;
687                             }
688
689 logicor_expr:             logicand_expr
690                             {
691                                 $$ = $1;
692                             }
693
694 conditional_expr:         logicor_expr
695                             {
696                                 $$ = $1;
697                             }
698
699 assignment_expr:          conditional_expr
700                             {
701                                 $$ = $1;
702                             }
703
704 expr:                     assignment_expr
705                             {
706                                 $$ = $1;
707                             }
708                         | expr ',' assignment_expr
709                             {
710                                 FIXME("Comma expression\n");
711                             }
712
713 %%
714
715 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
716 {
717     struct hlsl_scope *scope, *next_scope;
718     struct hlsl_type *hlsl_type, *next_type;
719     struct hlsl_ir_var *var, *next_var;
720
721     hlsl_ctx.line_no = 1;
722     hlsl_ctx.source_file = d3dcompiler_strdup("");
723     hlsl_ctx.cur_scope = NULL;
724     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
725     list_init(&hlsl_ctx.scopes);
726     list_init(&hlsl_ctx.types);
727     list_init(&hlsl_ctx.functions);
728
729     push_scope(&hlsl_ctx);
730     hlsl_ctx.globals = hlsl_ctx.cur_scope;
731
732     hlsl_parse();
733
734     d3dcompiler_free(hlsl_ctx.source_file);
735
736     TRACE("Freeing variables.\n");
737     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
738     {
739         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
740         {
741             free_declaration(var);
742         }
743         d3dcompiler_free(scope);
744     }
745
746     TRACE("Freeing types.\n");
747     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
748     {
749         free_hlsl_type(hlsl_type);
750     }
751
752     return NULL;
753 }