fix w component of glsl vec4 asin
[mesa.git] / src / mesa / shader / slang / slang_print.c
1
2 /**
3 * Dump/print a slang_operation tree
4 */
5
6
7 #include "imports.h"
8 #include "slang_compile.h"
9 #include "slang_print.h"
10
11
12 static void
13 spaces(int n)
14 {
15 while (n--)
16 printf(" ");
17 }
18
19
20 static void
21 print_type(const slang_fully_specified_type *t)
22 {
23 switch (t->qualifier) {
24 case SLANG_QUAL_NONE:
25 /*printf("");*/
26 break;
27 case SLANG_QUAL_CONST:
28 printf("const ");
29 break;
30 case SLANG_QUAL_ATTRIBUTE:
31 printf("attrib ");
32 break;
33 case SLANG_QUAL_VARYING:
34 printf("varying ");
35 break;
36 case SLANG_QUAL_UNIFORM:
37 printf("uniform ");
38 break;
39 case SLANG_QUAL_OUT:
40 printf("output ");
41 break;
42 case SLANG_QUAL_INOUT:
43 printf("inout ");
44 break;
45 case SLANG_QUAL_FIXEDOUTPUT:
46 printf("fixedoutput");
47 break;
48 case SLANG_QUAL_FIXEDINPUT:
49 printf("fixedinput");
50 break;
51 default:
52 printf("unknown qualifer!");
53 }
54
55 switch (t->specifier.type) {
56 case SLANG_SPEC_VOID:
57 printf("void");
58 break;
59 case SLANG_SPEC_BOOL:
60 printf("bool");
61 break;
62 case SLANG_SPEC_BVEC2:
63 printf("bvec2");
64 break;
65 case SLANG_SPEC_BVEC3:
66 printf("bvec3");
67 break;
68 case SLANG_SPEC_BVEC4:
69 printf("bvec4");
70 break;
71 case SLANG_SPEC_INT:
72 printf("int");
73 break;
74 case SLANG_SPEC_IVEC2:
75 printf("ivec2");
76 break;
77 case SLANG_SPEC_IVEC3:
78 printf("ivec3");
79 break;
80 case SLANG_SPEC_IVEC4:
81 printf("ivec4");
82 break;
83 case SLANG_SPEC_FLOAT:
84 printf("float");
85 break;
86 case SLANG_SPEC_VEC2:
87 printf("vec2");
88 break;
89 case SLANG_SPEC_VEC3:
90 printf("vec3");
91 break;
92 case SLANG_SPEC_VEC4:
93 printf("vec4");
94 break;
95 case SLANG_SPEC_MAT2:
96 printf("mat2");
97 break;
98 case SLANG_SPEC_MAT3:
99 printf("mat3");
100 break;
101 case SLANG_SPEC_MAT4:
102 printf("mat4");
103 break;
104 case SLANG_SPEC_MAT23:
105 printf("mat2x3");
106 break;
107 case SLANG_SPEC_MAT32:
108 printf("mat3x2");
109 break;
110 case SLANG_SPEC_MAT24:
111 printf("mat2x4");
112 break;
113 case SLANG_SPEC_MAT42:
114 printf("mat4x2");
115 break;
116 case SLANG_SPEC_MAT34:
117 printf("mat3x4");
118 break;
119 case SLANG_SPEC_MAT43:
120 printf("mat4x3");
121 break;
122 case SLANG_SPEC_SAMPLER1D:
123 printf("sampler1D");
124 break;
125 case SLANG_SPEC_SAMPLER2D:
126 printf("sampler2D");
127 break;
128 case SLANG_SPEC_SAMPLER3D:
129 printf("sampler3D");
130 break;
131 case SLANG_SPEC_SAMPLERCUBE:
132 printf("samplerCube");
133 break;
134 case SLANG_SPEC_SAMPLER1DSHADOW:
135 printf("sampler1DShadow");
136 break;
137 case SLANG_SPEC_SAMPLER2DSHADOW:
138 printf("sampler2DShadow");
139 break;
140 case SLANG_SPEC_STRUCT:
141 printf("struct");
142 break;
143 case SLANG_SPEC_ARRAY:
144 printf("array");
145 break;
146 default:
147 printf("unknown type");
148 }
149 /*printf("\n");*/
150 }
151
152
153 static void
154 print_variable(const slang_variable *v, int indent)
155 {
156 spaces(indent);
157 printf("VAR ");
158 print_type(&v->type);
159 printf(" %s", (char *) v->a_name);
160 if (v->initializer) {
161 printf(" :=\n");
162 slang_print_tree(v->initializer, indent + 3);
163 }
164 else {
165 printf(";\n");
166 }
167 }
168
169
170 static void
171 print_binary(const slang_operation *op, const char *oper, int indent)
172 {
173 assert(op->num_children == 2);
174 slang_print_tree(&op->children[0], indent + 3);
175 spaces(indent);
176 printf("%s\n", oper);
177 slang_print_tree(&op->children[1], indent + 3);
178 }
179
180
181 static void
182 print_generic2(const slang_operation *op, const char *oper,
183 const char *s, int indent)
184 {
185 int i;
186 if (oper) {
187 spaces(indent);
188 printf("[%p locals %p] %s %s\n", (void*) op, (void*) op->locals, oper, s);
189 }
190 for (i = 0; i < op->num_children; i++) {
191 spaces(indent);
192 printf("//child %d:\n", i);
193 slang_print_tree(&op->children[i], indent);
194 }
195 }
196
197 static void
198 print_generic(const slang_operation *op, const char *oper, int indent)
199 {
200 print_generic2(op, oper, "", indent);
201 }
202
203
204 static const slang_variable_scope *
205 find_scope(const slang_variable_scope *s, slang_atom name)
206 {
207 GLuint i;
208 for (i = 0; i < s->num_variables; i++) {
209 if (s->variables[i]->a_name == name)
210 return s;
211 }
212 if (s->outer_scope)
213 return find_scope(s->outer_scope, name);
214 else
215 return NULL;
216 }
217
218 static const slang_variable *
219 find_var(const slang_variable_scope *s, slang_atom name)
220 {
221 GLuint i;
222 for (i = 0; i < s->num_variables; i++) {
223 if (s->variables[i]->a_name == name)
224 return s->variables[i];
225 }
226 if (s->outer_scope)
227 return find_var(s->outer_scope, name);
228 else
229 return NULL;
230 }
231
232
233 void
234 slang_print_tree(const slang_operation *op, int indent)
235 {
236 int i;
237
238 switch (op->type) {
239
240 case SLANG_OPER_NONE:
241 spaces(indent);
242 printf("SLANG_OPER_NONE\n");
243 break;
244
245 case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
246 spaces(indent);
247 printf("{ locals %p outer %p\n", (void*)op->locals, (void*)op->locals->outer_scope);
248 print_generic(op, NULL, indent+3);
249 spaces(indent);
250 printf("}\n");
251 break;
252
253 case SLANG_OPER_BLOCK_NEW_SCOPE:
254 spaces(indent);
255 printf("{{ // new scope locals %p\n", (void*)op->locals);
256 print_generic(op, NULL, indent+3);
257 spaces(indent);
258 printf("}}\n");
259 break;
260
261 case SLANG_OPER_VARIABLE_DECL:
262 assert(op->num_children == 0 || op->num_children == 1);
263 {
264 slang_variable *v;
265 v = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
266 if (v) {
267 spaces(indent);
268 printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
269 print_type(&v->type);
270 printf(" %s (%p)", (char *) op->a_id,
271 (void *) find_var(op->locals, op->a_id));
272
273 printf(" (in scope %p) ",
274 (void *) find_scope(op->locals, op->a_id));
275 if (op->num_children == 1) {
276 printf(" :=\n");
277 slang_print_tree(&op->children[0], indent + 3);
278 }
279 else if (v->initializer) {
280 printf(" := INITIALIZER\n");
281 slang_print_tree(v->initializer, indent + 3);
282 }
283 else {
284 printf(";\n");
285 }
286 /*
287 spaces(indent);
288 printf("TYPE: ");
289 print_type(&v->type);
290 spaces(indent);
291 printf("ADDR: %d size: %d\n", v->address, v->size);
292 */
293 }
294 else {
295 spaces(indent);
296 printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
297 }
298 }
299 break;
300
301 case SLANG_OPER_ASM:
302 spaces(indent);
303 printf("ASM: %s\n", (char*) op->a_id);
304 print_generic(op, NULL, indent+3);
305 break;
306
307 case SLANG_OPER_BREAK:
308 spaces(indent);
309 printf("BREAK\n");
310 break;
311
312 case SLANG_OPER_CONTINUE:
313 spaces(indent);
314 printf("CONTINUE\n");
315 break;
316
317 case SLANG_OPER_DISCARD:
318 spaces(indent);
319 printf("DISCARD\n");
320 break;
321
322 case SLANG_OPER_RETURN:
323 spaces(indent);
324 printf("RETURN\n");
325 if (op->num_children > 0)
326 slang_print_tree(&op->children[0], indent + 3);
327 break;
328
329 case SLANG_OPER_LABEL:
330 spaces(indent);
331 printf("LABEL %s\n", (char *) op->a_id);
332 break;
333
334 case SLANG_OPER_EXPRESSION:
335 spaces(indent);
336 printf("EXPR: locals %p\n", (void*) op->locals);
337 /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
338 slang_print_tree(&op->children[0], indent + 3);
339 break;
340
341 case SLANG_OPER_IF:
342 spaces(indent);
343 printf("IF\n");
344 slang_print_tree(&op->children[0], indent + 3);
345 spaces(indent);
346 printf("THEN\n");
347 slang_print_tree(&op->children[1], indent + 3);
348 spaces(indent);
349 printf("ELSE\n");
350 slang_print_tree(&op->children[2], indent + 3);
351 spaces(indent);
352 printf("ENDIF\n");
353 break;
354
355 case SLANG_OPER_WHILE:
356 assert(op->num_children == 2);
357 spaces(indent);
358 printf("WHILE cond:\n");
359 slang_print_tree(&op->children[0], indent + 3);
360 spaces(indent);
361 printf("WHILE body:\n");
362 slang_print_tree(&op->children[1], indent + 3);
363 break;
364
365 case SLANG_OPER_DO:
366 spaces(indent);
367 printf("DO body:\n");
368 slang_print_tree(&op->children[0], indent + 3);
369 spaces(indent);
370 printf("DO cond:\n");
371 slang_print_tree(&op->children[1], indent + 3);
372 break;
373
374 case SLANG_OPER_FOR:
375 spaces(indent);
376 printf("FOR init:\n");
377 slang_print_tree(&op->children[0], indent + 3);
378 spaces(indent);
379 printf("FOR while:\n");
380 slang_print_tree(&op->children[1], indent + 3);
381 spaces(indent);
382 printf("FOR step:\n");
383 slang_print_tree(&op->children[2], indent + 3);
384 spaces(indent);
385 printf("FOR body:\n");
386 slang_print_tree(&op->children[3], indent + 3);
387 spaces(indent);
388 printf("ENDFOR\n");
389 /*
390 print_generic(op, "FOR", indent + 3);
391 */
392 break;
393
394 case SLANG_OPER_VOID:
395 spaces(indent);
396 printf("(oper-void)\n");
397 break;
398
399 case SLANG_OPER_LITERAL_BOOL:
400 spaces(indent);
401 printf("LITERAL (");
402 for (i = 0; i < op->literal_size; i++)
403 printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
404 printf(")\n");
405
406 break;
407
408 case SLANG_OPER_LITERAL_INT:
409 spaces(indent);
410 printf("LITERAL (");
411 for (i = 0; i < op->literal_size; i++)
412 printf("%d ", (int) op->literal[i]);
413 printf(")\n");
414 break;
415
416 case SLANG_OPER_LITERAL_FLOAT:
417 spaces(indent);
418 printf("LITERAL (");
419 for (i = 0; i < op->literal_size; i++)
420 printf("%f ", op->literal[i]);
421 printf(")\n");
422 break;
423
424 case SLANG_OPER_IDENTIFIER:
425 spaces(indent);
426 if (op->var && op->var->a_name)
427 printf("VAR %s (in scope %p)\n", (char *) op->var->a_name,
428 (void *) find_scope(op->locals, op->a_id));
429 else
430 printf("VAR' %s (in scope %p)\n", (char *) op->a_id,
431 (void *) find_scope(op->locals, op->a_id));
432 break;
433
434 case SLANG_OPER_SEQUENCE:
435 print_generic(op, "COMMA-SEQ", indent+3);
436 break;
437
438 case SLANG_OPER_ASSIGN:
439 spaces(indent);
440 printf("ASSIGNMENT locals %p\n", (void*)op->locals);
441 print_binary(op, ":=", indent);
442 break;
443
444 case SLANG_OPER_ADDASSIGN:
445 spaces(indent);
446 printf("ASSIGN\n");
447 print_binary(op, "+=", indent);
448 break;
449
450 case SLANG_OPER_SUBASSIGN:
451 spaces(indent);
452 printf("ASSIGN\n");
453 print_binary(op, "-=", indent);
454 break;
455
456 case SLANG_OPER_MULASSIGN:
457 spaces(indent);
458 printf("ASSIGN\n");
459 print_binary(op, "*=", indent);
460 break;
461
462 case SLANG_OPER_DIVASSIGN:
463 spaces(indent);
464 printf("ASSIGN\n");
465 print_binary(op, "/=", indent);
466 break;
467
468 /*SLANG_OPER_MODASSIGN,*/
469 /*SLANG_OPER_LSHASSIGN,*/
470 /*SLANG_OPER_RSHASSIGN,*/
471 /*SLANG_OPER_ORASSIGN,*/
472 /*SLANG_OPER_XORASSIGN,*/
473 /*SLANG_OPER_ANDASSIGN,*/
474 case SLANG_OPER_SELECT:
475 spaces(indent);
476 printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
477 assert(op->num_children == 3);
478 slang_print_tree(&op->children[0], indent+3);
479 spaces(indent);
480 printf("?\n");
481 slang_print_tree(&op->children[1], indent+3);
482 spaces(indent);
483 printf(":\n");
484 slang_print_tree(&op->children[2], indent+3);
485 break;
486
487 case SLANG_OPER_LOGICALOR:
488 print_binary(op, "||", indent);
489 break;
490
491 case SLANG_OPER_LOGICALXOR:
492 print_binary(op, "^^", indent);
493 break;
494
495 case SLANG_OPER_LOGICALAND:
496 print_binary(op, "&&", indent);
497 break;
498
499 /*SLANG_OPER_BITOR*/
500 /*SLANG_OPER_BITXOR*/
501 /*SLANG_OPER_BITAND*/
502 case SLANG_OPER_EQUAL:
503 print_binary(op, "==", indent);
504 break;
505
506 case SLANG_OPER_NOTEQUAL:
507 print_binary(op, "!=", indent);
508 break;
509
510 case SLANG_OPER_LESS:
511 print_binary(op, "<", indent);
512 break;
513
514 case SLANG_OPER_GREATER:
515 print_binary(op, ">", indent);
516 break;
517
518 case SLANG_OPER_LESSEQUAL:
519 print_binary(op, "<=", indent);
520 break;
521
522 case SLANG_OPER_GREATEREQUAL:
523 print_binary(op, ">=", indent);
524 break;
525
526 /*SLANG_OPER_LSHIFT*/
527 /*SLANG_OPER_RSHIFT*/
528 case SLANG_OPER_ADD:
529 print_binary(op, "+", indent);
530 break;
531
532 case SLANG_OPER_SUBTRACT:
533 print_binary(op, "-", indent);
534 break;
535
536 case SLANG_OPER_MULTIPLY:
537 print_binary(op, "*", indent);
538 break;
539
540 case SLANG_OPER_DIVIDE:
541 print_binary(op, "/", indent);
542 break;
543
544 /*SLANG_OPER_MODULUS*/
545 case SLANG_OPER_PREINCREMENT:
546 spaces(indent);
547 printf("PRE++\n");
548 slang_print_tree(&op->children[0], indent+3);
549 break;
550
551 case SLANG_OPER_PREDECREMENT:
552 spaces(indent);
553 printf("PRE--\n");
554 slang_print_tree(&op->children[0], indent+3);
555 break;
556
557 case SLANG_OPER_PLUS:
558 spaces(indent);
559 printf("SLANG_OPER_PLUS\n");
560 break;
561
562 case SLANG_OPER_MINUS:
563 spaces(indent);
564 printf("SLANG_OPER_MINUS\n");
565 break;
566
567 /*SLANG_OPER_COMPLEMENT*/
568 case SLANG_OPER_NOT:
569 spaces(indent);
570 printf("NOT\n");
571 slang_print_tree(&op->children[0], indent+3);
572 break;
573
574 case SLANG_OPER_SUBSCRIPT:
575 spaces(indent);
576 printf("SLANG_OPER_SUBSCRIPT\n");
577 print_generic(op, NULL, indent+3);
578 break;
579
580 case SLANG_OPER_CALL:
581 #if 0
582 slang_function *fun
583 = _slang_locate_function(A->space.funcs, oper->a_id,
584 oper->children,
585 oper->num_children, &A->space, A->atoms);
586 #endif
587 spaces(indent);
588 printf("CALL %s(\n", (char *) op->a_id);
589 for (i = 0; i < op->num_children; i++) {
590 slang_print_tree(&op->children[i], indent+3);
591 if (i + 1 < op->num_children) {
592 spaces(indent + 3);
593 printf(",\n");
594 }
595 }
596 spaces(indent);
597 printf(")\n");
598 break;
599
600 case SLANG_OPER_FIELD:
601 spaces(indent);
602 printf("FIELD %s of\n", (char*) op->a_id);
603 slang_print_tree(&op->children[0], indent+3);
604 break;
605
606 case SLANG_OPER_POSTINCREMENT:
607 spaces(indent);
608 printf("POST++\n");
609 slang_print_tree(&op->children[0], indent+3);
610 break;
611
612 case SLANG_OPER_POSTDECREMENT:
613 spaces(indent);
614 printf("POST--\n");
615 slang_print_tree(&op->children[0], indent+3);
616 break;
617
618 default:
619 printf("unknown op->type %d\n", (int) op->type);
620 }
621
622 }
623
624
625
626 void
627 slang_print_function(const slang_function *f, GLboolean body)
628 {
629 int i;
630
631 #if 0
632 if (_mesa_strcmp((char *) f->header.a_name, "main") != 0)
633 return;
634 #endif
635
636 printf("FUNCTION %s (\n",
637 (char *) f->header.a_name);
638
639 for (i = 0; i < f->param_count; i++) {
640 print_variable(f->parameters->variables[i], 3);
641 }
642
643 printf(")\n");
644 if (body && f->body)
645 slang_print_tree(f->body, 0);
646 }
647
648
649
650
651
652 const char *
653 slang_type_qual_string(slang_type_qualifier q)
654 {
655 switch (q) {
656 case SLANG_QUAL_NONE:
657 return "none";
658 case SLANG_QUAL_CONST:
659 return "const";
660 case SLANG_QUAL_ATTRIBUTE:
661 return "attribute";
662 case SLANG_QUAL_VARYING:
663 return "varying";
664 case SLANG_QUAL_UNIFORM:
665 return "uniform";
666 case SLANG_QUAL_OUT:
667 return "out";
668 case SLANG_QUAL_INOUT:
669 return "inout";
670 case SLANG_QUAL_FIXEDOUTPUT:
671 return "fixedoutput";
672 case SLANG_QUAL_FIXEDINPUT:
673 return "fixedinputk";
674 default:
675 return "qual?";
676 }
677 }
678
679
680 static const char *
681 slang_type_string(slang_type_specifier_type t)
682 {
683 switch (t) {
684 case SLANG_SPEC_VOID:
685 return "void";
686 case SLANG_SPEC_BOOL:
687 return "bool";
688 case SLANG_SPEC_BVEC2:
689 return "bvec2";
690 case SLANG_SPEC_BVEC3:
691 return "bvec3";
692 case SLANG_SPEC_BVEC4:
693 return "bvec4";
694 case SLANG_SPEC_INT:
695 return "int";
696 case SLANG_SPEC_IVEC2:
697 return "ivec2";
698 case SLANG_SPEC_IVEC3:
699 return "ivec3";
700 case SLANG_SPEC_IVEC4:
701 return "ivec4";
702 case SLANG_SPEC_FLOAT:
703 return "float";
704 case SLANG_SPEC_VEC2:
705 return "vec2";
706 case SLANG_SPEC_VEC3:
707 return "vec3";
708 case SLANG_SPEC_VEC4:
709 return "vec4";
710 case SLANG_SPEC_MAT2:
711 return "mat2";
712 case SLANG_SPEC_MAT3:
713 return "mat3";
714 case SLANG_SPEC_MAT4:
715 return "mat4";
716 case SLANG_SPEC_SAMPLER1D:
717 return "sampler1D";
718 case SLANG_SPEC_SAMPLER2D:
719 return "sampler2D";
720 case SLANG_SPEC_SAMPLER3D:
721 return "sampler3D";
722 case SLANG_SPEC_SAMPLERCUBE:
723 return "samplerCube";
724 case SLANG_SPEC_SAMPLER1DSHADOW:
725 return "sampler1DShadow";
726 case SLANG_SPEC_SAMPLER2DSHADOW:
727 return "sampler2DShadow";
728 case SLANG_SPEC_SAMPLER2DRECT:
729 return "sampler2DRect";
730 case SLANG_SPEC_SAMPLER2DRECTSHADOW:
731 return "sampler2DRectShadow";
732 case SLANG_SPEC_STRUCT:
733 return "struct";
734 case SLANG_SPEC_ARRAY:
735 return "array";
736 default:
737 return "type?";
738 }
739 }
740
741
742 static const char *
743 slang_fq_type_string(const slang_fully_specified_type *t)
744 {
745 static char str[1000];
746 sprintf(str, "%s %s", slang_type_qual_string(t->qualifier),
747 slang_type_string(t->specifier.type));
748 return str;
749 }
750
751
752 void
753 slang_print_type(const slang_fully_specified_type *t)
754 {
755 printf("%s %s", slang_type_qual_string(t->qualifier),
756 slang_type_string(t->specifier.type));
757 }
758
759
760 #if 0
761 static char *
762 slang_var_string(const slang_variable *v)
763 {
764 static char str[1000];
765 sprintf(str, "%s : %s",
766 (char *) v->a_name,
767 slang_fq_type_string(&v->type));
768 return str;
769 }
770 #endif
771
772
773 void
774 slang_print_variable(const slang_variable *v)
775 {
776 printf("Name: %s\n", (char *) v->a_name);
777 printf("Type: %s\n", slang_fq_type_string(&v->type));
778 }
779
780
781 void
782 _slang_print_var_scope(const slang_variable_scope *vars, int indent)
783 {
784 GLuint i;
785
786 spaces(indent);
787 printf("Var scope %p %d vars:\n", (void *) vars, vars->num_variables);
788 for (i = 0; i < vars->num_variables; i++) {
789 spaces(indent + 3);
790 printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
791 }
792 spaces(indent + 3);
793 printf("outer_scope = %p\n", (void*) vars->outer_scope);
794
795 if (vars->outer_scope) {
796 /*spaces(indent + 3);*/
797 _slang_print_var_scope(vars->outer_scope, indent + 3);
798 }
799 }
800
801
802
803 int
804 slang_checksum_tree(const slang_operation *op)
805 {
806 int s = op->num_children;
807 int i;
808
809 for (i = 0; i < op->num_children; i++) {
810 s += slang_checksum_tree(&op->children[i]);
811 }
812 return s;
813 }