d3dcompiler: Parse variable declarations.
[wine] / dlls / d3dcompiler_43 / hlsl.y
1 /*
2  * HLSL parser
3  *
4  * Copyright 2008 Stefan Dösinger
5  * Copyright 2012 Matteo Bruni for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 %{
22 #include "config.h"
23 #include "wine/debug.h"
24
25 #include <stdio.h>
26
27 #include "d3dcompiler_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(hlsl_parser);
30
31 int hlsl_lex(void);
32
33 struct hlsl_parse_ctx hlsl_ctx;
34
35 void hlsl_message(const char *fmt, ...)
36 {
37     va_list args;
38
39     va_start(args, fmt);
40     compilation_message(&hlsl_ctx.messages, fmt, args);
41     va_end(args);
42 }
43
44 static void hlsl_error(const char *s)
45 {
46     hlsl_message("Line %u: %s\n", hlsl_ctx.line_no, s);
47     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
48 }
49
50 static void debug_dump_decl(struct hlsl_type *type, DWORD modifiers, const char *declname, unsigned int line_no)
51 {
52     TRACE("Line %u: ", line_no);
53     TRACE("%s %s;\n", debug_hlsl_type(type), declname);
54 }
55
56 static BOOL declare_variable(struct hlsl_ir_var *decl, BOOL local)
57 {
58     BOOL ret;
59
60     TRACE("Declaring variable %s.\n", decl->name);
61     ret = add_declaration(hlsl_ctx.cur_scope, decl, local);
62     if (ret == FALSE)
63     {
64         struct hlsl_ir_var *old = get_variable(hlsl_ctx.cur_scope, decl->name);
65
66         hlsl_message("Line %u: \"%s\" already declared.\n", hlsl_ctx.line_no, decl->name);
67         hlsl_message("Line %u: \"%s\" was previously declared here.\n", old->node.line, decl->name);
68         set_parse_status(&hlsl_ctx.status, PARSE_ERR);
69         return FALSE;
70     }
71     return TRUE;
72 }
73
74 %}
75
76 %error-verbose
77
78 %union
79 {
80     struct hlsl_type *type;
81     INT intval;
82     FLOAT floatval;
83     char *name;
84     DWORD modifiers;
85     struct list *list;
86     struct parse_variable_def *variable_def;
87 }
88
89 %token KW_BLENDSTATE
90 %token KW_BREAK
91 %token KW_BUFFER
92 %token KW_CBUFFER
93 %token KW_COLUMN_MAJOR
94 %token KW_COMPILE
95 %token KW_CONST
96 %token KW_CONTINUE
97 %token KW_DEPTHSTENCILSTATE
98 %token KW_DEPTHSTENCILVIEW
99 %token KW_DISCARD
100 %token KW_DO
101 %token KW_DOUBLE
102 %token KW_ELSE
103 %token KW_EXTERN
104 %token KW_FALSE
105 %token KW_FOR
106 %token KW_GEOMETRYSHADER
107 %token KW_GROUPSHARED
108 %token KW_IF
109 %token KW_IN
110 %token KW_INLINE
111 %token KW_INOUT
112 %token KW_MATRIX
113 %token KW_NAMESPACE
114 %token KW_NOINTERPOLATION
115 %token KW_OUT
116 %token KW_PASS
117 %token KW_PIXELSHADER
118 %token KW_PRECISE
119 %token KW_RASTERIZERSTATE
120 %token KW_RENDERTARGETVIEW
121 %token KW_RETURN
122 %token KW_REGISTER
123 %token KW_ROW_MAJOR
124 %token KW_SAMPLER
125 %token KW_SAMPLER1D
126 %token KW_SAMPLER2D
127 %token KW_SAMPLER3D
128 %token KW_SAMPLERCUBE
129 %token KW_SAMPLER_STATE
130 %token KW_SAMPLERCOMPARISONSTATE
131 %token KW_SHARED
132 %token KW_STATEBLOCK
133 %token KW_STATEBLOCK_STATE
134 %token KW_STATIC
135 %token KW_STRING
136 %token KW_STRUCT
137 %token KW_SWITCH
138 %token KW_TBUFFER
139 %token KW_TECHNIQUE
140 %token KW_TECHNIQUE10
141 %token KW_TEXTURE
142 %token KW_TEXTURE1D
143 %token KW_TEXTURE1DARRAY
144 %token KW_TEXTURE2D
145 %token KW_TEXTURE2DARRAY
146 %token KW_TEXTURE2DMS
147 %token KW_TEXTURE2DMSARRAY
148 %token KW_TEXTURE3D
149 %token KW_TEXTURE3DARRAY
150 %token KW_TEXTURECUBE
151 %token KW_TRUE
152 %token KW_TYPEDEF
153 %token KW_UNIFORM
154 %token KW_VECTOR
155 %token KW_VERTEXSHADER
156 %token KW_VOID
157 %token KW_VOLATILE
158 %token KW_WHILE
159
160 %token OP_INC
161 %token OP_DEC
162 %token OP_AND
163 %token OP_OR
164 %token OP_EQ
165 %token OP_LEFTSHIFT
166 %token OP_LEFTSHIFTASSIGN
167 %token OP_RIGHTSHIFT
168 %token OP_RIGHTSHIFTASSIGN
169 %token OP_ELLIPSIS
170 %token OP_LE
171 %token OP_GE
172 %token OP_LT
173 %token OP_GT
174 %token OP_NE
175 %token OP_ADDASSIGN
176 %token OP_SUBASSIGN
177 %token OP_MULASSIGN
178 %token OP_DIVASSIGN
179 %token OP_MODASSIGN
180 %token OP_ANDASSIGN
181 %token OP_ORASSIGN
182 %token OP_XORASSIGN
183 %token OP_UNKNOWN1
184 %token OP_UNKNOWN2
185 %token OP_UNKNOWN3
186 %token OP_UNKNOWN4
187
188 %token <intval> PRE_LINE
189
190 %token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
191 %type <name> any_identifier
192 %token <name> STRING
193 %token <floatval> C_FLOAT
194 %token <intval> C_INTEGER
195 %type <type> base_type
196 %type <type> type
197 %type <modifiers> var_modifiers
198 %type <intval> array
199 %type <name> semantic
200 %type <variable_def> variable_def
201 %type <list> variables_def
202 %%
203
204 hlsl_prog:                /* empty */
205                             {
206                             }
207                         | hlsl_prog declaration_statement
208                             {
209                                 TRACE("Declaration statement parsed.\n");
210                             }
211                         | hlsl_prog preproc_directive
212                             {
213                             }
214
215 preproc_directive:        PRE_LINE STRING
216                             {
217                                 TRACE("Updating line information to file %s, line %u\n", debugstr_a($2), $1);
218                                 hlsl_ctx.line_no = $1 - 1;
219                                 d3dcompiler_free(hlsl_ctx.source_file);
220                                 hlsl_ctx.source_file = $2;
221                             }
222
223 any_identifier:           VAR_IDENTIFIER
224                         | TYPE_IDENTIFIER
225                         | NEW_IDENTIFIER
226
227 semantic:                 /* Empty */
228                             {
229                                 $$ = NULL;
230                             }
231                         | ':' any_identifier
232                             {
233                                 $$ = $2;
234                             }
235
236 type:                     base_type
237                             {
238                                 $$ = $1;
239                             }
240
241 base_type:                KW_VOID
242                             {
243                                 $$ = new_hlsl_type("void", HLSL_TYPE_VOID, 1, 1);
244                             }
245                         | TYPE_IDENTIFIER
246                             {
247                                 struct hlsl_type *type;
248
249                                 TRACE("Type %s.\n", $1);
250                                 type = get_type(hlsl_ctx.cur_scope, $1, TRUE);
251                                 $$ = type;
252                                 d3dcompiler_free($1);
253                             }
254                         | KW_STRUCT TYPE_IDENTIFIER
255                             {
256                                 struct hlsl_type *type;
257
258                                 TRACE("Struct type %s.\n", $2);
259                                 type = get_type(hlsl_ctx.cur_scope, $2, TRUE);
260                                 if (type->base_type != HLSL_TYPE_STRUCT)
261                                 {
262                                     hlsl_message("Line %u: Redefining %s as a structure.\n",
263                                             hlsl_ctx.line_no, $2);
264                                     set_parse_status(&hlsl_ctx.status, PARSE_ERR);
265                                 }
266                                 else
267                                 {
268                                     $$ = type;
269                                 }
270                                 d3dcompiler_free($2);
271                             }
272
273 declaration_statement:    declaration
274                             {
275                             }
276
277 declaration:              var_modifiers type variables_def ';'
278                             {
279                                 struct parse_variable_def *v, *v_next;
280                                 struct hlsl_ir_var *var;
281                                 BOOL ret, local = TRUE;
282
283                                 LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
284                                 {
285                                     debug_dump_decl($2, $1, v->name, hlsl_ctx.line_no);
286                                     var = d3dcompiler_alloc(sizeof(*var));
287                                     var->node.type = HLSL_IR_VAR;
288                                     if (v->array_size)
289                                         var->node.data_type = new_array_type($2, v->array_size);
290                                     else
291                                         var->node.data_type = $2;
292                                     var->name = v->name;
293                                     var->modifiers = $1;
294                                     var->semantic = v->semantic;
295                                     var->node.line = hlsl_ctx.line_no;
296                                     if (v->initializer)
297                                     {
298                                         FIXME("Variable with an initializer.\n");
299                                     }
300
301                                     ret = declare_variable(var, local);
302                                     if (ret == FALSE)
303                                         free_declaration(var);
304                                     else
305                                         TRACE("Declared variable %s.\n", var->name);
306                                     d3dcompiler_free(v);
307                                 }
308                                 d3dcompiler_free($3);
309                             }
310
311 variables_def:            variable_def
312                             {
313                                 $$ = d3dcompiler_alloc(sizeof(*$$));
314                                 list_init($$);
315                                 list_add_head($$, &$1->entry);
316                             }
317                         | variables_def ',' variable_def
318                             {
319                                 $$ = $1;
320                                 list_add_tail($$, &$3->entry);
321                             }
322
323                           /* FIXME: Local variables can't have semantics. */
324 variable_def:             any_identifier array semantic
325                             {
326                                 $$ = d3dcompiler_alloc(sizeof(*$$));
327                                 $$->name = $1;
328                                 $$->array_size = $2;
329                                 $$->semantic = $3;
330                             }
331
332 array:                    /* Empty */
333                             {
334                                 $$ = 0;
335                             }
336
337 var_modifiers:            /* Empty */
338                             {
339                                 $$ = 0;
340                             }
341
342 %%
343
344 struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
345 {
346     struct hlsl_scope *scope, *next_scope;
347     struct hlsl_type *hlsl_type, *next_type;
348     struct hlsl_ir_var *var, *next_var;
349
350     hlsl_ctx.line_no = 1;
351     hlsl_ctx.source_file = d3dcompiler_strdup("");
352     hlsl_ctx.cur_scope = NULL;
353     hlsl_ctx.matrix_majority = HLSL_COLUMN_MAJOR;
354     list_init(&hlsl_ctx.scopes);
355     list_init(&hlsl_ctx.types);
356     list_init(&hlsl_ctx.functions);
357
358     push_scope(&hlsl_ctx);
359     hlsl_ctx.globals = hlsl_ctx.cur_scope;
360
361     hlsl_parse();
362
363     d3dcompiler_free(hlsl_ctx.source_file);
364
365     TRACE("Freeing variables.\n");
366     LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
367     {
368         LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry)
369         {
370             free_declaration(var);
371         }
372         d3dcompiler_free(scope);
373     }
374
375     TRACE("Freeing types.\n");
376     LIST_FOR_EACH_ENTRY_SAFE(hlsl_type, next_type, &hlsl_ctx.types, struct hlsl_type, entry)
377     {
378         free_hlsl_type(hlsl_type);
379     }
380
381     return NULL;
382 }