d3dcompiler: Parse "while" loops.
[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 struct YYLTYPE;
36 static void set_location(struct source_location *loc, const struct YYLTYPE *l);
37
38 void hlsl_message(const char *fmt, ...)
39 {
40     va_list args;
41
42     va_start(args, fmt);
43     compilation_message(&hlsl_ctx.messages, fmt, args);
44     va_end(args);
45 }
46
47 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
48 {
49     const char *names[] =
50     {
51         "error",
52         "warning",
53         "note",
54     };
55     return names[level];
56 }
57
58 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
59         enum hlsl_error_level level, const char *fmt, ...)
60 {
61     va_list args;
62     char *string = NULL;
63     int rc, size = 0;
64
65     while (1)
66     {
67         va_start(args, fmt);
68         rc = vsnprintf(string, size, fmt, args);
69         va_end(args);
70
71         if (rc >= 0 && rc < size)
72             break;
73
74         if (rc >= size)
75             size = rc + 1;
76         else
77             size = size ? size * 2 : 32;
78
79         if (!string)
80             string = d3dcompiler_alloc(size);
81         else
82             string = d3dcompiler_realloc(string, size);
83         if (!string)
84         {
85             ERR("Error reallocating memory for a string.\n");
86             return;
87         }
88     }
89
90     hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
91     d3dcompiler_free(string);
92
93     if (level == HLSL_LEVEL_ERROR)
94         set_parse_status(&hlsl_ctx.status, PARSE_ERR);
95     else if (level == HLSL_LEVEL_WARNING)
96         set_parse_status(&hlsl_ctx.status, PARSE_WARN);
97 }
98
99 static void hlsl_error(const char *s)
100 {
101     hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
102 }
103
104 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
105 {
106     TRACE("Line %u: ", line_no);
107     if (modifiers)
108         TRACE("%s ", debug_modifiers(modifiers));
109     TRACE("%s %s;\n", debug_hlsl_type(type), declname);
110 }
111
112 static void check_invalid_matrix_modifiers(DWORD modifiers, struct source_location *loc)
113 {
114     if (modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
115     {
116         hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
117                 "'row_major' or 'column_major' modifiers are only allowed for matrices");
118     }
119 }
120
121 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
122 {
123     BOOL ret;
124
125     TRACE("Declaring variable %s.\n", decl->name);
126     if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
127     {
128         if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
129         {
130             decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
131                     ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
132         }
133     }
134     else
135         check_invalid_matrix_modifiers(decl->modifiers, &decl->node.loc);
136
137     if (local)
138     {
139         DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
140                 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
141         if (invalid)
142         {
143             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
144                     "modifier '%s' invalid for local variables", debug_modifiers(invalid));
145         }
146         if (decl->semantic)
147         {
148             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
149                     "semantics are not allowed on local variables");
150             return FALSE;
151         }
152     }
153     else
154     {
155         if (find_function(decl->name))
156         {
157             hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
158                     "redefinition of '%s'", decl->name);
159             return FALSE;
160         }
161     }
162     ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
163     if (!ret)
164     {
165         struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
166
167         hlsl_report_message(decl->node.loc.file, decl->node.loc.line, decl->node.loc.col, HLSL_LEVEL_ERROR,
168                 "\"%s\" already declared", decl->name);
169         hlsl_report_message(old->node.loc.file, old->node.loc.line, old->node.loc.col, HLSL_LEVEL_NOTE,
170                 "\"%s\" was previously declared here", old->name);
171         return FALSE;
172     }
173     return TRUE;
174 }
175
176 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc);
177
178 static BOOL check_type_modifiers(DWORD modifiers, struct source_location *loc)
179 {
180     if (modifiers & ~HLSL_TYPE_MODIFIERS_MASK)
181     {
182         hlsl_report_message(loc->file, loc->line, loc->col, HLSL_LEVEL_ERROR,
183                 "modifier not allowed on typedefs");
184         return FALSE;
185     }
186     return TRUE;
187 }
188
189 static BOOL add_type_to_scope(struct hlsl_scope *scope, struct hlsl_type *def)
190 {
191     if (get_type(scope, def->name, FALSE))
192         return FALSE;
193
194     wine_rb_put(&scope->types, def->name, &def->scope_entry);
195     return TRUE;
196 }
197
198 static void declare_predefined_types(struct hlsl_scope *scope)
199 {
200     struct hlsl_type *type;
201     unsigned int x, y, bt;
202     static const char *names[] =
203     {
204         "float",
205         "half",
206         "double",
207         "int",
208         "uint",
209         "bool",
210     };
211     char name[10];
212
213     for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
214     {
215         for (y = 1; y <= 4; ++y)
216         {
217             for (x = 1; x <= 4; ++x)
218             {
219                 sprintf(name, "%s%ux%u", names[bt], x, y);
220                 type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_MATRIX, bt, x, y);
221                 add_type_to_scope(scope, type);
222
223                 if (y == 1)
224                 {
225                     sprintf(name, "%s%u", names[bt], x);
226                     type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_VECTOR, bt, x, y);
227                     add_type_to_scope(scope, type);
228
229                     if (x == 1)
230                     {
231                         sprintf(name, "%s", names[bt]);
232                         type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y);
233                         add_type_to_scope(scope, type);
234                     }
235                 }
236             }
237         }
238     }
239
240     /* DX8 effects predefined types */
241     type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
242     add_type_to_scope(scope, type);
243     type = new_hlsl_type(d3dcompiler_strdup("FLOAT"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
244     add_type_to_scope(scope, type);
245     type = new_hlsl_type(d3dcompiler_strdup("VECTOR"), HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1);
246     add_type_to_scope(scope, type);
247     type = new_hlsl_type(d3dcompiler_strdup("MATRIX"), HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4);
248     add_type_to_scope(scope, type);
249     type = new_hlsl_type(d3dcompiler_strdup("STRING"), HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1);
250     add_type_to_scope(scope, type);
251     type = new_hlsl_type(d3dcompiler_strdup("TEXTURE"), HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1);
252     add_type_to_scope(scope, type);
253     type = new_hlsl_type(d3dcompiler_strdup("PIXELSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1);
254     add_type_to_scope(scope, type);
255     type = new_hlsl_type(d3dcompiler_strdup("VERTEXSHADER"), HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1);
256     add_type_to_scope(scope, type);
257 }
258
259 static struct hlsl_ir_if *loop_condition(struct list *cond_list)
260 {
261     struct hlsl_ir_if *out_cond;
262     struct hlsl_ir_expr *not_cond;
263     struct hlsl_ir_node *cond, *operands[3];
264     struct hlsl_ir_jump *jump;
265     unsigned int count = list_count(cond_list);
266
267     if (!count)
268         return NULL;
269     if (count != 1)
270         ERR("Got multiple expressions in a for condition.\n");
271
272     cond = LIST_ENTRY(list_head(cond_list), struct hlsl_ir_node, entry);
273     out_cond = d3dcompiler_alloc(sizeof(*out_cond));
274     if (!out_cond)
275     {
276         ERR("Out of memory.\n");
277         return NULL;
278     }
279     out_cond->node.type = HLSL_IR_IF;
280     operands[0] = cond;
281     operands[1] = operands[2] = NULL;
282     not_cond = new_expr(HLSL_IR_UNOP_LOGIC_NOT, operands, &cond->loc);
283     if (!not_cond)
284     {
285         ERR("Out of memory.\n");
286         d3dcompiler_free(out_cond);
287         return NULL;
288     }
289     out_cond->condition = &not_cond->node;
290     jump = d3dcompiler_alloc(sizeof(*jump));
291     if (!jump)
292     {
293         ERR("Out of memory.\n");
294         d3dcompiler_free(out_cond);
295         d3dcompiler_free(not_cond);
296         return NULL;
297     }
298     jump->node.type = HLSL_IR_JUMP;
299     jump->type = HLSL_IR_JUMP_BREAK;
300     out_cond->then_instrs = d3dcompiler_alloc(sizeof(*out_cond->then_instrs));
301     if (!out_cond->then_instrs)
302     {
303         ERR("Out of memory.\n");
304         d3dcompiler_free(out_cond);
305         d3dcompiler_free(not_cond);
306         d3dcompiler_free(jump);
307         return NULL;
308     }
309     list_init(out_cond->then_instrs);
310     list_add_head(out_cond->then_instrs, &jump->node.entry);
311
312     return out_cond;
313 }
314
315 enum loop_type
316 {
317     LOOP_FOR,
318     LOOP_WHILE,
319     LOOP_DO_WHILE
320 };
321
322 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
323         struct list *iter, struct list *body, struct source_location *loc)
324 {
325     struct list *list = NULL;
326     struct hlsl_ir_loop *loop = NULL;
327     struct hlsl_ir_if *cond_jump = NULL;
328
329     list = d3dcompiler_alloc(sizeof(*list));
330     if (!list)
331         goto oom;
332     list_init(list);
333
334     if (init)
335         list_move_head(list, init);
336
337     loop = d3dcompiler_alloc(sizeof(*loop));
338     if (!loop)
339         goto oom;
340     loop->node.type = HLSL_IR_LOOP;
341     loop->node.loc = *loc;
342     list_add_tail(list, &loop->node.entry);
343     loop->body = d3dcompiler_alloc(sizeof(*loop->body));
344     if (!loop->body)
345         goto oom;
346     list_init(loop->body);
347
348     cond_jump = loop_condition(cond);
349     if (!cond_jump)
350         goto oom;
351
352     if (type != LOOP_DO_WHILE)
353         list_add_tail(loop->body, &cond_jump->node.entry);
354
355     list_move_tail(loop->body, body);
356
357     if (iter)
358         list_move_tail(loop->body, iter);
359
360     if (type == LOOP_DO_WHILE)
361         list_add_tail(loop->body, &cond_jump->node.entry);
362
363     d3dcompiler_free(init);
364     d3dcompiler_free(cond);
365     d3dcompiler_free(iter);
366     d3dcompiler_free(body);
367     return list;
368
369 oom:
370     ERR("Out of memory.\n");
371     if (loop)
372         d3dcompiler_free(loop->body);
373     d3dcompiler_free(loop);
374     d3dcompiler_free(cond_jump);
375     d3dcompiler_free(list);
376     free_instr_list(init);
377     free_instr_list(cond);
378     free_instr_list(iter);
379     free_instr_list(body);
380     return NULL;
381 }
382
383 static unsigned int initializer_size(struct list *initializer)
384 {
385     unsigned int count = 0;
386     struct hlsl_ir_node *node;
387
388     LIST_FOR_EACH_ENTRY(node, initializer, struct hlsl_ir_node, entry)
389     {
390         count += components_count_type(node->data_type);
391     }
392     TRACE("Initializer size = %u\n", count);
393     return count;
394 }
395
396 static unsigned int components_count_expr_list(struct list *list)
397 {
398     struct hlsl_ir_node *node;
399     unsigned int count = 0;
400
401     LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
402     {
403         count += components_count_type(node->data_type);
404     }
405     return count;
406 }
407
408 static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
409         struct hlsl_ir_node *val, struct source_location *loc)
410 {
411     struct hlsl_ir_swizzle *swizzle = d3dcompiler_alloc(sizeof(*swizzle));
412
413     if (!swizzle)
414         return NULL;
415     swizzle->node.type = HLSL_IR_SWIZZLE;
416     swizzle->node.loc = *loc;
417     swizzle->node.data_type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1);
418     swizzle->val = val;
419     swizzle->swizzle = s;
420     return swizzle;
421 }
422
423 static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const char *swizzle,
424         struct source_location *loc)
425 {
426     unsigned int len = strlen(swizzle), component = 0;
427     unsigned int i, set, swiz = 0;
428     BOOL valid;
429
430     if (value->data_type->type == HLSL_CLASS_MATRIX)
431     {
432         /* Matrix swizzle */
433         BOOL m_swizzle;
434         unsigned int inc, x, y;
435
436         if (len < 3 || swizzle[0] != '_')
437             return NULL;
438         m_swizzle = swizzle[1] == 'm';
439         inc = m_swizzle ? 4 : 3;
440
441         if (len % inc || len > inc * 4)
442             return NULL;
443
444         for (i = 0; i < len; i += inc)
445         {
446             if (swizzle[i] != '_')
447                 return NULL;
448             if (m_swizzle)
449             {
450                 if (swizzle[i + 1] != 'm')
451                     return NULL;
452                 x = swizzle[i + 2] - '0';
453                 y = swizzle[i + 3] - '0';
454             }
455             else
456             {
457                 x = swizzle[i + 1] - '1';
458                 y = swizzle[i + 2] - '1';
459             }
460
461             if (x >= value->data_type->dimx || y >= value->data_type->dimy)
462                 return NULL;
463             swiz |= (y << 4 | x) << component * 8;
464             component++;
465         }
466         return new_swizzle(swiz, component, value, loc);
467     }
468
469     /* Vector swizzle */
470     if (len > 4)
471         return NULL;
472
473     for (set = 0; set < 2; ++set)
474     {
475         valid = TRUE;
476         component = 0;
477         for (i = 0; i < len; ++i)
478         {
479             char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}};
480             unsigned int s = 0;
481
482             for (s = 0; s < 4; ++s)
483             {
484                 if (swizzle[i] == c[set][s])
485                     break;
486             }
487             if (s == 4)
488             {
489                 valid = FALSE;
490                 break;
491             }
492
493             if (s >= value->data_type->dimx)
494                 return NULL;
495             swiz |= s << component * 2;
496             component++;
497         }
498         if (valid)
499             return new_swizzle(swiz, component, value, loc);
500     }
501
502     return NULL;
503 }
504
505 static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct list *list,
506         struct source_location *loc)
507 {
508     BOOL ret;
509     struct hlsl_type *type;
510     struct parse_variable_def *v, *v_next;
511
512     if (!check_type_modifiers(modifiers, loc))
513     {
514         LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
515             d3dcompiler_free(v);
516         d3dcompiler_free(list);
517         return FALSE;
518     }
519
520     LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry)
521     {
522         if (v->array_size)
523             type = new_array_type(orig_type, v->array_size);
524         else
525             type = clone_hlsl_type(orig_type);
526         if (!type)
527         {
528             ERR("Out of memory\n");
529             return FALSE;
530         }
531         d3dcompiler_free((void *)type->name);
532         type->name = v->name;
533         type->modifiers |= modifiers;
534
535         if (type->type != HLSL_CLASS_MATRIX)
536             check_invalid_matrix_modifiers(type->modifiers, &v->loc);
537
538         ret = add_type_to_scope(hlsl_ctx.cur_scope, type);
539         if (!ret)
540         {
541             hlsl_report_message(v->loc.file, v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
542                     "redefinition of custom type '%s'", v->name);
543         }
544         d3dcompiler_free(v);
545     }
546     d3dcompiler_free(list);
547     return TRUE;
548 }
549
550 %}
551
552 %locations
553 %error-verbose
554 %expect 1
555
556 %union
557 {
558     struct hlsl_type *type;
559     INT intval;
560     FLOAT floatval;
561     BOOL boolval;
562     char *name;
563     DWORD modifiers;
564     struct hlsl_ir_var *var;
565     struct hlsl_ir_node *instr;
566     struct list *list;
567     struct hlsl_ir_function_decl *function;
568     struct parse_parameter parameter;
569     struct parse_variable_def *variable_def;
570     struct parse_if_body if_body;
571     enum parse_unary_op unary_op;
572     enum parse_assign_op assign_op;
573 }
574
575 %token KW_BLENDSTATE
576 %token KW_BREAK
577 %token KW_BUFFER
578 %token KW_CBUFFER
579 %token KW_COLUMN_MAJOR
580 %token KW_COMPILE
581 %token KW_CONST
582 %token KW_CONTINUE
583 %token KW_DEPTHSTENCILSTATE
584 %token KW_DEPTHSTENCILVIEW
585 %token KW_DISCARD
586 %token KW_DO
587 %token KW_DOUBLE
588 %token KW_ELSE
589 %token KW_EXTERN
590 %token KW_FALSE
591 %token KW_FOR
592 %token KW_GEOMETRYSHADER
593 %token KW_GROUPSHARED
594 %token KW_IF
595 %token KW_IN
596 %token KW_INLINE
597 %token KW_INOUT
598 %token KW_MATRIX
599 %token KW_NAMESPACE
600 %token KW_NOINTERPOLATION
601 %token KW_OUT
602 %token KW_PASS
603 %token KW_PIXELSHADER
604 %token KW_PRECISE
605 %token KW_RASTERIZERSTATE
606 %token KW_RENDERTARGETVIEW
607 %token KW_RETURN
608 %token KW_REGISTER
609 %token KW_ROW_MAJOR
610 %token KW_SAMPLER
611 %token KW_SAMPLER1D
612 %token KW_SAMPLER2D
613 %token KW_SAMPLER3D
614 %token KW_SAMPLERCUBE
615 %token KW_SAMPLER_STATE
616 %token KW_SAMPLERCOMPARISONSTATE
617 %token KW_SHARED
618 %token KW_STATEBLOCK
619 %token KW_STATEBLOCK_STATE
620 %token KW_STATIC
621 %token KW_STRING
622 %token KW_STRUCT
623 %token KW_SWITCH
624 %token KW_TBUFFER
625 %token KW_TECHNIQUE
626 %token KW_TECHNIQUE10
627 %token KW_TEXTURE
628 %token KW_TEXTURE1D
629 %token KW_TEXTURE1DARRAY
630 %token KW_TEXTURE2D
631 %token KW_TEXTURE2DARRAY
632 %token KW_TEXTURE2DMS
633 %token KW_TEXTURE2DMSARRAY
634 %token KW_TEXTURE3D
635 %token KW_TEXTURE3DARRAY
636 %token KW_TEXTURECUBE
637 %token KW_TRUE
638 %token KW_TYPEDEF
639 %token KW_UNIFORM
640 %token KW_VECTOR
641 %token KW_VERTEXSHADER
642 %token KW_VOID
643 %token KW_VOLATILE
644 %token KW_WHILE
645
646 %token OP_INC
647 %token OP_DEC
648 %token OP_AND
649 %token OP_OR
650 %token OP_EQ
651 %token OP_LEFTSHIFT
652 %token OP_LEFTSHIFTASSIGN
653 %token OP_RIGHTSHIFT
654 %token OP_RIGHTSHIFTASSIGN
655 %token OP_ELLIPSIS
656 %token OP_LE
657 %token OP_GE
658 %token OP_NE
659 %token OP_ADDASSIGN
660 %token OP_SUBASSIGN
661 %token OP_MULASSIGN
662 %token OP_DIVASSIGN
663 %token OP_MODASSIGN
664 %token OP_ANDASSIGN
665 %token OP_ORASSIGN
666 %token OP_XORASSIGN
667 %token OP_UNKNOWN1
668 %token OP_UNKNOWN2
669 %token OP_UNKNOWN3
670 %token OP_UNKNOWN4
671
672 %token <intval> PRE_LINE
673
674 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
675 %type <name> any_identifier var_identifier
676 %token <name> STRING
677 %token <floatval> C_FLOAT
678 %token <intval> C_INTEGER
679 %type <boolval> boolean
680 %type <type> base_type
681 %type <type> type
682 %type <list> declaration_statement
683 %type <list> declaration
684 %type <list> type_specs
685 %type <variable_def> type_spec
686 %type <list> complex_initializer
687 %type <list> initializer_expr_list
688 %type <instr> initializer_expr
689 %type <modifiers> var_modifiers
690 %type <list> parameters
691 %type <list> param_list
692 %type <instr> expr
693 %type <var> variable
694 %type <intval> array
695 %type <list> statement
696 %type <list> statement_list
697 %type <list> compound_statement
698 %type <list> jump_statement
699 %type <list> selection_statement
700 %type <list> loop_statement
701 %type <function> func_declaration
702 %type <function> func_prototype
703 %type <parameter> parameter
704 %type <name> semantic
705 %type <variable_def> variable_def
706 %type <list> variables_def
707 %type <if_body> if_body
708 %type <instr> primary_expr
709 %type <instr> postfix_expr
710 %type <instr> unary_expr
711 %type <instr> mul_expr
712 %type <instr> add_expr
713 %type <instr> shift_expr
714 %type <instr> relational_expr
715 %type <instr> equality_expr
716 %type <instr> bitand_expr
717 %type <instr> bitxor_expr
718 %type <instr> bitor_expr
719 %type <instr> logicand_expr
720 %type <instr> logicor_expr
721 %type <instr> conditional_expr
722 %type <instr> assignment_expr
723 %type <list> expr_statement
724 %type <unary_op> unary_op
725 %type <assign_op> assign_op
726 %type <modifiers> input_mod
727 %%
728
729 hlsl_prog:                /* empty */
730                             {
731                             }
732                         | hlsl_prog func_declaration
733                             {
734                                 FIXME("Check that the function doesn't conflict with an already declared one.\n");
735                                 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
736                             }
737                         | hlsl_prog declaration_statement
738                             {
739                                 TRACE("Declaration statement parsed.\n");
740                             }
741                         | hlsl_prog preproc_directive
742                             {
743                             }
744
745 preproc_directive:        PRE_LINE STRING
746                             {
747                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
748                                 hlsl_ctx.line_no = $1;
749                                 if (strcmp($2, hlsl_ctx.source_file))
750                                 {
751                                     const char **new_array;
752
753                                     hlsl_ctx.source_file = $2;
754                                     new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
755                                             sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
756                                     if (new_array)
757                                     {
758                                         hlsl_ctx.source_files = new_array;
759                                         hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
760                                     }
761                                 }
762                             }
763
764 any_identifier:           VAR_IDENTIFIER
765                         | TYPE_IDENTIFIER
766                         | NEW_IDENTIFIER
767
768 func_declaration:         func_prototype compound_statement
769                             {
770                                 TRACE("Function %s parsed.\n", $1->name);
771                                 $$ = $1;
772                                 $$->body = $2;
773                                 pop_scope(&hlsl_ctx);
774                             }
775                         | func_prototype ';'
776                             {
777                                 TRACE("Function prototype for %s.\n", $1->name);
778                                 $$ = $1;
779                                 pop_scope(&hlsl_ctx);
780                             }
781
782 func_prototype:           var_modifiers type var_identifier '(' parameters ')' semantic
783                             {
784                                 if (get_variable(hlsl_ctx.globals, $3))
785                                 {
786                                     hlsl_report_message(hlsl_ctx.source_file, @3.first_line, @3.first_column,
787                                             HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3);
788                                     return 1;
789                                 }
790                                 if ($2->base_type == HLSL_TYPE_VOID && $7)
791                                 {
792                                     hlsl_report_message(hlsl_ctx.source_file, @7.first_line, @7.first_column,
793                                             HLSL_LEVEL_ERROR, "void function with a semantic");
794                                 }
795
796                                 $$ = new_func_decl($3, $2, $5);
797                                 if (!$$)
798                                 {
799                                     ERR("Out of memory.\n");
800                                     return -1;
801                                 }
802                                 $$->semantic = $7;
803                             }
804
805 compound_statement:       '{' '}'
806                             {
807                                 $$ = d3dcompiler_alloc(sizeof(*$$));
808                                 list_init($$);
809                             }
810                         | '{' scope_start statement_list '}'
811                             {
812                                 pop_scope(&hlsl_ctx);
813                                 $$ = $3;
814                             }
815
816 scope_start:              /* Empty */
817                             {
818                                 push_scope(&hlsl_ctx);
819                             }
820
821 var_identifier:           VAR_IDENTIFIER
822                         | NEW_IDENTIFIER
823
824 semantic:                 /* Empty */
825                             {
826                                 $$ = NULL;
827                             }
828                         | ':' any_identifier
829                             {
830                                 $$ = $2;
831                             }
832
833 parameters:               scope_start
834                             {
835                                 $$ = d3dcompiler_alloc(sizeof(*$$));
836                                 list_init($$);
837                             }
838                         | scope_start param_list
839                             {
840                                 $$ = $2;
841                             }
842
843 param_list:               parameter
844                             {
845                                 struct source_location loc;
846
847                                 $$ = d3dcompiler_alloc(sizeof(*$$));
848                                 list_init($$);
849                                 set_location(&loc, &@1);
850                                 if (!add_func_parameter($$, &$1, &loc))
851                                 {
852                                     ERR("Error adding function parameter %s.\n", $1.name);
853                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
854                                     return -1;
855                                 }
856                             }
857                         | param_list ',' parameter
858                             {
859                                 struct source_location loc;
860
861                                 $$ = $1;
862                                 set_location(&loc, &@3);
863                                 if (!add_func_parameter($$, &$3, &loc))
864                                 {
865                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
866                                             "duplicate parameter %s", $3.name);
867                                     return 1;
868                                 }
869                             }
870
871 parameter:                input_mod var_modifiers type any_identifier semantic
872                             {
873                                 $$.modifiers = $1;
874                                 $$.modifiers |= $2;
875                                 $$.type = $3;
876                                 $$.name = $4;
877                                 $$.semantic = $5;
878                             }
879
880 input_mod:                /* Empty */
881                             {
882                                 $$ = HLSL_MODIFIER_IN;
883                             }
884                         | KW_IN
885                             {
886                                 $$ = HLSL_MODIFIER_IN;
887                             }
888                         | KW_OUT
889                             {
890                                 $$ = HLSL_MODIFIER_OUT;
891                             }
892                         | KW_INOUT
893                             {
894                                 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
895                             }
896
897 type:                     base_type
898                             {
899                                 $$ = $1;
900                             }
901                         | KW_VECTOR '<' base_type ',' C_INTEGER '>'
902                             {
903                                 if ($3->type != HLSL_CLASS_SCALAR)
904                                 {
905                                     hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
906                                             hlsl_ctx.line_no);
907                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
908                                     return 1;
909                                 }
910                                 if ($5 < 1 || $5 > 4)
911                                 {
912                                     hlsl_message("Line %u: vector size must be between 1 and 4.\n",
913                                             hlsl_ctx.line_no);
914                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
915                                     return 1;
916                                 }
917
918                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
919                             }
920                         | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
921                             {
922                                 if ($3->type != HLSL_CLASS_SCALAR)
923                                 {
924                                     hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
925                                             hlsl_ctx.line_no);
926                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
927                                     return 1;
928                                 }
929                                 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
930                                 {
931                                     hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
932                                             hlsl_ctx.line_no);
933                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
934                                     return 1;
935                                 }
936
937                                 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
938                             }
939
940 base_type:                KW_VOID
941                             {
942                                 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
943                             }
944                         | KW_SAMPLER
945                             {
946                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
947                                 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
948                             }
949                         | KW_SAMPLER1D
950                             {
951                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
952                                 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
953                             }
954                         | KW_SAMPLER2D
955                             {
956                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
957                                 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
958                             }
959                         | KW_SAMPLER3D
960                             {
961                                 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
962                                 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
963                             }
964                         | KW_SAMPLERCUBE
965                             {
966                                 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
967                                 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
968                             }
969                         | TYPE_IDENTIFIER
970                             {
971                                 struct hlsl_type *type;
972
973                                 TRACE("Type %s.\n", $1);
974                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
975                                 $$ = type;
976                                 d3dcompiler_free($1);
977                             }
978                         | KW_STRUCT TYPE_IDENTIFIER
979                             {
980                                 struct hlsl_type *type;
981
982                                 TRACE("Struct type %s.\n", $2);
983                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
984                                 if (type->type != HLSL_CLASS_STRUCT)
985                                 {
986                                     hlsl_message("Line %u: redefining %s as a structure.\n",
987                                             hlsl_ctx.line_no, $2);
988                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
989                                 }
990                                 else
991                                 {
992                                     $$ = type;
993                                 }
994                                 d3dcompiler_free($2);
995                             }
996
997 declaration_statement:    declaration
998                             {
999                                 $$ = $1;
1000                             }
1001                         | typedef
1002                             {
1003                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1004                                 if (!$$)
1005                                 {
1006                                     ERR("Out of memory\n");
1007                                     return -1;
1008                                 }
1009                                 list_init($$);
1010                             }
1011
1012 typedef:                  KW_TYPEDEF var_modifiers type type_specs ';'
1013                             {
1014                                 struct source_location loc;
1015
1016                                 set_location(&loc, &@1);
1017                                 if (!add_typedef($2, $3, $4, &loc))
1018                                     return 1;
1019                             }
1020
1021 type_specs:               type_spec
1022                             {
1023                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1024                                 list_init($$);
1025                                 list_add_head($$, &$1->entry);
1026                             }
1027                         | type_specs ',' type_spec
1028                             {
1029                                 $$ = $1;
1030                                 list_add_tail($$, &$3->entry);
1031                             }
1032
1033 type_spec:                any_identifier array
1034                             {
1035                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1036                                 set_location(&$$->loc, &@1);
1037                                 $$->name = $1;
1038                                 $$->array_size = $2;
1039                             }
1040
1041 declaration:              var_modifiers type variables_def ';'
1042                             {
1043                                 struct hlsl_type *type;
1044                                 struct parse_variable_def *v, *v_next;
1045                                 struct hlsl_ir_var *var;
1046                                 struct hlsl_ir_node *assignment;
1047                                 BOOL ret, local = TRUE;
1048
1049                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1050                                 list_init($$);
1051                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
1052                                 {
1053                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
1054                                     var = d3dcompiler_alloc(sizeof(*var));
1055                                     var->node.type = HLSL_IR_VAR;
1056                                     if (v->array_size)
1057                                         type = new_array_type($2, v->array_size);
1058                                     else
1059                                         type = $2;
1060                                     var->node.data_type = type;
1061                                     var->node.loc = v->loc;
1062                                     var->name = v->name;
1063                                     var->modifiers = $1;
1064                                     var->semantic = v->semantic;
1065
1066                                     if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
1067                                     {
1068                                         var->modifiers |= HLSL_STORAGE_UNIFORM;
1069                                         local = FALSE;
1070                                     }
1071
1072                                     if (var->modifiers & HLSL_MODIFIER_CONST && !v->initializer)
1073                                     {
1074                                         hlsl_report_message(v->loc.file, v->loc.line, v->loc.col,
1075                                                 HLSL_LEVEL_ERROR, "const variable without initializer");
1076                                         free_declaration(var);
1077                                         d3dcompiler_free(v);
1078                                         continue;
1079                                     }
1080
1081                                     ret = declare_variable(var, local);
1082                                     if (!ret)
1083                                         free_declaration(var);
1084                                     else
1085                                         TRACE("Declared variable %s.\n", var->name);
1086
1087                                     if (v->initializer)
1088                                     {
1089                                         unsigned int size = initializer_size(v->initializer);
1090                                         struct hlsl_ir_node *node;
1091
1092                                         TRACE("Variable with initializer\n");
1093                                         if (type->type <= HLSL_CLASS_LAST_NUMERIC
1094                                             && type->dimx * type->dimy != size
1095                                             && size != 1)
1096                                         {
1097                                             if (size < type->dimx * type->dimy)
1098                                             {
1099                                                 hlsl_report_message(v->loc.file,
1100                                                         v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
1101                                                         "'%s' initializer does not match", v->name);
1102                                                 free_instr_list(v->initializer);
1103                                                 d3dcompiler_free(v);
1104                                                 continue;
1105                                             }
1106                                         }
1107
1108                                         if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY)
1109                                             && components_count_type(type) != size)
1110                                         {
1111                                             hlsl_report_message(v->loc.file,
1112                                                     v->loc.line, v->loc.col, HLSL_LEVEL_ERROR,
1113                                                     "'%s' initializer does not match", v->name);
1114                                             free_instr_list(v->initializer);
1115                                             d3dcompiler_free(v);
1116                                             continue;
1117                                         }
1118
1119                                         if (type->type > HLSL_CLASS_LAST_NUMERIC)
1120                                         {
1121                                             FIXME("Initializers for non scalar/struct variables not supported yet\n");
1122                                             free_instr_list(v->initializer);
1123                                             d3dcompiler_free(v);
1124                                             continue;
1125                                         }
1126                                         if (v->array_size > 0)
1127                                         {
1128                                             FIXME("Initializing arrays is not supported yet\n");
1129                                             free_instr_list(v->initializer);
1130                                             d3dcompiler_free(v);
1131                                             continue;
1132                                         }
1133
1134                                         if (list_count(v->initializer) > 1)
1135                                         {
1136                                             FIXME("Complex initializers are not supported yet.\n");
1137                                             free_instr_list(v->initializer);
1138                                             d3dcompiler_free(v);
1139                                             continue;
1140                                         }
1141                                         node = LIST_ENTRY(list_head(v->initializer), struct hlsl_ir_node, entry);
1142                                         assignment = make_assignment(&var->node, ASSIGN_OP_ASSIGN,
1143                                                 BWRITERSP_WRITEMASK_ALL, node);
1144                                         list_add_tail($$, &assignment->entry);
1145                                     }
1146                                     d3dcompiler_free(v);
1147                                 }
1148                                 d3dcompiler_free($3);
1149                             }
1150
1151 variables_def:            variable_def
1152                             {
1153                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1154                                 list_init($$);
1155                                 list_add_head($$, &$1->entry);
1156                             }
1157                         | variables_def ',' variable_def
1158                             {
1159                                 $$ = $1;
1160                                 list_add_tail($$, &$3->entry);
1161                             }
1162
1163 variable_def:             any_identifier array semantic
1164                             {
1165                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1166                                 set_location(&$$->loc, &@1);
1167                                 $$->name = $1;
1168                                 $$->array_size = $2;
1169                                 $$->semantic = $3;
1170                             }
1171                         | any_identifier array semantic '=' complex_initializer
1172                             {
1173                                 TRACE("Declaration with initializer.\n");
1174                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1175                                 set_location(&$$->loc, &@1);
1176                                 $$->name = $1;
1177                                 $$->array_size = $2;
1178                                 $$->semantic = $3;
1179                                 $$->initializer = $5;
1180                             }
1181
1182 array:                    /* Empty */
1183                             {
1184                                 $$ = 0;
1185                             }
1186                         | '[' expr ']'
1187                             {
1188                                 FIXME("Array.\n");
1189                                 $$ = 0;
1190                                 free_instr($2);
1191                             }
1192
1193 var_modifiers:            /* Empty */
1194                             {
1195                                 $$ = 0;
1196                             }
1197                         | KW_EXTERN var_modifiers
1198                             {
1199                                 $$ = add_modifier($2, HLSL_STORAGE_EXTERN, &@1);
1200                             }
1201                         | KW_NOINTERPOLATION var_modifiers
1202                             {
1203                                 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION, &@1);
1204                             }
1205                         | KW_PRECISE var_modifiers
1206                             {
1207                                 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE, &@1);
1208                             }
1209                         | KW_SHARED var_modifiers
1210                             {
1211                                 $$ = add_modifier($2, HLSL_STORAGE_SHARED, &@1);
1212                             }
1213                         | KW_GROUPSHARED var_modifiers
1214                             {
1215                                 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED, &@1);
1216                             }
1217                         | KW_STATIC var_modifiers
1218                             {
1219                                 $$ = add_modifier($2, HLSL_STORAGE_STATIC, &@1);
1220                             }
1221                         | KW_UNIFORM var_modifiers
1222                             {
1223                                 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM, &@1);
1224                             }
1225                         | KW_VOLATILE var_modifiers
1226                             {
1227                                 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE, &@1);
1228                             }
1229                         | KW_CONST var_modifiers
1230                             {
1231                                 $$ = add_modifier($2, HLSL_MODIFIER_CONST, &@1);
1232                             }
1233                         | KW_ROW_MAJOR var_modifiers
1234                             {
1235                                 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR, &@1);
1236                             }
1237                         | KW_COLUMN_MAJOR var_modifiers
1238                             {
1239                                 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR, &@1);
1240                             }
1241
1242 complex_initializer:      initializer_expr
1243                             {
1244                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1245                                 list_init($$);
1246                                 list_add_head($$, &$1->entry);
1247                             }
1248                         | '{' initializer_expr_list '}'
1249                             {
1250                                 $$ = $2;
1251                             }
1252
1253 initializer_expr:         assignment_expr
1254                             {
1255                                 $$ = $1;
1256                             }
1257
1258 initializer_expr_list:    initializer_expr
1259                             {
1260                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1261                                 list_init($$);
1262                                 list_add_head($$, &$1->entry);
1263                             }
1264                         | initializer_expr_list ',' initializer_expr
1265                             {
1266                                 $$ = $1;
1267                                 list_add_tail($$, &$3->entry);
1268                             }
1269
1270 boolean:                  KW_TRUE
1271                             {
1272                                 $$ = TRUE;
1273                             }
1274                         | KW_FALSE
1275                             {
1276                                 $$ = FALSE;
1277                             }
1278
1279 statement_list:           statement
1280                             {
1281                                 $$ = $1;
1282                             }
1283                         | statement_list statement
1284                             {
1285                                 $$ = $1;
1286                                 list_move_tail($$, $2);
1287                                 d3dcompiler_free($2);
1288                             }
1289
1290 statement:                declaration_statement
1291                         | expr_statement
1292                         | compound_statement
1293                         | jump_statement
1294                         | selection_statement
1295                         | loop_statement
1296
1297                           /* FIXME: add rule for return with no value */
1298 jump_statement:           KW_RETURN expr ';'
1299                             {
1300                                 struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
1301                                 if (!jump)
1302                                 {
1303                                     ERR("Out of memory\n");
1304                                     return -1;
1305                                 }
1306                                 jump->node.type = HLSL_IR_JUMP;
1307                                 set_location(&jump->node.loc, &@1);
1308                                 jump->type = HLSL_IR_JUMP_RETURN;
1309                                 jump->node.data_type = $2->data_type;
1310                                 jump->return_value = $2;
1311
1312                                 FIXME("Check for valued return on void function.\n");
1313                                 FIXME("Implicit conversion to the return type if needed, "
1314                                         "error out if conversion not possible.\n");
1315
1316                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1317                                 list_init($$);
1318                                 list_add_tail($$, &jump->node.entry);
1319                             }
1320
1321 selection_statement:      KW_IF '(' expr ')' if_body
1322                             {
1323                                 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
1324                                 if (!instr)
1325                                 {
1326                                     ERR("Out of memory\n");
1327                                     return -1;
1328                                 }
1329                                 instr->node.type = HLSL_IR_IF;
1330                                 set_location(&instr->node.loc, &@1);
1331                                 instr->condition = $3;
1332                                 instr->then_instrs = $5.then_instrs;
1333                                 instr->else_instrs = $5.else_instrs;
1334                                 if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
1335                                 {
1336                                     hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
1337                                             instr->node.loc.col, HLSL_LEVEL_ERROR,
1338                                             "if condition requires a scalar");
1339                                 }
1340                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1341                                 list_init($$);
1342                                 list_add_head($$, &instr->node.entry);
1343                             }
1344
1345 if_body:                  statement
1346                             {
1347                                 $$.then_instrs = $1;
1348                                 $$.else_instrs = NULL;
1349                             }
1350                         | statement KW_ELSE statement
1351                             {
1352                                 $$.then_instrs = $1;
1353                                 $$.else_instrs = $3;
1354                             }
1355
1356 loop_statement:           KW_WHILE '(' expr ')' statement
1357                             {
1358                                 struct source_location loc;
1359                                 struct list *cond = d3dcompiler_alloc(sizeof(*cond));
1360
1361                                 if (!cond)
1362                                 {
1363                                     ERR("Out of memory.\n");
1364                                     return -1;
1365                                 }
1366                                 list_init(cond);
1367                                 list_add_head(cond, &$3->entry);
1368                                 set_location(&loc, &@1);
1369                                 $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
1370                             }
1371
1372 expr_statement:           ';'
1373                             {
1374                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1375                                 list_init($$);
1376                             }
1377                         | expr ';'
1378                             {
1379                                 $$ = d3dcompiler_alloc(sizeof(*$$));
1380                                 list_init($$);
1381                                 if ($1)
1382                                     list_add_head($$, &$1->entry);
1383                             }
1384
1385 primary_expr:             C_FLOAT
1386                             {
1387                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1388                                 if (!c)
1389                                 {
1390                                     ERR("Out of memory.\n");
1391                                     return -1;
1392                                 }
1393                                 c->node.type = HLSL_IR_CONSTANT;
1394                                 set_location(&c->node.loc, &yylloc);
1395                                 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
1396                                 c->v.value.f[0] = $1;
1397                                 $$ = &c->node;
1398                             }
1399                         | C_INTEGER
1400                             {
1401                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1402                                 if (!c)
1403                                 {
1404                                     ERR("Out of memory.\n");
1405                                     return -1;
1406                                 }
1407                                 c->node.type = HLSL_IR_CONSTANT;
1408                                 set_location(&c->node.loc, &yylloc);
1409                                 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
1410                                 c->v.value.i[0] = $1;
1411                                 $$ = &c->node;
1412                             }
1413                         | boolean
1414                             {
1415                                 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
1416                                 if (!c)
1417                                 {
1418                                     ERR("Out of memory.\n");
1419                                     return -1;
1420                                 }
1421                                 c->node.type = HLSL_IR_CONSTANT;
1422                                 set_location(&c->node.loc, &yylloc);
1423                                 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
1424                                 c->v.value.b[0] = $1;
1425                                 $$ = &c->node;
1426                             }
1427                         | variable
1428                             {
1429                                 struct hlsl_ir_deref *deref = new_var_deref($1);
1430                                 if (deref)
1431                                 {
1432                                     $$ = &deref->node;
1433                                     set_location(&$$->loc, &@1);
1434                                 }
1435                                 else
1436                                     $$ = NULL;
1437                             }
1438                         | '(' expr ')'
1439                             {
1440                                 $$ = $2;
1441                             }
1442
1443 variable:                 VAR_IDENTIFIER
1444                             {
1445                                 struct hlsl_ir_var *var;
1446                                 var = get_variable(hlsl_ctx.cur_scope, $1);
1447                                 if (!var)
1448                                 {
1449                                     hlsl_message("Line %d: variable '%s' not declared\n",
1450                                             hlsl_ctx.line_no, $1);
1451                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1452                                     return 1;
1453                                 }
1454                                 $$ = var;
1455                             }
1456
1457 postfix_expr:             primary_expr
1458                             {
1459                                 $$ = $1;
1460                             }
1461                         | postfix_expr OP_INC
1462                             {
1463                                 struct hlsl_ir_node *operands[3];
1464                                 struct source_location loc;
1465
1466                                 set_location(&loc, &@2);
1467                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1468                                 {
1469                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1470                                             "modifying a const expression");
1471                                     return 1;
1472                                 }
1473                                 operands[0] = $1;
1474                                 operands[1] = operands[2] = NULL;
1475                                 $$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
1476                                 /* Post increment/decrement expressions are considered const */
1477                                 $$->data_type = clone_hlsl_type($$->data_type);
1478                                 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1479                             }
1480                         | postfix_expr OP_DEC
1481                             {
1482                                 struct hlsl_ir_node *operands[3];
1483                                 struct source_location loc;
1484
1485                                 set_location(&loc, &@2);
1486                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1487                                 {
1488                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1489                                             "modifying a const expression");
1490                                     return 1;
1491                                 }
1492                                 operands[0] = $1;
1493                                 operands[1] = operands[2] = NULL;
1494                                 $$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
1495                                 /* Post increment/decrement expressions are considered const */
1496                                 $$->data_type = clone_hlsl_type($$->data_type);
1497                                 $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
1498                             }
1499                         | postfix_expr '.' any_identifier
1500                             {
1501                                 struct source_location loc;
1502
1503                                 set_location(&loc, &@2);
1504                                 if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
1505                                 {
1506                                     struct hlsl_ir_swizzle *swizzle;
1507
1508                                     swizzle = get_swizzle($1, $3, &loc);
1509                                     if (!swizzle)
1510                                     {
1511                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1512                                                 "invalid swizzle %s", debugstr_a($3));
1513                                         return 1;
1514                                     }
1515                                     $$ = &swizzle->node;
1516                                 }
1517                                 else
1518                                 {
1519                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1520                                             "invalid subscript %s", debugstr_a($3));
1521                                     return 1;
1522                                 }
1523                             }
1524                           /* "var_modifiers" doesn't make sense in this case, but it's needed
1525                              in the grammar to avoid shift/reduce conflicts. */
1526                         | var_modifiers type '(' initializer_expr_list ')'
1527                             {
1528                                 struct hlsl_ir_constructor *constructor;
1529
1530                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
1531                                 if ($1)
1532                                 {
1533                                     hlsl_message("Line %u: unexpected modifier in a constructor.\n",
1534                                             hlsl_ctx.line_no);
1535                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1536                                     return -1;
1537                                 }
1538                                 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
1539                                 {
1540                                     hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
1541                                             hlsl_ctx.line_no);
1542                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1543                                     return -1;
1544                                 }
1545                                 if ($2->dimx * $2->dimy != components_count_expr_list($4))
1546                                 {
1547                                     hlsl_message("Line %u: wrong number of components in constructor.\n",
1548                                             hlsl_ctx.line_no);
1549                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
1550                                     return -1;
1551                                 }
1552
1553                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
1554                                 constructor->node.type = HLSL_IR_CONSTRUCTOR;
1555                                 set_location(&constructor->node.loc, &@3);
1556                                 constructor->node.data_type = $2;
1557                                 constructor->arguments = $4;
1558
1559                                 $$ = &constructor->node;
1560                             }
1561
1562 unary_expr:               postfix_expr
1563                             {
1564                                 $$ = $1;
1565                             }
1566                         | OP_INC unary_expr
1567                             {
1568                                 struct hlsl_ir_node *operands[3];
1569                                 struct source_location loc;
1570
1571                                 set_location(&loc, &@1);
1572                                 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
1573                                 {
1574                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1575                                             "modifying a const expression");
1576                                     return 1;
1577                                 }
1578                                 operands[0] = $2;
1579                                 operands[1] = operands[2] = NULL;
1580                                 $$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
1581                             }
1582                         | OP_DEC unary_expr
1583                             {
1584                                 struct hlsl_ir_node *operands[3];
1585                                 struct source_location loc;
1586
1587                                 set_location(&loc, &@1);
1588                                 if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
1589                                 {
1590                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1591                                             "modifying a const expression");
1592                                     return 1;
1593                                 }
1594                                 operands[0] = $2;
1595                                 operands[1] = operands[2] = NULL;
1596                                 $$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
1597                             }
1598                         | unary_op unary_expr
1599                             {
1600                                 enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG,
1601                                         HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT};
1602                                 struct hlsl_ir_node *operands[3];
1603                                 struct source_location loc;
1604
1605                                 if ($1 == UNARY_OP_PLUS)
1606                                 {
1607                                     $$ = $2;
1608                                 }
1609                                 else
1610                                 {
1611                                     operands[0] = $2;
1612                                     operands[1] = operands[2] = NULL;
1613                                     set_location(&loc, &@1);
1614                                     $$ = &new_expr(ops[$1], operands, &loc)->node;
1615                                 }
1616                             }
1617                           /* var_modifiers just to avoid shift/reduce conflicts */
1618                         | '(' var_modifiers type array ')' unary_expr
1619                             {
1620                                 struct hlsl_ir_expr *expr;
1621                                 struct hlsl_type *src_type = $6->data_type;
1622                                 struct hlsl_type *dst_type;
1623                                 struct source_location loc;
1624
1625                                 set_location(&loc, &@3);
1626                                 if ($2)
1627                                 {
1628                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1629                                             "unexpected modifier in a cast");
1630                                     return 1;
1631                                 }
1632
1633                                 if ($4)
1634                                     dst_type = new_array_type($3, $4);
1635                                 else
1636                                     dst_type = $3;
1637
1638                                 if (!compatible_data_types(src_type, dst_type))
1639                                 {
1640                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1641                                             "can't cast from %s to %s",
1642                                             debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
1643                                     return 1;
1644                                 }
1645
1646                                 expr = new_cast($6, dst_type, &loc);
1647                                 $$ = expr ? &expr->node : NULL;
1648                             }
1649
1650 unary_op:                 '+'
1651                             {
1652                                 $$ = UNARY_OP_PLUS;
1653                             }
1654                         | '-'
1655                             {
1656                                 $$ = UNARY_OP_MINUS;
1657                             }
1658                         | '!'
1659                             {
1660                                 $$ = UNARY_OP_LOGICNOT;
1661                             }
1662                         | '~'
1663                             {
1664                                 $$ = UNARY_OP_BITNOT;
1665                             }
1666
1667 mul_expr:                 unary_expr
1668                             {
1669                                 $$ = $1;
1670                             }
1671                         | mul_expr '*' unary_expr
1672                             {
1673                                 struct source_location loc;
1674
1675                                 set_location(&loc, &@2);
1676                                 $$ = &hlsl_mul($1, $3, &loc)->node;
1677                             }
1678                         | mul_expr '/' unary_expr
1679                             {
1680                                 struct source_location loc;
1681
1682                                 set_location(&loc, &@2);
1683                                 $$ = &hlsl_div($1, $3, &loc)->node;
1684                             }
1685                         | mul_expr '%' unary_expr
1686                             {
1687                                 struct source_location loc;
1688
1689                                 set_location(&loc, &@2);
1690                                 $$ = &hlsl_mod($1, $3, &loc)->node;
1691                             }
1692
1693 add_expr:                 mul_expr
1694                             {
1695                                 $$ = $1;
1696                             }
1697                         | add_expr '+' mul_expr
1698                             {
1699                                 struct source_location loc;
1700
1701                                 set_location(&loc, &@2);
1702                                 $$ = &hlsl_add($1, $3, &loc)->node;
1703                             }
1704                         | add_expr '-' mul_expr
1705                             {
1706                                 struct source_location loc;
1707
1708                                 set_location(&loc, &@2);
1709                                 $$ = &hlsl_sub($1, $3, &loc)->node;
1710                             }
1711
1712 shift_expr:               add_expr
1713                             {
1714                                 $$ = $1;
1715                             }
1716                         | shift_expr OP_LEFTSHIFT add_expr
1717                             {
1718                                 FIXME("Left shift\n");
1719                             }
1720                         | shift_expr OP_RIGHTSHIFT add_expr
1721                             {
1722                                 FIXME("Right shift\n");
1723                             }
1724
1725 relational_expr:          shift_expr
1726                             {
1727                                 $$ = $1;
1728                             }
1729                         | relational_expr '<' shift_expr
1730                             {
1731                                 struct source_location loc;
1732
1733                                 set_location(&loc, &@2);
1734                                 $$ = &hlsl_lt($1, $3, &loc)->node;
1735                             }
1736                         | relational_expr '>' shift_expr
1737                             {
1738                                 struct source_location loc;
1739
1740                                 set_location(&loc, &@2);
1741                                 $$ = &hlsl_gt($1, $3, &loc)->node;
1742                             }
1743                         | relational_expr OP_LE shift_expr
1744                             {
1745                                 struct source_location loc;
1746
1747                                 set_location(&loc, &@2);
1748                                 $$ = &hlsl_le($1, $3, &loc)->node;
1749                             }
1750                         | relational_expr OP_GE shift_expr
1751                             {
1752                                 struct source_location loc;
1753
1754                                 set_location(&loc, &@2);
1755                                 $$ = &hlsl_ge($1, $3, &loc)->node;
1756                             }
1757
1758 equality_expr:            relational_expr
1759                             {
1760                                 $$ = $1;
1761                             }
1762                         | equality_expr OP_EQ relational_expr
1763                             {
1764                                 struct source_location loc;
1765
1766                                 set_location(&loc, &@2);
1767                                 $$ = &hlsl_eq($1, $3, &loc)->node;
1768                             }
1769                         | equality_expr OP_NE relational_expr
1770                             {
1771                                 struct source_location loc;
1772
1773                                 set_location(&loc, &@2);
1774                                 $$ = &hlsl_ne($1, $3, &loc)->node;
1775                             }
1776
1777 bitand_expr:              equality_expr
1778                             {
1779                                 $$ = $1;
1780                             }
1781                         | bitand_expr '&' equality_expr
1782                             {
1783                                 FIXME("bitwise AND\n");
1784                             }
1785
1786 bitxor_expr:              bitand_expr
1787                             {
1788                                 $$ = $1;
1789                             }
1790                         | bitxor_expr '^' bitand_expr
1791                             {
1792                                 FIXME("bitwise XOR\n");
1793                             }
1794
1795 bitor_expr:               bitxor_expr
1796                             {
1797                                 $$ = $1;
1798                             }
1799                         | bitor_expr '|' bitxor_expr
1800                             {
1801                                 FIXME("bitwise OR\n");
1802                             }
1803
1804 logicand_expr:            bitor_expr
1805                             {
1806                                 $$ = $1;
1807                             }
1808                         | logicand_expr OP_AND bitor_expr
1809                             {
1810                                 FIXME("logic AND\n");
1811                             }
1812
1813 logicor_expr:             logicand_expr
1814                             {
1815                                 $$ = $1;
1816                             }
1817                         | logicor_expr OP_OR logicand_expr
1818                             {
1819                                 FIXME("logic OR\n");
1820                             }
1821
1822 conditional_expr:         logicor_expr
1823                             {
1824                                 $$ = $1;
1825                             }
1826                         | logicor_expr '?' expr ':' assignment_expr
1827                             {
1828                                 FIXME("ternary operator\n");
1829                             }
1830
1831 assignment_expr:          conditional_expr
1832                             {
1833                                 $$ = $1;
1834                             }
1835                         | unary_expr assign_op assignment_expr
1836                             {
1837                                 struct source_location loc;
1838
1839                                 set_location(&loc, &@2);
1840                                 if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
1841                                 {
1842                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
1843                                             "l-value is const");
1844                                     return 1;
1845                                 }
1846                                 $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
1847                                 if (!$$)
1848                                     return 1;
1849                                 $$->loc = loc;
1850                             }
1851
1852 assign_op:                '='
1853                             {
1854                                 $$ = ASSIGN_OP_ASSIGN;
1855                             }
1856                         | OP_ADDASSIGN
1857                             {
1858                                 $$ = ASSIGN_OP_ADD;
1859                             }
1860                         | OP_SUBASSIGN
1861                             {
1862                                 $$ = ASSIGN_OP_SUB;
1863                             }
1864                         | OP_MULASSIGN
1865                             {
1866                                 $$ = ASSIGN_OP_MUL;
1867                             }
1868                         | OP_DIVASSIGN
1869                             {
1870                                 $$ = ASSIGN_OP_DIV;
1871                             }
1872                         | OP_MODASSIGN
1873                             {
1874                                 $$ = ASSIGN_OP_MOD;
1875                             }
1876                         | OP_LEFTSHIFTASSIGN
1877                             {
1878                                 $$ = ASSIGN_OP_LSHIFT;
1879                             }
1880                         | OP_RIGHTSHIFTASSIGN
1881                             {
1882                                 $$ = ASSIGN_OP_RSHIFT;
1883                             }
1884                         | OP_ANDASSIGN
1885                             {
1886                                 $$ = ASSIGN_OP_AND;
1887                             }
1888                         | OP_ORASSIGN
1889                             {
1890                                 $$ = ASSIGN_OP_OR;
1891                             }
1892                         | OP_XORASSIGN
1893                             {
1894                                 $$ = ASSIGN_OP_XOR;
1895                             }
1896
1897 expr:                     assignment_expr
1898                             {
1899                                 $$ = $1;
1900                             }
1901                         | expr ',' assignment_expr
1902                             {
1903                                 FIXME("Comma expression\n");
1904                             }
1905
1906 %%
1907
1908 static void set_location(struct source_location *loc, const struct YYLTYPE *l)
1909 {
1910     loc->file = hlsl_ctx.source_file;
1911     loc->line = l->first_line;
1912     loc->col = l->first_column;
1913 }
1914
1915 static DWORD add_modifier(DWORD modifiers, DWORD mod, const struct YYLTYPE *loc)
1916 {
1917     if (modifiers & mod)
1918     {
1919         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1920                 "modifier '%s' already specified", debug_modifiers(mod));
1921         return modifiers;
1922     }
1923     if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
1924             && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
1925     {
1926         hlsl_report_message(hlsl_ctx.source_file, loc->first_line, loc->first_column, HLSL_LEVEL_ERROR,
1927                 "more than one matrix majority keyword");
1928         return modifiers;
1929     }
1930     return modifiers | mod;
1931 }
1932
1933 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
1934         const char *entrypoint, char **messages)
1935 {
1936     struct hlsl_ir_function_decl *function;
1937     struct hlsl_scope *scope, *next_scope;
1938     struct hlsl_type *hlsl_type, *next_type;
1939     struct hlsl_ir_var *var, *next_var;
1940     unsigned int i;
1941
1942     hlsl_ctx.status = PARSE_SUCCESS;
1943     hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
1944     hlsl_ctx.line_no = hlsl_ctx.column = 1;
1945     hlsl_ctx.source_file = d3dcompiler_strdup("");
1946     hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1947     if (hlsl_ctx.source_files)
1948         hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1949     hlsl_ctx.source_files_count = 1;
1950     hlsl_ctx.cur_scope = NULL;
1951     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1952     list_init(&hlsl_ctx.scopes);
1953     list_init(&hlsl_ctx.types);
1954     list_init(&hlsl_ctx.functions);
1955
1956     push_scope(&hlsl_ctx);
1957     hlsl_ctx.globals = hlsl_ctx.cur_scope;
1958     declare_predefined_types(hlsl_ctx.globals);
1959
1960     hlsl_parse();
1961
1962     if (TRACE_ON(hlsl_parser))
1963     {
1964         struct hlsl_ir_function_decl *func;
1965
1966         TRACE("IR dump.\n");
1967         LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1968         {
1969             if (func->body)
1970                 debug_dump_ir_function(func);
1971         }
1972     }
1973
1974     TRACE("Compilation status = %d\n", hlsl_ctx.status);
1975     if (messages)
1976     {
1977         if (hlsl_ctx.messages.size)
1978             *messages = hlsl_ctx.messages.string;
1979         else
1980             *messages = NULL;
1981     }
1982     else
1983     {
1984         if (hlsl_ctx.messages.capacity)
1985             d3dcompiler_free(hlsl_ctx.messages.string);
1986     }
1987
1988     for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1989         d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1990     d3dcompiler_free(hlsl_ctx.source_files);
1991
1992     TRACE("Freeing functions IR.\n");
1993     LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1994         free_function(function);
1995
1996     TRACE("Freeing variables.\n");
1997     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1998     {
1999         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
2000         {
2001             free_declaration(var);
2002         }
2003         wine_rb_destroy(&scope->types, NULL, NULL);
2004         d3dcompiler_free(scope);
2005     }
2006
2007     TRACE("Freeing types.\n");
2008     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
2009     {
2010         free_hlsl_type(hlsl_type);
2011     }
2012
2013     return NULL;
2014 }