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