glsl: Refactor variable declaration handling.
[mesa.git] / src / glsl / ir_reader.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <cstdarg>
25
26 extern "C" {
27 #include <talloc.h>
28 }
29
30 #include "ir_reader.h"
31 #include "glsl_parser_extras.h"
32 #include "glsl_types.h"
33 #include "s_expression.h"
34
35 static void ir_read_error(_mesa_glsl_parse_state *, s_expression *,
36 const char *fmt, ...);
37 static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *);
38
39 static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *,
40 s_expression *);
41 static ir_function *read_function(_mesa_glsl_parse_state *, s_list *,
42 bool skip_body);
43 static void read_function_sig(_mesa_glsl_parse_state *, ir_function *,
44 s_list *, bool skip_body);
45
46 static void read_instructions(_mesa_glsl_parse_state *, exec_list *,
47 s_expression *, ir_loop *);
48 static ir_instruction *read_instruction(_mesa_glsl_parse_state *,
49 s_expression *, ir_loop *);
50 static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_list *);
51 static ir_if *read_if(_mesa_glsl_parse_state *, s_list *, ir_loop *);
52 static ir_loop *read_loop(_mesa_glsl_parse_state *st, s_list *list);
53 static ir_return *read_return(_mesa_glsl_parse_state *, s_list *);
54
55 static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *);
56 static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *);
57 static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *);
58 static ir_call *read_call(_mesa_glsl_parse_state *, s_list *);
59 static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *);
60 static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *);
61 static ir_texture *read_texture(_mesa_glsl_parse_state *, s_list *);
62
63 static ir_dereference *read_dereference(_mesa_glsl_parse_state *,
64 s_expression *);
65 static ir_dereference *read_var_ref(_mesa_glsl_parse_state *, s_list *);
66 static ir_dereference *read_array_ref(_mesa_glsl_parse_state *, s_list *);
67 static ir_dereference *read_record_ref(_mesa_glsl_parse_state *, s_list *);
68
69 void
70 _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions,
71 const char *src, bool scan_for_protos)
72 {
73 s_expression *expr = s_expression::read_expression(state, src);
74 if (expr == NULL) {
75 ir_read_error(state, NULL, "couldn't parse S-Expression.");
76 return;
77 }
78
79 if (scan_for_protos) {
80 scan_for_prototypes(state, instructions, expr);
81 if (state->error)
82 return;
83 }
84
85 read_instructions(state, instructions, expr, NULL);
86 talloc_free(expr);
87 }
88
89 static void
90 ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr,
91 const char *fmt, ...)
92 {
93 va_list ap;
94
95 state->error = true;
96
97 state->info_log = talloc_strdup_append(state->info_log, "error: ");
98
99 va_start(ap, fmt);
100 state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
101 va_end(ap);
102 state->info_log = talloc_strdup_append(state->info_log, "\n");
103
104 if (expr != NULL) {
105 state->info_log = talloc_strdup_append(state->info_log,
106 "...in this context:\n ");
107 expr->print();
108 state->info_log = talloc_strdup_append(state->info_log, "\n\n");
109 }
110 }
111
112 static const glsl_type *
113 read_type(_mesa_glsl_parse_state *st, s_expression *expr)
114 {
115 s_list *list = SX_AS_LIST(expr);
116 if (list != NULL) {
117 s_symbol *type_sym = SX_AS_SYMBOL(list->subexpressions.get_head());
118 if (type_sym == NULL) {
119 ir_read_error(st, expr, "expected type (array ...) or (struct ...)");
120 return NULL;
121 }
122 if (strcmp(type_sym->value(), "array") == 0) {
123 if (list->length() != 3) {
124 ir_read_error(st, expr, "expected type (array <type> <int>)");
125 return NULL;
126 }
127
128 // Read base type
129 s_expression *base_expr = (s_expression*) type_sym->next;
130 const glsl_type *base_type = read_type(st, base_expr);
131 if (base_type == NULL) {
132 ir_read_error(st, NULL, "when reading base type of array");
133 return NULL;
134 }
135
136 // Read array size
137 s_int *size = SX_AS_INT(base_expr->next);
138 if (size == NULL) {
139 ir_read_error(st, expr, "found non-integer array size");
140 return NULL;
141 }
142
143 return glsl_type::get_array_instance(base_type, size->value());
144 } else if (strcmp(type_sym->value(), "struct") == 0) {
145 assert(false); // FINISHME
146 } else {
147 ir_read_error(st, expr, "expected (array ...) or (struct ...); "
148 "found (%s ...)", type_sym->value());
149 return NULL;
150 }
151 }
152
153 s_symbol *type_sym = SX_AS_SYMBOL(expr);
154 if (type_sym == NULL) {
155 ir_read_error(st, expr, "expected <type> (symbol or list)");
156 return NULL;
157 }
158
159 const glsl_type *type = st->symbols->get_type(type_sym->value());
160 if (type == NULL)
161 ir_read_error(st, expr, "invalid type: %s", type_sym->value());
162
163 return type;
164 }
165
166
167 static void
168 scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions,
169 s_expression *expr)
170 {
171 s_list *list = SX_AS_LIST(expr);
172 if (list == NULL) {
173 ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
174 return;
175 }
176
177 foreach_iter(exec_list_iterator, it, list->subexpressions) {
178 s_list *sub = SX_AS_LIST(it.get());
179 if (sub == NULL)
180 continue; // not a (function ...); ignore it.
181
182 s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head());
183 if (tag == NULL || strcmp(tag->value(), "function") != 0)
184 continue; // not a (function ...); ignore it.
185
186 ir_function *f = read_function(st, sub, true);
187 if (f == NULL)
188 return;
189 instructions->push_tail(f);
190 }
191 }
192
193 static ir_function *
194 read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body)
195 {
196 void *ctx = st;
197 bool added = false;
198 if (list->length() < 3) {
199 ir_read_error(st, list, "Expected (function <name> (signature ...) ...)");
200 return NULL;
201 }
202
203 s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
204 if (name == NULL) {
205 ir_read_error(st, list, "Expected (function <name> ...)");
206 return NULL;
207 }
208
209 ir_function *f = st->symbols->get_function(name->value());
210 if (f == NULL) {
211 f = new(ctx) ir_function(name->value());
212 added = st->symbols->add_function(f->name, f);
213 assert(added);
214 }
215
216 exec_list_iterator it = list->subexpressions.iterator();
217 it.next(); // skip "function" tag
218 it.next(); // skip function name
219 for (/* nothing */; it.has_next(); it.next()) {
220 s_list *siglist = SX_AS_LIST(it.get());
221 if (siglist == NULL) {
222 ir_read_error(st, list, "Expected (function (signature ...) ...)");
223 return NULL;
224 }
225
226 s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head());
227 if (tag == NULL || strcmp(tag->value(), "signature") != 0) {
228 ir_read_error(st, siglist, "Expected (signature ...)");
229 return NULL;
230 }
231
232 read_function_sig(st, f, siglist, skip_body);
233 }
234 return added ? f : NULL;
235 }
236
237 static void
238 read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list,
239 bool skip_body)
240 {
241 void *ctx = st;
242 if (list->length() != 4) {
243 ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
244 "(<instruction> ...))");
245 return;
246 }
247
248 s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
249 const glsl_type *return_type = read_type(st, type_expr);
250 if (return_type == NULL)
251 return;
252
253 s_list *paramlist = SX_AS_LIST(type_expr->next);
254 s_list *body_list = SX_AS_LIST(paramlist->next);
255 if (paramlist == NULL || body_list == NULL) {
256 ir_read_error(st, list, "Expected (signature <type> (parameters ...) "
257 "(<instruction> ...))");
258 return;
259 }
260 s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head());
261 if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) {
262 ir_read_error(st, paramlist, "Expected (parameters ...)");
263 return;
264 }
265
266 // Read the parameters list into a temporary place.
267 exec_list hir_parameters;
268 st->symbols->push_scope();
269
270 exec_list_iterator it = paramlist->subexpressions.iterator();
271 for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
272 s_list *decl = SX_AS_LIST(it.get());
273 ir_variable *var = read_declaration(st, decl);
274 if (var == NULL)
275 return;
276
277 hir_parameters.push_tail(var);
278 }
279
280 ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
281 if (sig == NULL && skip_body) {
282 /* If scanning for prototypes, generate a new signature. */
283 sig = new(ctx) ir_function_signature(return_type);
284 sig->is_built_in = true;
285 f->add_signature(sig);
286 } else if (sig != NULL) {
287 const char *badvar = sig->qualifiers_match(&hir_parameters);
288 if (badvar != NULL) {
289 ir_read_error(st, list, "function `%s' parameter `%s' qualifiers "
290 "don't match prototype", f->name, badvar);
291 return;
292 }
293
294 if (sig->return_type != return_type) {
295 ir_read_error(st, list, "function `%s' return type doesn't "
296 "match prototype", f->name);
297 return;
298 }
299 } else {
300 /* No prototype for this body exists - skip it. */
301 st->symbols->pop_scope();
302 return;
303 }
304 assert(sig != NULL);
305
306 sig->replace_parameters(&hir_parameters);
307
308 if (!skip_body && !body_list->subexpressions.is_empty()) {
309 if (sig->is_defined) {
310 ir_read_error(st, list, "function %s redefined", f->name);
311 return;
312 }
313 read_instructions(st, &sig->body, body_list, NULL);
314 sig->is_defined = true;
315 }
316
317 st->symbols->pop_scope();
318 }
319
320 static void
321 read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions,
322 s_expression *expr, ir_loop *loop_ctx)
323 {
324 // Read in a list of instructions
325 s_list *list = SX_AS_LIST(expr);
326 if (list == NULL) {
327 ir_read_error(st, expr, "Expected (<instruction> ...); found an atom.");
328 return;
329 }
330
331 foreach_iter(exec_list_iterator, it, list->subexpressions) {
332 s_expression *sub = (s_expression*) it.get();
333 ir_instruction *ir = read_instruction(st, sub, loop_ctx);
334 if (ir != NULL)
335 instructions->push_tail(ir);
336 }
337 }
338
339
340 static ir_instruction *
341 read_instruction(_mesa_glsl_parse_state *st, s_expression *expr,
342 ir_loop *loop_ctx)
343 {
344 void *ctx = st;
345 s_symbol *symbol = SX_AS_SYMBOL(expr);
346 if (symbol != NULL) {
347 if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL)
348 return new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
349 if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL)
350 return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
351 }
352
353 s_list *list = SX_AS_LIST(expr);
354 if (list == NULL || list->subexpressions.is_empty()) {
355 ir_read_error(st, expr, "Invalid instruction.\n");
356 return NULL;
357 }
358
359 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
360 if (tag == NULL) {
361 ir_read_error(st, expr, "expected instruction tag");
362 return NULL;
363 }
364
365 ir_instruction *inst = NULL;
366 if (strcmp(tag->value(), "declare") == 0) {
367 inst = read_declaration(st, list);
368 } else if (strcmp(tag->value(), "assign") == 0) {
369 inst = read_assignment(st, list);
370 } else if (strcmp(tag->value(), "if") == 0) {
371 inst = read_if(st, list, loop_ctx);
372 } else if (strcmp(tag->value(), "loop") == 0) {
373 inst = read_loop(st, list);
374 } else if (strcmp(tag->value(), "return") == 0) {
375 inst = read_return(st, list);
376 } else if (strcmp(tag->value(), "function") == 0) {
377 inst = read_function(st, list, false);
378 } else {
379 inst = read_rvalue(st, list);
380 if (inst == NULL)
381 ir_read_error(st, NULL, "when reading instruction");
382 }
383 return inst;
384 }
385
386
387 static ir_variable *
388 read_declaration(_mesa_glsl_parse_state *st, s_list *list)
389 {
390 void *ctx = st;
391 if (list->length() != 4) {
392 ir_read_error(st, list, "expected (declare (<qualifiers>) <type> "
393 "<name>)");
394 return NULL;
395 }
396
397 s_list *quals = SX_AS_LIST(list->subexpressions.head->next);
398 if (quals == NULL) {
399 ir_read_error(st, list, "expected a list of variable qualifiers");
400 return NULL;
401 }
402
403 s_expression *type_expr = (s_expression*) quals->next;
404 const glsl_type *type = read_type(st, type_expr);
405 if (type == NULL)
406 return NULL;
407
408 s_symbol *var_name = SX_AS_SYMBOL(type_expr->next);
409 if (var_name == NULL) {
410 ir_read_error(st, list, "expected variable name, found non-symbol");
411 return NULL;
412 }
413
414 ir_variable *var = new(ctx) ir_variable(type, var_name->value(),
415 ir_var_auto);
416
417 foreach_iter(exec_list_iterator, it, quals->subexpressions) {
418 s_symbol *qualifier = SX_AS_SYMBOL(it.get());
419 if (qualifier == NULL) {
420 ir_read_error(st, list, "qualifier list must contain only symbols");
421 delete var;
422 return NULL;
423 }
424
425 // FINISHME: Check for duplicate/conflicting qualifiers.
426 if (strcmp(qualifier->value(), "centroid") == 0) {
427 var->centroid = 1;
428 } else if (strcmp(qualifier->value(), "invariant") == 0) {
429 var->invariant = 1;
430 } else if (strcmp(qualifier->value(), "uniform") == 0) {
431 var->mode = ir_var_uniform;
432 } else if (strcmp(qualifier->value(), "auto") == 0) {
433 var->mode = ir_var_auto;
434 } else if (strcmp(qualifier->value(), "in") == 0) {
435 var->mode = ir_var_in;
436 } else if (strcmp(qualifier->value(), "out") == 0) {
437 var->mode = ir_var_out;
438 } else if (strcmp(qualifier->value(), "inout") == 0) {
439 var->mode = ir_var_inout;
440 } else if (strcmp(qualifier->value(), "smooth") == 0) {
441 var->interpolation = ir_var_smooth;
442 } else if (strcmp(qualifier->value(), "flat") == 0) {
443 var->interpolation = ir_var_flat;
444 } else if (strcmp(qualifier->value(), "noperspective") == 0) {
445 var->interpolation = ir_var_noperspective;
446 } else {
447 ir_read_error(st, list, "unknown qualifier: %s", qualifier->value());
448 delete var;
449 return NULL;
450 }
451 }
452
453 // Add the variable to the symbol table
454 st->symbols->add_variable(var->name, var);
455
456 return var;
457 }
458
459
460 static ir_if *
461 read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx)
462 {
463 void *ctx = st;
464 if (list->length() != 4) {
465 ir_read_error(st, list, "expected (if <condition> (<then> ...) "
466 "(<else> ...))");
467 return NULL;
468 }
469
470 s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
471 ir_rvalue *condition = read_rvalue(st, cond_expr);
472 if (condition == NULL) {
473 ir_read_error(st, NULL, "when reading condition of (if ...)");
474 return NULL;
475 }
476
477 s_expression *then_expr = (s_expression*) cond_expr->next;
478 s_expression *else_expr = (s_expression*) then_expr->next;
479
480 ir_if *iff = new(ctx) ir_if(condition);
481
482 read_instructions(st, &iff->then_instructions, then_expr, loop_ctx);
483 read_instructions(st, &iff->else_instructions, else_expr, loop_ctx);
484 if (st->error) {
485 delete iff;
486 iff = NULL;
487 }
488 return iff;
489 }
490
491
492 static ir_loop *
493 read_loop(_mesa_glsl_parse_state *st, s_list *list)
494 {
495 void *ctx = st;
496 if (list->length() != 6) {
497 ir_read_error(st, list, "expected (loop <counter> <from> <to> "
498 "<increment> <body>)");
499 return NULL;
500 }
501
502 s_expression *count_expr = (s_expression*) list->subexpressions.head->next;
503 s_expression *from_expr = (s_expression*) count_expr->next;
504 s_expression *to_expr = (s_expression*) from_expr->next;
505 s_expression *inc_expr = (s_expression*) to_expr->next;
506 s_expression *body_expr = (s_expression*) inc_expr->next;
507
508 // FINISHME: actually read the count/from/to fields.
509
510 ir_loop *loop = new(ctx) ir_loop;
511 read_instructions(st, &loop->body_instructions, body_expr, loop);
512 if (st->error) {
513 delete loop;
514 loop = NULL;
515 }
516 return loop;
517 }
518
519
520 static ir_return *
521 read_return(_mesa_glsl_parse_state *st, s_list *list)
522 {
523 void *ctx = st;
524 if (list->length() != 2) {
525 ir_read_error(st, list, "expected (return <rvalue>)");
526 return NULL;
527 }
528
529 s_expression *expr = (s_expression*) list->subexpressions.head->next;
530
531 ir_rvalue *retval = read_rvalue(st, expr);
532 if (retval == NULL) {
533 ir_read_error(st, NULL, "when reading return value");
534 return NULL;
535 }
536
537 return new(ctx) ir_return(retval);
538 }
539
540
541 static ir_rvalue *
542 read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr)
543 {
544 s_list *list = SX_AS_LIST(expr);
545 if (list == NULL || list->subexpressions.is_empty())
546 return NULL;
547
548 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head());
549 if (tag == NULL) {
550 ir_read_error(st, expr, "expected rvalue tag");
551 return NULL;
552 }
553
554 ir_rvalue *rvalue = read_dereference(st, list);
555 if (rvalue != NULL || st->error)
556 return rvalue;
557 else if (strcmp(tag->value(), "swiz") == 0) {
558 rvalue = read_swizzle(st, list);
559 } else if (strcmp(tag->value(), "expression") == 0) {
560 rvalue = read_expression(st, list);
561 } else if (strcmp(tag->value(), "call") == 0) {
562 rvalue = read_call(st, list);
563 } else if (strcmp(tag->value(), "constant") == 0) {
564 rvalue = read_constant(st, list);
565 } else {
566 rvalue = read_texture(st, list);
567 if (rvalue == NULL && !st->error)
568 ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value());
569 }
570
571 return rvalue;
572 }
573
574 static ir_assignment *
575 read_assignment(_mesa_glsl_parse_state *st, s_list *list)
576 {
577 void *ctx = st;
578 if (list->length() != 4) {
579 ir_read_error(st, list, "expected (assign <condition> <lhs> <rhs>)");
580 return NULL;
581 }
582
583 s_expression *cond_expr = (s_expression*) list->subexpressions.head->next;
584 s_expression *lhs_expr = (s_expression*) cond_expr->next;
585 s_expression *rhs_expr = (s_expression*) lhs_expr->next;
586
587 // FINISHME: Deal with "true" condition
588 ir_rvalue *condition = read_rvalue(st, cond_expr);
589 if (condition == NULL) {
590 ir_read_error(st, NULL, "when reading condition of assignment");
591 return NULL;
592 }
593
594 ir_rvalue *lhs = read_rvalue(st, lhs_expr);
595 if (lhs == NULL) {
596 ir_read_error(st, NULL, "when reading left-hand side of assignment");
597 return NULL;
598 }
599
600 ir_rvalue *rhs = read_rvalue(st, rhs_expr);
601 if (rhs == NULL) {
602 ir_read_error(st, NULL, "when reading right-hand side of assignment");
603 return NULL;
604 }
605
606 return new(ctx) ir_assignment(lhs, rhs, condition);
607 }
608
609 static ir_call *
610 read_call(_mesa_glsl_parse_state *st, s_list *list)
611 {
612 void *ctx = st;
613 if (list->length() != 3) {
614 ir_read_error(st, list, "expected (call <name> (<param> ...))");
615 return NULL;
616 }
617
618 s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next);
619 s_list *params = SX_AS_LIST(name->next);
620 if (name == NULL || params == NULL) {
621 ir_read_error(st, list, "expected (call <name> (<param> ...))");
622 return NULL;
623 }
624
625 exec_list parameters;
626
627 foreach_iter(exec_list_iterator, it, params->subexpressions) {
628 s_expression *expr = (s_expression*) it.get();
629 ir_rvalue *param = read_rvalue(st, expr);
630 if (param == NULL) {
631 ir_read_error(st, list, "when reading parameter to function call");
632 return NULL;
633 }
634 parameters.push_tail(param);
635 }
636
637 ir_function *f = st->symbols->get_function(name->value());
638 if (f == NULL) {
639 ir_read_error(st, list, "found call to undefined function %s",
640 name->value());
641 return NULL;
642 }
643
644 ir_function_signature *callee = f->matching_signature(&parameters);
645 if (callee == NULL) {
646 ir_read_error(st, list, "couldn't find matching signature for function "
647 "%s", name->value());
648 return NULL;
649 }
650
651 return new(ctx) ir_call(callee, &parameters);
652 }
653
654 static ir_expression *
655 read_expression(_mesa_glsl_parse_state *st, s_list *list)
656 {
657 void *ctx = st;
658 const unsigned list_length = list->length();
659 if (list_length < 4) {
660 ir_read_error(st, list, "expected (expression <type> <operator> "
661 "<operand> [<operand>])");
662 return NULL;
663 }
664
665 s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
666 const glsl_type *type = read_type(st, type_expr);
667 if (type == NULL)
668 return NULL;
669
670 /* Read the operator */
671 s_symbol *op_sym = SX_AS_SYMBOL(type_expr->next);
672 if (op_sym == NULL) {
673 ir_read_error(st, list, "expected operator, found non-symbol");
674 return NULL;
675 }
676
677 ir_expression_operation op = ir_expression::get_operator(op_sym->value());
678 if (op == (ir_expression_operation) -1) {
679 ir_read_error(st, list, "invalid operator: %s", op_sym->value());
680 return NULL;
681 }
682
683 /* Now that we know the operator, check for the right number of operands */
684 if (ir_expression::get_num_operands(op) == 2) {
685 if (list_length != 5) {
686 ir_read_error(st, list, "expected (expression <type> %s <operand> "
687 " <operand>)", op_sym->value());
688 return NULL;
689 }
690 } else {
691 if (list_length != 4) {
692 ir_read_error(st, list, "expected (expression <type> %s <operand>)",
693 op_sym->value());
694 return NULL;
695 }
696 }
697
698 s_expression *exp1 = (s_expression*) (op_sym->next);
699 ir_rvalue *arg1 = read_rvalue(st, exp1);
700 if (arg1 == NULL) {
701 ir_read_error(st, NULL, "when reading first operand of %s",
702 op_sym->value());
703 return NULL;
704 }
705
706 ir_rvalue *arg2 = NULL;
707 if (ir_expression::get_num_operands(op) == 2) {
708 s_expression *exp2 = (s_expression*) (exp1->next);
709 arg2 = read_rvalue(st, exp2);
710 if (arg2 == NULL) {
711 ir_read_error(st, NULL, "when reading second operand of %s",
712 op_sym->value());
713 return NULL;
714 }
715 }
716
717 return new(ctx) ir_expression(op, type, arg1, arg2);
718 }
719
720 static ir_swizzle *
721 read_swizzle(_mesa_glsl_parse_state *st, s_list *list)
722 {
723 if (list->length() != 3) {
724 ir_read_error(st, list, "expected (swiz <swizzle> <rvalue>)");
725 return NULL;
726 }
727
728 s_symbol *swiz = SX_AS_SYMBOL(list->subexpressions.head->next);
729 if (swiz == NULL) {
730 ir_read_error(st, list, "expected a valid swizzle; found non-symbol");
731 return NULL;
732 }
733
734 if (strlen(swiz->value()) > 4) {
735 ir_read_error(st, list, "expected a valid swizzle; found %s",
736 swiz->value());
737 return NULL;
738 }
739
740 s_expression *sub = (s_expression*) swiz->next;
741 if (sub == NULL) {
742 ir_read_error(st, list, "expected rvalue: (swizzle %s <rvalue>)",
743 swiz->value());
744 return NULL;
745 }
746
747 ir_rvalue *rvalue = read_rvalue(st, sub);
748 if (rvalue == NULL)
749 return NULL;
750
751 ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(),
752 rvalue->type->vector_elements);
753 if (ir == NULL)
754 ir_read_error(st, list, "invalid swizzle");
755
756 return ir;
757 }
758
759 static ir_constant *
760 read_constant(_mesa_glsl_parse_state *st, s_list *list)
761 {
762 void *ctx = st;
763 if (list->length() != 3) {
764 ir_read_error(st, list, "expected (constant <type> (...))");
765 return NULL;
766 }
767
768 s_expression *type_expr = (s_expression*) list->subexpressions.head->next;
769 const glsl_type *type = read_type(st, type_expr);
770 if (type == NULL)
771 return NULL;
772
773 s_list *values = SX_AS_LIST(type_expr->next);
774 if (values == NULL) {
775 ir_read_error(st, list, "expected (constant <type> (...))");
776 return NULL;
777 }
778
779 if (type->is_array()) {
780 const unsigned elements_supplied = values->length();
781 if (elements_supplied != type->length) {
782 ir_read_error(st, values, "expected exactly %u array elements, "
783 "given %u", type->length, elements_supplied);
784 return NULL;
785 }
786
787 exec_list elements;
788 foreach_iter(exec_list_iterator, it, values->subexpressions) {
789 s_expression *expr = (s_expression *) it.get();
790 s_list *elt = SX_AS_LIST(expr);
791 if (elt == NULL) {
792 ir_read_error(st, expr, "expected (constant ...) array element");
793 return NULL;
794 }
795
796 ir_constant *ir_elt = read_constant(st, elt);
797 if (ir_elt == NULL)
798 return NULL;
799 elements.push_tail(ir_elt);
800 }
801 return new(ctx) ir_constant(type, &elements);
802 }
803
804 const glsl_type *const base_type = type->get_base_type();
805
806 ir_constant_data data;
807
808 // Read in list of values (at most 16).
809 int k = 0;
810 foreach_iter(exec_list_iterator, it, values->subexpressions) {
811 if (k >= 16) {
812 ir_read_error(st, values, "expected at most 16 numbers");
813 return NULL;
814 }
815
816 s_expression *expr = (s_expression*) it.get();
817
818 if (base_type->base_type == GLSL_TYPE_FLOAT) {
819 s_number *value = SX_AS_NUMBER(expr);
820 if (value == NULL) {
821 ir_read_error(st, values, "expected numbers");
822 return NULL;
823 }
824 data.f[k] = value->fvalue();
825 } else {
826 s_int *value = SX_AS_INT(expr);
827 if (value == NULL) {
828 ir_read_error(st, values, "expected integers");
829 return NULL;
830 }
831
832 switch (base_type->base_type) {
833 case GLSL_TYPE_UINT: {
834 data.u[k] = value->value();
835 break;
836 }
837 case GLSL_TYPE_INT: {
838 data.i[k] = value->value();
839 break;
840 }
841 case GLSL_TYPE_BOOL: {
842 data.b[k] = value->value();
843 break;
844 }
845 default:
846 ir_read_error(st, values, "unsupported constant type");
847 return NULL;
848 }
849 }
850 ++k;
851 }
852
853 return new(ctx) ir_constant(type, &data);
854 }
855
856 static ir_dereference *
857 read_dereference(_mesa_glsl_parse_state *st, s_expression *expr)
858 {
859 s_list *list = SX_AS_LIST(expr);
860 if (list == NULL || list->subexpressions.is_empty())
861 return NULL;
862
863 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
864 assert(tag != NULL);
865
866 if (strcmp(tag->value(), "var_ref") == 0)
867 return read_var_ref(st, list);
868 if (strcmp(tag->value(), "array_ref") == 0)
869 return read_array_ref(st, list);
870 if (strcmp(tag->value(), "record_ref") == 0)
871 return read_record_ref(st, list);
872 return NULL;
873 }
874
875 static ir_dereference *
876 read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
877 {
878 void *ctx = st;
879 if (list->length() != 2) {
880 ir_read_error(st, list, "expected (var_ref <variable name>)");
881 return NULL;
882 }
883 s_symbol *var_name = SX_AS_SYMBOL(list->subexpressions.head->next);
884 if (var_name == NULL) {
885 ir_read_error(st, list, "expected (var_ref <variable name>)");
886 return NULL;
887 }
888
889 ir_variable *var = st->symbols->get_variable(var_name->value());
890 if (var == NULL) {
891 ir_read_error(st, list, "undeclared variable: %s", var_name->value());
892 return NULL;
893 }
894
895 return new(ctx) ir_dereference_variable(var);
896 }
897
898 static ir_dereference *
899 read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
900 {
901 void *ctx = st;
902 if (list->length() != 3) {
903 ir_read_error(st, list, "expected (array_ref <rvalue> <index>)");
904 return NULL;
905 }
906
907 s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
908 ir_rvalue *subject = read_rvalue(st, subj_expr);
909 if (subject == NULL) {
910 ir_read_error(st, NULL, "when reading the subject of an array_ref");
911 return NULL;
912 }
913
914 s_expression *idx_expr = (s_expression*) subj_expr->next;
915 ir_rvalue *idx = read_rvalue(st, idx_expr);
916 return new(ctx) ir_dereference_array(subject, idx);
917 }
918
919 static ir_dereference *
920 read_record_ref(_mesa_glsl_parse_state *st, s_list *list)
921 {
922 void *ctx = st;
923 if (list->length() != 3) {
924 ir_read_error(st, list, "expected (record_ref <rvalue> <field>)");
925 return NULL;
926 }
927
928 s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
929 ir_rvalue *subject = read_rvalue(st, subj_expr);
930 if (subject == NULL) {
931 ir_read_error(st, NULL, "when reading the subject of a record_ref");
932 return NULL;
933 }
934
935 s_symbol *field = SX_AS_SYMBOL(subj_expr->next);
936 if (field == NULL) {
937 ir_read_error(st, list, "expected (record_ref ... <field name>)");
938 return NULL;
939 }
940 return new(ctx) ir_dereference_record(subject, field->value());
941 }
942
943 static bool
944 valid_texture_list_length(ir_texture_opcode op, s_list *list)
945 {
946 unsigned required_length = 7;
947 if (op == ir_txf)
948 required_length = 5;
949 else if (op == ir_tex)
950 required_length = 6;
951
952 return list->length() == required_length;
953 }
954
955 static ir_texture *
956 read_texture(_mesa_glsl_parse_state *st, s_list *list)
957 {
958 void *ctx = st;
959 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
960 assert(tag != NULL);
961
962 ir_texture_opcode op = ir_texture::get_opcode(tag->value());
963 if (op == (ir_texture_opcode) -1)
964 return NULL;
965
966 if (!valid_texture_list_length(op, list)) {
967 ir_read_error(st, NULL, "invalid list size in (%s ...)", tag->value());
968 return NULL;
969 }
970
971 ir_texture *tex = new(ctx) ir_texture(op);
972
973 // Read sampler (must be a deref)
974 s_expression *sampler_expr = (s_expression *) tag->next;
975 ir_dereference *sampler = read_dereference(st, sampler_expr);
976 if (sampler == NULL) {
977 ir_read_error(st, NULL, "when reading sampler in (%s ...)", tag->value());
978 return NULL;
979 }
980 tex->set_sampler(sampler);
981
982 // Read coordinate (any rvalue)
983 s_expression *coordinate_expr = (s_expression *) sampler_expr->next;
984 tex->coordinate = read_rvalue(st, coordinate_expr);
985 if (tex->coordinate == NULL) {
986 ir_read_error(st, NULL, "when reading coordinate in (%s ...)",
987 tag->value());
988 return NULL;
989 }
990
991 // Read texel offset, i.e. (0 0 0)
992 s_list *offset_list = SX_AS_LIST(coordinate_expr->next);
993 if (offset_list == NULL || offset_list->length() != 3) {
994 ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
995 return NULL;
996 }
997 s_int *offset_x = SX_AS_INT(offset_list->subexpressions.head);
998 s_int *offset_y = SX_AS_INT(offset_x->next);
999 s_int *offset_z = SX_AS_INT(offset_y->next);
1000 if (offset_x == NULL || offset_y == NULL || offset_z == NULL) {
1001 ir_read_error(st, offset_list, "expected (<int> <int> <int>)");
1002 return NULL;
1003 }
1004 tex->offsets[0] = offset_x->value();
1005 tex->offsets[1] = offset_y->value();
1006 tex->offsets[2] = offset_z->value();
1007
1008 if (op == ir_txf) {
1009 s_expression *lod_expr = (s_expression *) offset_list->next;
1010 tex->lod_info.lod = read_rvalue(st, lod_expr);
1011 if (tex->lod_info.lod == NULL) {
1012 ir_read_error(st, NULL, "when reading LOD in (txf ...)");
1013 return NULL;
1014 }
1015 } else {
1016 s_expression *proj_expr = (s_expression *) offset_list->next;
1017 s_int *proj_as_int = SX_AS_INT(proj_expr);
1018 if (proj_as_int && proj_as_int->value() == 1) {
1019 tex->projector = NULL;
1020 } else {
1021 tex->projector = read_rvalue(st, proj_expr);
1022 if (tex->projector == NULL) {
1023 ir_read_error(st, NULL, "when reading projective divide in (%s ..)",
1024 tag->value());
1025 return NULL;
1026 }
1027 }
1028
1029 s_list *shadow_list = SX_AS_LIST(proj_expr->next);
1030 if (shadow_list == NULL) {
1031 ir_read_error(st, NULL, "shadow comparitor must be a list");
1032 return NULL;
1033 }
1034 if (shadow_list->subexpressions.is_empty()) {
1035 tex->shadow_comparitor= NULL;
1036 } else {
1037 tex->shadow_comparitor = read_rvalue(st, shadow_list);
1038 if (tex->shadow_comparitor == NULL) {
1039 ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)",
1040 tag->value());
1041 return NULL;
1042 }
1043 }
1044 s_expression *lod_expr = (s_expression *) shadow_list->next;
1045
1046 switch (op) {
1047 case ir_txb:
1048 tex->lod_info.bias = read_rvalue(st, lod_expr);
1049 if (tex->lod_info.bias == NULL) {
1050 ir_read_error(st, NULL, "when reading LOD bias in (txb ...)");
1051 return NULL;
1052 }
1053 break;
1054 case ir_txl:
1055 tex->lod_info.lod = read_rvalue(st, lod_expr);
1056 if (tex->lod_info.lod == NULL) {
1057 ir_read_error(st, NULL, "when reading LOD in (txl ...)");
1058 return NULL;
1059 }
1060 break;
1061 case ir_txd: {
1062 s_list *lod_list = SX_AS_LIST(lod_expr);
1063 if (lod_list->length() != 2) {
1064 ir_read_error(st, lod_expr, "expected (dPdx dPdy) in (txd ...)");
1065 return NULL;
1066 }
1067 s_expression *dx_expr = (s_expression *) lod_list->subexpressions.head;
1068 s_expression *dy_expr = (s_expression *) dx_expr->next;
1069
1070 tex->lod_info.grad.dPdx = read_rvalue(st, dx_expr);
1071 if (tex->lod_info.grad.dPdx == NULL) {
1072 ir_read_error(st, NULL, "when reading dPdx in (txd ...)");
1073 return NULL;
1074 }
1075 tex->lod_info.grad.dPdy = read_rvalue(st, dy_expr);
1076 if (tex->lod_info.grad.dPdy == NULL) {
1077 ir_read_error(st, NULL, "when reading dPdy in (txd ...)");
1078 return NULL;
1079 }
1080 break;
1081 }
1082 default:
1083 // tex doesn't have any extra parameters and txf was handled earlier.
1084 break;
1085 };
1086 }
1087 return tex;
1088 }