d3dcompiler: Track the location of each lexer token.
[wine/multimedia.git] / dlls / d3dcompiler_43 / hlsl.y
blob48c43a2417bb4a4081b8aa0acfedca33f54ff48d
1 /*
2 * HLSL parser
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2012 Matteo Bruni for CodeWeavers
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.
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.
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
22 #include "config.h"
23 #include "wine/debug.h"
25 #include <stdio.h>
27 #include "d3dcompiler_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
31 int hlsl_lex(void);
33 struct hlsl_parse_ctx hlsl_ctx;
35 void hlsl_message(const char *fmt, ...)
37 va_list args;
39 va_start(args, fmt);
40 compilation_message(&hlsl_ctx.messages, fmt, args);
41 va_end(args);
44 static const char *hlsl_get_error_level_name(enum hlsl_error_level level)
46 const char *names[] =
48 "error",
49 "warning",
50 "note",
52 return names[level];
55 void hlsl_report_message(const char *filename, DWORD line, DWORD column,
56 enum hlsl_error_level level, const char *fmt, ...)
58 va_list args;
59 char *string = NULL;
60 int rc, size = 0;
62 while (1)
64 va_start(args, fmt);
65 rc = vsnprintf(string, size, fmt, args);
66 va_end(args);
68 if (rc >= 0 && rc < size)
69 break;
71 if (rc >= size)
72 size = rc + 1;
73 else
74 size = size ? size * 2 : 32;
76 if (!string)
77 string = d3dcompiler_alloc(size);
78 else
79 string = d3dcompiler_realloc(string, size);
80 if (!string)
82 ERR("Error reallocating memory for a string.\n");
83 return;
87 hlsl_message("%s:%u:%u: %s: %s\n", filename, line, column, hlsl_get_error_level_name(level), string);
88 d3dcompiler_free(string);
90 if (level == HLSL_LEVEL_ERROR)
91 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
92 else if (level == HLSL_LEVEL_WARNING)
93 set_parse_status(&hlsl_ctx.status, PARSE_WARN);
96 static void hlsl_error(const char *s)
98 hlsl_report_message(hlsl_ctx.source_file, hlsl_ctx.line_no, hlsl_ctx.column, HLSL_LEVEL_ERROR, "%s", s);
101 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
103 TRACE("Line %u: ", line_no);
104 if (modifiers)
105 TRACE("%s ", debug_modifiers(modifiers));
106 TRACE("%s %s;\n", debug_hlsl_type(type), declname);
109 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
111 BOOL ret;
113 TRACE("Declaring variable %s.\n", decl->name);
114 if (decl->node.data_type->type == HLSL_CLASS_MATRIX)
116 if (!(decl->modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)))
118 decl->modifiers |= hlsl_ctx.matrix_majority == HLSL_ROW_MAJOR
119 ? HLSL_MODIFIER_ROW_MAJOR : HLSL_MODIFIER_COLUMN_MAJOR;
122 if (local)
124 DWORD invalid = decl->modifiers & (HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED
125 | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM);
126 if (invalid)
128 hlsl_message("Line %u: modifier '%s' invalid for local variables.\n",
129 hlsl_ctx.line_no, debug_modifiers(invalid));
130 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
133 ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
134 if (ret == FALSE)
136 struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
138 hlsl_message("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no, decl->name);
139 hlsl_message("Line %u: \"%s\" was previously declared here.\n", old->node.line, decl->name);
140 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
141 return FALSE;
143 return TRUE;
146 static DWORD add_modifier(DWORD modifiers, DWORD mod)
148 if (modifiers & mod)
150 hlsl_message("Line %u: modifier '%s' already specified.\n",
151 hlsl_ctx.line_no, debug_modifiers(mod));
152 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
153 return modifiers;
155 if (mod & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
156 && modifiers & (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR))
158 hlsl_message("Line %u: more than one matrix majority keyword.\n",
159 hlsl_ctx.line_no);
160 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
161 return modifiers;
163 return modifiers | mod;
166 static unsigned int components_count_expr_list(struct list *list)
168 struct hlsl_ir_node *node;
169 unsigned int count = 0;
171 LIST_FOR_EACH_ENTRY(node, list, struct hlsl_ir_node, entry)
173 count += components_count_type(node->data_type);
175 return count;
180 %locations
181 %error-verbose
183 %union
185 struct hlsl_type *type;
186 INT intval;
187 FLOAT floatval;
188 BOOL boolval;
189 char *name;
190 DWORD modifiers;
191 struct hlsl_ir_var *var;
192 struct hlsl_ir_node *instr;
193 struct list *list;
194 struct hlsl_ir_function_decl *function;
195 struct parse_parameter parameter;
196 struct parse_variable_def *variable_def;
199 %token KW_BLENDSTATE
200 %token KW_BREAK
201 %token KW_BUFFER
202 %token KW_CBUFFER
203 %token KW_COLUMN_MAJOR
204 %token KW_COMPILE
205 %token KW_CONST
206 %token KW_CONTINUE
207 %token KW_DEPTHSTENCILSTATE
208 %token KW_DEPTHSTENCILVIEW
209 %token KW_DISCARD
210 %token KW_DO
211 %token KW_DOUBLE
212 %token KW_ELSE
213 %token KW_EXTERN
214 %token KW_FALSE
215 %token KW_FOR
216 %token KW_GEOMETRYSHADER
217 %token KW_GROUPSHARED
218 %token KW_IF
219 %token KW_IN
220 %token KW_INLINE
221 %token KW_INOUT
222 %token KW_MATRIX
223 %token KW_NAMESPACE
224 %token KW_NOINTERPOLATION
225 %token KW_OUT
226 %token KW_PASS
227 %token KW_PIXELSHADER
228 %token KW_PRECISE
229 %token KW_RASTERIZERSTATE
230 %token KW_RENDERTARGETVIEW
231 %token KW_RETURN
232 %token KW_REGISTER
233 %token KW_ROW_MAJOR
234 %token KW_SAMPLER
235 %token KW_SAMPLER1D
236 %token KW_SAMPLER2D
237 %token KW_SAMPLER3D
238 %token KW_SAMPLERCUBE
239 %token KW_SAMPLER_STATE
240 %token KW_SAMPLERCOMPARISONSTATE
241 %token KW_SHARED
242 %token KW_STATEBLOCK
243 %token KW_STATEBLOCK_STATE
244 %token KW_STATIC
245 %token KW_STRING
246 %token KW_STRUCT
247 %token KW_SWITCH
248 %token KW_TBUFFER
249 %token KW_TECHNIQUE
250 %token KW_TECHNIQUE10
251 %token KW_TEXTURE
252 %token KW_TEXTURE1D
253 %token KW_TEXTURE1DARRAY
254 %token KW_TEXTURE2D
255 %token KW_TEXTURE2DARRAY
256 %token KW_TEXTURE2DMS
257 %token KW_TEXTURE2DMSARRAY
258 %token KW_TEXTURE3D
259 %token KW_TEXTURE3DARRAY
260 %token KW_TEXTURECUBE
261 %token KW_TRUE
262 %token KW_TYPEDEF
263 %token KW_UNIFORM
264 %token KW_VECTOR
265 %token KW_VERTEXSHADER
266 %token KW_VOID
267 %token KW_VOLATILE
268 %token KW_WHILE
270 %token OP_INC
271 %token OP_DEC
272 %token OP_AND
273 %token OP_OR
274 %token OP_EQ
275 %token OP_LEFTSHIFT
276 %token OP_LEFTSHIFTASSIGN
277 %token OP_RIGHTSHIFT
278 %token OP_RIGHTSHIFTASSIGN
279 %token OP_ELLIPSIS
280 %token OP_LE
281 %token OP_GE
282 %token OP_NE
283 %token OP_ADDASSIGN
284 %token OP_SUBASSIGN
285 %token OP_MULASSIGN
286 %token OP_DIVASSIGN
287 %token OP_MODASSIGN
288 %token OP_ANDASSIGN
289 %token OP_ORASSIGN
290 %token OP_XORASSIGN
291 %token OP_UNKNOWN1
292 %token OP_UNKNOWN2
293 %token OP_UNKNOWN3
294 %token OP_UNKNOWN4
296 %token <intval> PRE_LINE
298 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
299 %type <name> any_identifier var_identifier
300 %token <name> STRING
301 %token <floatval> C_FLOAT
302 %token <intval> C_INTEGER
303 %type <boolval> boolean
304 %type <type> base_type
305 %type <type> type
306 %type <list> declaration_statement
307 %type <list> complex_initializer
308 %type <list> initializer_expr_list
309 %type <instr> initializer_expr
310 %type <modifiers> var_modifiers
311 %type <list> parameters
312 %type <list> param_list
313 %type <instr> expr
314 %type <var> variable
315 %type <intval> array
316 %type <list> statement
317 %type <list> statement_list
318 %type <list> compound_statement
319 %type <function> func_declaration
320 %type <function> func_prototype
321 %type <parameter> parameter
322 %type <name> semantic
323 %type <variable_def> variable_def
324 %type <list> variables_def
325 %type <instr> primary_expr
326 %type <instr> postfix_expr
327 %type <instr> unary_expr
328 %type <instr> mul_expr
329 %type <instr> add_expr
330 %type <instr> shift_expr
331 %type <instr> relational_expr
332 %type <instr> equality_expr
333 %type <instr> bitand_expr
334 %type <instr> bitxor_expr
335 %type <instr> bitor_expr
336 %type <instr> logicand_expr
337 %type <instr> logicor_expr
338 %type <instr> conditional_expr
339 %type <instr> assignment_expr
340 %type <list> expr_statement
341 %type <modifiers> input_mod
344 hlsl_prog: /* empty */
347 | hlsl_prog func_declaration
349 FIXME("Check that the function doesn't conflict with an already declared one.\n");
350 list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
352 | hlsl_prog declaration_statement
354 TRACE("Declaration statement parsed.\n");
356 | hlsl_prog preproc_directive
360 preproc_directive: PRE_LINE STRING
362 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
363 hlsl_ctx.line_no = $1;
364 if (strcmp($2, hlsl_ctx.source_file))
366 const char **new_array;
368 hlsl_ctx.source_file = $2;
369 new_array = d3dcompiler_realloc(hlsl_ctx.source_files,
370 sizeof(*hlsl_ctx.source_files) * hlsl_ctx.source_files_count + 1);
371 if (new_array)
373 hlsl_ctx.source_files = new_array;
374 hlsl_ctx.source_files[hlsl_ctx.source_files_count++] = $2;
379 any_identifier: VAR_IDENTIFIER
380 | TYPE_IDENTIFIER
381 | NEW_IDENTIFIER
383 func_declaration: func_prototype compound_statement
385 TRACE("Function %s parsed.\n", $1->name);
386 $$ = $1;
387 $$->body = $2;
388 pop_scope(&hlsl_ctx);
390 | func_prototype ';'
392 TRACE("Function prototype for %s.\n", $1->name);
393 $$ = $1;
394 pop_scope(&hlsl_ctx);
397 func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
399 $$ = new_func_decl($3, $2, $5);
400 if (!$$)
402 ERR("Out of memory.\n");
403 return -1;
405 $$->semantic = $7;
408 compound_statement: '{' '}'
410 $$ = d3dcompiler_alloc(sizeof(*$$));
411 list_init($$);
413 | '{' scope_start statement_list '}'
415 pop_scope(&hlsl_ctx);
416 $$ = $3;
419 scope_start: /* Empty */
421 push_scope(&hlsl_ctx);
424 var_identifier: VAR_IDENTIFIER
425 | NEW_IDENTIFIER
427 semantic: /* Empty */
429 $$ = NULL;
431 | ':' any_identifier
433 $$ = $2;
436 parameters: scope_start
438 $$ = d3dcompiler_alloc(sizeof(*$$));
439 list_init($$);
441 | scope_start param_list
443 $$ = $2;
446 param_list: parameter
448 $$ = d3dcompiler_alloc(sizeof(*$$));
449 list_init($$);
450 if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
452 ERR("Error adding function parameter %s.\n", $1.name);
453 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
454 return -1;
457 | param_list ',' parameter
459 $$ = $1;
460 if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
462 hlsl_message("Line %u: duplicate parameter %s.\n",
463 hlsl_ctx.line_no, $3.name);
464 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
465 return 1;
469 parameter: input_mod var_modifiers type any_identifier semantic
471 $$.modifiers = $1;
472 $$.modifiers |= $2;
473 $$.type = $3;
474 $$.name = $4;
475 $$.semantic = $5;
478 input_mod: /* Empty */
480 $$ = HLSL_MODIFIER_IN;
482 | KW_IN
484 $$ = HLSL_MODIFIER_IN;
486 | KW_OUT
488 $$ = HLSL_MODIFIER_OUT;
490 | KW_INOUT
492 $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
495 type: base_type
497 $$ = $1;
499 | KW_VECTOR '<' base_type ',' C_INTEGER '>'
501 if ($3->type != HLSL_CLASS_SCALAR)
503 hlsl_message("Line %u: vectors of non-scalar types are not allowed.\n",
504 hlsl_ctx.line_no);
505 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
506 return 1;
508 if ($5 < 1 || $5 > 4)
510 hlsl_message("Line %u: vector size must be between 1 and 4.\n",
511 hlsl_ctx.line_no);
512 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
513 return 1;
516 $$ = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, $3->base_type, $5, 1);
518 | KW_MATRIX '<' base_type ',' C_INTEGER ',' C_INTEGER '>'
520 if ($3->type != HLSL_CLASS_SCALAR)
522 hlsl_message("Line %u: matrices of non-scalar types are not allowed.\n",
523 hlsl_ctx.line_no);
524 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
525 return 1;
527 if ($5 < 1 || $5 > 4 || $7 < 1 || $7 > 4)
529 hlsl_message("Line %u: matrix dimensions must be between 1 and 4.\n",
530 hlsl_ctx.line_no);
531 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
532 return 1;
535 $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7);
538 base_type: KW_VOID
540 $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_SCALAR, HLSL_TYPE_VOID, 1, 1);
542 | KW_SAMPLER
544 $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
545 $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
547 | KW_SAMPLER1D
549 $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
550 $$->sampler_dim = HLSL_SAMPLER_DIM_1D;
552 | KW_SAMPLER2D
554 $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
555 $$->sampler_dim = HLSL_SAMPLER_DIM_2D;
557 | KW_SAMPLER3D
559 $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
560 $$->sampler_dim = HLSL_SAMPLER_DIM_3D;
562 | KW_SAMPLERCUBE
564 $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);
565 $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE;
567 | TYPE_IDENTIFIER
569 struct hlsl_type *type;
571 TRACE("Type %s.\n", $1);
572 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
573 $$ = type;
574 d3dcompiler_free($1);
576 | KW_STRUCT TYPE_IDENTIFIER
578 struct hlsl_type *type;
580 TRACE("Struct type %s.\n", $2);
581 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
582 if (type->type != HLSL_CLASS_STRUCT)
584 hlsl_message("Line %u: redefining %s as a structure.\n",
585 hlsl_ctx.line_no, $2);
586 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
588 else
590 $$ = type;
592 d3dcompiler_free($2);
595 declaration_statement: declaration
597 $$ = d3dcompiler_alloc(sizeof(*$$));
598 list_init($$);
601 declaration: var_modifiers type variables_def ';'
603 struct parse_variable_def *v, *v_next;
604 struct hlsl_ir_var *var;
605 BOOL ret, local = TRUE;
607 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
609 debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
610 var = d3dcompiler_alloc(sizeof(*var));
611 var->node.type = HLSL_IR_VAR;
612 if (v->array_size)
613 var->node.data_type = new_array_type($2, v->array_size);
614 else
615 var->node.data_type = $2;
616 var->name = v->name;
617 var->modifiers = $1;
618 var->semantic = v->semantic;
619 var->node.line = hlsl_ctx.line_no;
620 if (v->initializer)
622 FIXME("Variable with an initializer.\n");
623 free_instr_list(v->initializer);
626 if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
628 var->modifiers |= HLSL_STORAGE_UNIFORM;
629 local = FALSE;
632 ret = declare_variable(var, local);
633 if (ret == FALSE)
634 free_declaration(var);
635 else
636 TRACE("Declared variable %s.\n", var->name);
637 d3dcompiler_free(v);
639 d3dcompiler_free($3);
642 variables_def: variable_def
644 $$ = d3dcompiler_alloc(sizeof(*$$));
645 list_init($$);
646 list_add_head($$, &$1->entry);
648 | variables_def ',' variable_def
650 $$ = $1;
651 list_add_tail($$, &$3->entry);
654 /* FIXME: Local variables can't have semantics. */
655 variable_def: any_identifier array semantic
657 $$ = d3dcompiler_alloc(sizeof(*$$));
658 $$->name = $1;
659 $$->array_size = $2;
660 $$->semantic = $3;
662 | any_identifier array semantic '=' complex_initializer
664 TRACE("Declaration with initializer.\n");
665 $$ = d3dcompiler_alloc(sizeof(*$$));
666 $$->name = $1;
667 $$->array_size = $2;
668 $$->semantic = $3;
669 $$->initializer = $5;
672 array: /* Empty */
674 $$ = 0;
676 | '[' expr ']'
678 FIXME("Array.\n");
679 $$ = 0;
680 free_instr($2);
683 var_modifiers: /* Empty */
685 $$ = 0;
687 | KW_EXTERN var_modifiers
689 $$ = add_modifier($2, HLSL_STORAGE_EXTERN);
691 | KW_NOINTERPOLATION var_modifiers
693 $$ = add_modifier($2, HLSL_STORAGE_NOINTERPOLATION);
695 | KW_PRECISE var_modifiers
697 $$ = add_modifier($2, HLSL_MODIFIER_PRECISE);
699 | KW_SHARED var_modifiers
701 $$ = add_modifier($2, HLSL_STORAGE_SHARED);
703 | KW_GROUPSHARED var_modifiers
705 $$ = add_modifier($2, HLSL_STORAGE_GROUPSHARED);
707 | KW_STATIC var_modifiers
709 $$ = add_modifier($2, HLSL_STORAGE_STATIC);
711 | KW_UNIFORM var_modifiers
713 $$ = add_modifier($2, HLSL_STORAGE_UNIFORM);
715 | KW_VOLATILE var_modifiers
717 $$ = add_modifier($2, HLSL_STORAGE_VOLATILE);
719 | KW_CONST var_modifiers
721 $$ = add_modifier($2, HLSL_MODIFIER_CONST);
723 | KW_ROW_MAJOR var_modifiers
725 $$ = add_modifier($2, HLSL_MODIFIER_ROW_MAJOR);
727 | KW_COLUMN_MAJOR var_modifiers
729 $$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
732 complex_initializer: initializer_expr
734 $$ = d3dcompiler_alloc(sizeof(*$$));
735 list_init($$);
736 list_add_head($$, &$1->entry);
738 | '{' initializer_expr_list '}'
740 $$ = $2;
743 initializer_expr: assignment_expr
745 $$ = $1;
748 initializer_expr_list: initializer_expr
750 $$ = d3dcompiler_alloc(sizeof(*$$));
751 list_init($$);
752 list_add_head($$, &$1->entry);
754 | initializer_expr_list ',' initializer_expr
756 $$ = $1;
757 list_add_tail($$, &$3->entry);
760 boolean: KW_TRUE
762 $$ = TRUE;
764 | KW_FALSE
766 $$ = FALSE;
769 statement_list: statement
771 $$ = $1;
773 | statement_list statement
775 $$ = $1;
776 list_move_tail($$, $2);
777 d3dcompiler_free($2);
780 statement: declaration_statement
782 $$ = $1;
784 | expr_statement
786 $$ = $1;
788 | compound_statement
790 $$ = $1;
793 expr_statement: ';'
795 $$ = d3dcompiler_alloc(sizeof(*$$));
796 list_init($$);
798 | expr ';'
800 $$ = d3dcompiler_alloc(sizeof(*$$));
801 list_init($$);
802 if ($1)
803 list_add_head($$, &$1->entry);
806 primary_expr: C_FLOAT
808 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
809 if (!c)
811 ERR("Out of memory.\n");
812 return -1;
814 c->node.type = HLSL_IR_CONSTANT;
815 c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
816 c->v.value.f[0] = $1;
817 $$ = &c->node;
819 | C_INTEGER
821 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
822 if (!c)
824 ERR("Out of memory.\n");
825 return -1;
827 c->node.type = HLSL_IR_CONSTANT;
828 c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
829 c->v.value.i[0] = $1;
830 $$ = &c->node;
832 | boolean
834 struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
835 if (!c)
837 ERR("Out of memory.\n");
838 return -1;
840 c->node.type = HLSL_IR_CONSTANT;
841 c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
842 c->v.value.b[0] = $1;
843 $$ = &c->node;
845 | variable
847 struct hlsl_ir_deref *deref = new_var_deref($1);
848 $$ = deref ? &deref->node : NULL;
850 | '(' expr ')'
852 $$ = $2;
855 variable: VAR_IDENTIFIER
857 struct hlsl_ir_var *var;
858 var = get_variable(hlsl_ctx.cur_scope, $1);
859 if (!var)
861 hlsl_message("Line %d: variable '%s' not declared\n",
862 hlsl_ctx.line_no, $1);
863 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
864 return 1;
866 $$ = var;
869 postfix_expr: primary_expr
871 $$ = $1;
873 /* "var_modifiers" doesn't make sense in this case, but it's needed
874 in the grammar to avoid shift/reduce conflicts. */
875 | var_modifiers type '(' initializer_expr_list ')'
877 struct hlsl_ir_constructor *constructor;
879 TRACE("%s constructor.\n", debug_hlsl_type($2));
880 if ($1)
882 hlsl_message("Line %u: unexpected modifier in a constructor.\n",
883 hlsl_ctx.line_no);
884 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
885 return -1;
887 if ($2->type > HLSL_CLASS_LAST_NUMERIC)
889 hlsl_message("Line %u: constructors are allowed only for numeric data types.\n",
890 hlsl_ctx.line_no);
891 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
892 return -1;
894 if ($2->dimx * $2->dimy != components_count_expr_list($4))
896 hlsl_message("Line %u: wrong number of components in constructor.\n",
897 hlsl_ctx.line_no);
898 set_parse_status(&hlsl_ctx.status, PARSE_ERR);
899 return -1;
902 constructor = d3dcompiler_alloc(sizeof(*constructor));
903 constructor->node.type = HLSL_IR_CONSTRUCTOR;
904 constructor->node.data_type = $2;
905 constructor->arguments = $4;
907 $$ = &constructor->node;
910 unary_expr: postfix_expr
912 $$ = $1;
915 mul_expr: unary_expr
917 $$ = $1;
920 add_expr: mul_expr
922 $$ = $1;
925 shift_expr: add_expr
927 $$ = $1;
930 relational_expr: shift_expr
932 $$ = $1;
935 equality_expr: relational_expr
937 $$ = $1;
940 bitand_expr: equality_expr
942 $$ = $1;
945 bitxor_expr: bitand_expr
947 $$ = $1;
950 bitor_expr: bitxor_expr
952 $$ = $1;
955 logicand_expr: bitor_expr
957 $$ = $1;
960 logicor_expr: logicand_expr
962 $$ = $1;
965 conditional_expr: logicor_expr
967 $$ = $1;
970 assignment_expr: conditional_expr
972 $$ = $1;
975 expr: assignment_expr
977 $$ = $1;
979 | expr ',' assignment_expr
981 FIXME("Comma expression\n");
986 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD major, DWORD minor,
987 const char *entrypoint, char **messages)
989 struct hlsl_ir_function_decl *function;
990 struct hlsl_scope *scope, *next_scope;
991 struct hlsl_type *hlsl_type, *next_type;
992 struct hlsl_ir_var *var, *next_var;
993 unsigned int i;
995 hlsl_ctx.status = PARSE_SUCCESS;
996 hlsl_ctx.messages.size = hlsl_ctx.messages.capacity = 0;
997 hlsl_ctx.line_no = hlsl_ctx.column = 1;
998 hlsl_ctx.source_file = d3dcompiler_strdup("");
999 hlsl_ctx.source_files = d3dcompiler_alloc(sizeof(*hlsl_ctx.source_files));
1000 if (hlsl_ctx.source_files)
1001 hlsl_ctx.source_files[0] = hlsl_ctx.source_file;
1002 hlsl_ctx.source_files_count = 1;
1003 hlsl_ctx.cur_scope = NULL;
1004 hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
1005 list_init(&hlsl_ctx.scopes);
1006 list_init(&hlsl_ctx.types);
1007 list_init(&hlsl_ctx.functions);
1009 push_scope(&hlsl_ctx);
1010 hlsl_ctx.globals = hlsl_ctx.cur_scope;
1012 hlsl_parse();
1014 if (TRACE_ON(hlsl_parser))
1016 struct hlsl_ir_function_decl *func;
1018 TRACE("IR dump.\n");
1019 LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1021 if (func->body)
1022 debug_dump_ir_function(func);
1026 TRACE("Compilation status = %d\n", hlsl_ctx.status);
1027 if (messages)
1029 if (hlsl_ctx.messages.size)
1030 *messages = hlsl_ctx.messages.string;
1031 else
1032 *messages = NULL;
1034 else
1036 if (hlsl_ctx.messages.capacity)
1037 d3dcompiler_free(hlsl_ctx.messages.string);
1040 for (i = 0; i < hlsl_ctx.source_files_count; ++i)
1041 d3dcompiler_free((void *)hlsl_ctx.source_files[i]);
1042 d3dcompiler_free(hlsl_ctx.source_files);
1044 TRACE("Freeing functions IR.\n");
1045 LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
1046 free_function(function);
1048 TRACE("Freeing variables.\n");
1049 LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
1051 LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
1053 free_declaration(var);
1055 d3dcompiler_free(scope);
1058 TRACE("Freeing types.\n");
1059 LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
1061 free_hlsl_type(hlsl_type);
1064 return NULL;