r300: move some more function to generic
[mesa.git] / src / mesa / shader / slang / slang_print.c
1
2 /**
3 * Dump/print a slang_operation tree
4 */
5
6
7 #include "main/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 (at %p)", (char *) v->a_name, (void *) v);
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 #if 0
175 printf("binary at %p locals=%p outer=%p\n",
176 (void *) op,
177 (void *) op->locals,
178 (void *) op->locals->outer_scope);
179 #endif
180 slang_print_tree(&op->children[0], indent + 3);
181 spaces(indent);
182 printf("%s at %p locals=%p outer=%p\n",
183 oper, (void *) op, (void *) op->locals,
184 (void *) op->locals->outer_scope);
185 slang_print_tree(&op->children[1], indent + 3);
186 }
187
188
189 static void
190 print_generic2(const slang_operation *op, const char *oper,
191 const char *s, int indent)
192 {
193 GLuint i;
194 if (oper) {
195 spaces(indent);
196 printf("%s %s at %p locals=%p outer=%p\n",
197 oper, s, (void *) op, (void *) op->locals,
198 (void *) op->locals->outer_scope);
199 }
200 for (i = 0; i < op->num_children; i++) {
201 spaces(indent);
202 printf("//child %u of %u:\n", i, op->num_children);
203 slang_print_tree(&op->children[i], indent);
204 }
205 }
206
207 static void
208 print_generic(const slang_operation *op, const char *oper, int indent)
209 {
210 print_generic2(op, oper, "", indent);
211 }
212
213
214 static const slang_variable_scope *
215 find_scope(const slang_variable_scope *s, slang_atom name)
216 {
217 GLuint i;
218 for (i = 0; i < s->num_variables; i++) {
219 if (s->variables[i]->a_name == name)
220 return s;
221 }
222 if (s->outer_scope)
223 return find_scope(s->outer_scope, name);
224 else
225 return NULL;
226 }
227
228 static const slang_variable *
229 find_var(const slang_variable_scope *s, slang_atom name)
230 {
231 GLuint i;
232 for (i = 0; i < s->num_variables; i++) {
233 if (s->variables[i]->a_name == name)
234 return s->variables[i];
235 }
236 if (s->outer_scope)
237 return find_var(s->outer_scope, name);
238 else
239 return NULL;
240 }
241
242
243 void
244 slang_print_tree(const slang_operation *op, int indent)
245 {
246 GLuint i;
247
248 switch (op->type) {
249
250 case SLANG_OPER_NONE:
251 spaces(indent);
252 printf("SLANG_OPER_NONE\n");
253 break;
254
255 case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
256 spaces(indent);
257 printf("{ locals=%p outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
258 print_generic(op, NULL, indent+3);
259 spaces(indent);
260 printf("}\n");
261 break;
262
263 case SLANG_OPER_BLOCK_NEW_SCOPE:
264 spaces(indent);
265 printf("{{ // new scope locals=%p outer=%p: ",
266 (void *) op->locals,
267 (void *) op->locals->outer_scope);
268 for (i = 0; i < op->locals->num_variables; i++) {
269 printf("%s ", (char *) op->locals->variables[i]->a_name);
270 }
271 printf("\n");
272 print_generic(op, NULL, indent+3);
273 spaces(indent);
274 printf("}}\n");
275 break;
276
277 case SLANG_OPER_VARIABLE_DECL:
278 assert(op->num_children == 0 || op->num_children == 1);
279 {
280 slang_variable *v;
281 v = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
282 if (v) {
283 const slang_variable_scope *scope;
284 spaces(indent);
285 printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
286 print_type(&v->type);
287 printf(" %s (%p)", (char *) op->a_id,
288 (void *) find_var(op->locals, op->a_id));
289
290 scope = find_scope(op->locals, op->a_id);
291 printf(" (in scope %p) ", (void *) scope);
292 assert(scope);
293 if (op->num_children == 1) {
294 printf(" :=\n");
295 slang_print_tree(&op->children[0], indent + 3);
296 }
297 else if (v->initializer) {
298 printf(" := INITIALIZER\n");
299 slang_print_tree(v->initializer, indent + 3);
300 }
301 else {
302 printf(";\n");
303 }
304 /*
305 spaces(indent);
306 printf("TYPE: ");
307 print_type(&v->type);
308 spaces(indent);
309 printf("ADDR: %d size: %d\n", v->address, v->size);
310 */
311 }
312 else {
313 spaces(indent);
314 printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
315 }
316 }
317 break;
318
319 case SLANG_OPER_ASM:
320 spaces(indent);
321 printf("ASM: %s at %p locals=%p outer=%p\n",
322 (char *) op->a_id,
323 (void *) op,
324 (void *) op->locals,
325 (void *) op->locals->outer_scope);
326 print_generic(op, "ASM", indent+3);
327 break;
328
329 case SLANG_OPER_BREAK:
330 spaces(indent);
331 printf("BREAK\n");
332 break;
333
334 case SLANG_OPER_CONTINUE:
335 spaces(indent);
336 printf("CONTINUE\n");
337 break;
338
339 case SLANG_OPER_DISCARD:
340 spaces(indent);
341 printf("DISCARD\n");
342 break;
343
344 case SLANG_OPER_RETURN:
345 spaces(indent);
346 printf("RETURN\n");
347 if (op->num_children > 0)
348 slang_print_tree(&op->children[0], indent + 3);
349 break;
350
351 case SLANG_OPER_LABEL:
352 spaces(indent);
353 printf("LABEL %s\n", (char *) op->a_id);
354 break;
355
356 case SLANG_OPER_EXPRESSION:
357 spaces(indent);
358 printf("EXPR: locals=%p outer=%p\n",
359 (void *) op->locals,
360 (void *) op->locals->outer_scope);
361 /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
362 slang_print_tree(&op->children[0], indent + 3);
363 break;
364
365 case SLANG_OPER_IF:
366 spaces(indent);
367 printf("IF\n");
368 slang_print_tree(&op->children[0], indent + 3);
369 spaces(indent);
370 printf("THEN\n");
371 slang_print_tree(&op->children[1], indent + 3);
372 spaces(indent);
373 printf("ELSE\n");
374 slang_print_tree(&op->children[2], indent + 3);
375 spaces(indent);
376 printf("ENDIF\n");
377 break;
378
379 case SLANG_OPER_WHILE:
380 assert(op->num_children == 2);
381 spaces(indent);
382 printf("WHILE LOOP: locals = %p\n", (void *) op->locals);
383 indent += 3;
384 spaces(indent);
385 printf("WHILE cond:\n");
386 slang_print_tree(&op->children[0], indent + 3);
387 spaces(indent);
388 printf("WHILE body:\n");
389 slang_print_tree(&op->children[1], indent + 3);
390 indent -= 3;
391 spaces(indent);
392 printf("END WHILE LOOP\n");
393 break;
394
395 case SLANG_OPER_DO:
396 spaces(indent);
397 printf("DO LOOP: locals = %p\n", (void *) op->locals);
398 indent += 3;
399 spaces(indent);
400 printf("DO body:\n");
401 slang_print_tree(&op->children[0], indent + 3);
402 spaces(indent);
403 printf("DO cond:\n");
404 slang_print_tree(&op->children[1], indent + 3);
405 indent -= 3;
406 spaces(indent);
407 printf("END DO LOOP\n");
408 break;
409
410 case SLANG_OPER_FOR:
411 spaces(indent);
412 printf("FOR LOOP: locals = %p\n", (void *) op->locals);
413 indent += 3;
414 spaces(indent);
415 printf("FOR init:\n");
416 slang_print_tree(&op->children[0], indent + 3);
417 spaces(indent);
418 printf("FOR condition:\n");
419 slang_print_tree(&op->children[1], indent + 3);
420 spaces(indent);
421 printf("FOR step:\n");
422 slang_print_tree(&op->children[2], indent + 3);
423 spaces(indent);
424 printf("FOR body:\n");
425 slang_print_tree(&op->children[3], indent + 3);
426 indent -= 3;
427 spaces(indent);
428 printf("ENDFOR\n");
429 /*
430 print_generic(op, "FOR", indent + 3);
431 */
432 break;
433
434 case SLANG_OPER_VOID:
435 spaces(indent);
436 printf("(oper-void)\n");
437 break;
438
439 case SLANG_OPER_LITERAL_BOOL:
440 spaces(indent);
441 printf("LITERAL (");
442 for (i = 0; i < op->literal_size; i++)
443 printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
444 printf(")\n");
445
446 break;
447
448 case SLANG_OPER_LITERAL_INT:
449 spaces(indent);
450 printf("LITERAL (");
451 for (i = 0; i < op->literal_size; i++)
452 printf("%d ", (int) op->literal[i]);
453 printf(")\n");
454 break;
455
456 case SLANG_OPER_LITERAL_FLOAT:
457 spaces(indent);
458 printf("LITERAL (");
459 for (i = 0; i < op->literal_size; i++)
460 printf("%f ", op->literal[i]);
461 printf(")\n");
462 break;
463
464 case SLANG_OPER_IDENTIFIER:
465 {
466 const slang_variable_scope *scope;
467 spaces(indent);
468 if (op->var && op->var->a_name) {
469 scope = find_scope(op->locals, op->var->a_name);
470 printf("VAR %s (in scope %p)\n", (char *) op->var->a_name,
471 (void *) scope);
472 assert(scope);
473 }
474 else {
475 scope = find_scope(op->locals, op->a_id);
476 printf("VAR' %s (in scope %p) locals=%p outer=%p\n",
477 (char *) op->a_id,
478 (void *) scope,
479 (void *) op->locals,
480 (void *) op->locals->outer_scope);
481 assert(scope);
482 }
483 }
484 break;
485
486 case SLANG_OPER_SEQUENCE:
487 print_generic(op, "COMMA-SEQ", indent+3);
488 break;
489
490 case SLANG_OPER_ASSIGN:
491 spaces(indent);
492 printf("ASSIGNMENT locals=%p outer=%p\n",
493 (void *) op->locals,
494 (void *) op->locals->outer_scope);
495 print_binary(op, ":=", indent);
496 break;
497
498 case SLANG_OPER_ADDASSIGN:
499 spaces(indent);
500 printf("ASSIGN\n");
501 print_binary(op, "+=", indent);
502 break;
503
504 case SLANG_OPER_SUBASSIGN:
505 spaces(indent);
506 printf("ASSIGN\n");
507 print_binary(op, "-=", indent);
508 break;
509
510 case SLANG_OPER_MULASSIGN:
511 spaces(indent);
512 printf("ASSIGN\n");
513 print_binary(op, "*=", indent);
514 break;
515
516 case SLANG_OPER_DIVASSIGN:
517 spaces(indent);
518 printf("ASSIGN\n");
519 print_binary(op, "/=", indent);
520 break;
521
522 /*SLANG_OPER_MODASSIGN,*/
523 /*SLANG_OPER_LSHASSIGN,*/
524 /*SLANG_OPER_RSHASSIGN,*/
525 /*SLANG_OPER_ORASSIGN,*/
526 /*SLANG_OPER_XORASSIGN,*/
527 /*SLANG_OPER_ANDASSIGN,*/
528 case SLANG_OPER_SELECT:
529 spaces(indent);
530 printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
531 assert(op->num_children == 3);
532 slang_print_tree(&op->children[0], indent+3);
533 spaces(indent);
534 printf("?\n");
535 slang_print_tree(&op->children[1], indent+3);
536 spaces(indent);
537 printf(":\n");
538 slang_print_tree(&op->children[2], indent+3);
539 break;
540
541 case SLANG_OPER_LOGICALOR:
542 print_binary(op, "||", indent);
543 break;
544
545 case SLANG_OPER_LOGICALXOR:
546 print_binary(op, "^^", indent);
547 break;
548
549 case SLANG_OPER_LOGICALAND:
550 print_binary(op, "&&", indent);
551 break;
552
553 /*SLANG_OPER_BITOR*/
554 /*SLANG_OPER_BITXOR*/
555 /*SLANG_OPER_BITAND*/
556 case SLANG_OPER_EQUAL:
557 print_binary(op, "==", indent);
558 break;
559
560 case SLANG_OPER_NOTEQUAL:
561 print_binary(op, "!=", indent);
562 break;
563
564 case SLANG_OPER_LESS:
565 print_binary(op, "<", indent);
566 break;
567
568 case SLANG_OPER_GREATER:
569 print_binary(op, ">", indent);
570 break;
571
572 case SLANG_OPER_LESSEQUAL:
573 print_binary(op, "<=", indent);
574 break;
575
576 case SLANG_OPER_GREATEREQUAL:
577 print_binary(op, ">=", indent);
578 break;
579
580 /*SLANG_OPER_LSHIFT*/
581 /*SLANG_OPER_RSHIFT*/
582 case SLANG_OPER_ADD:
583 print_binary(op, "+", indent);
584 break;
585
586 case SLANG_OPER_SUBTRACT:
587 print_binary(op, "-", indent);
588 break;
589
590 case SLANG_OPER_MULTIPLY:
591 print_binary(op, "*", indent);
592 break;
593
594 case SLANG_OPER_DIVIDE:
595 print_binary(op, "/", indent);
596 break;
597
598 /*SLANG_OPER_MODULUS*/
599 case SLANG_OPER_PREINCREMENT:
600 spaces(indent);
601 printf("PRE++\n");
602 slang_print_tree(&op->children[0], indent+3);
603 break;
604
605 case SLANG_OPER_PREDECREMENT:
606 spaces(indent);
607 printf("PRE--\n");
608 slang_print_tree(&op->children[0], indent+3);
609 break;
610
611 case SLANG_OPER_PLUS:
612 spaces(indent);
613 printf("SLANG_OPER_PLUS\n");
614 break;
615
616 case SLANG_OPER_MINUS:
617 spaces(indent);
618 printf("SLANG_OPER_MINUS\n");
619 break;
620
621 /*SLANG_OPER_COMPLEMENT*/
622 case SLANG_OPER_NOT:
623 spaces(indent);
624 printf("NOT\n");
625 slang_print_tree(&op->children[0], indent+3);
626 break;
627
628 case SLANG_OPER_SUBSCRIPT:
629 spaces(indent);
630 printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
631 (void *) op->locals,
632 (void *) op->locals->outer_scope);
633 print_generic(op, NULL, indent+3);
634 break;
635
636 case SLANG_OPER_CALL:
637 #if 0
638 slang_function *fun
639 = _slang_locate_function(A->space.funcs, oper->a_id,
640 oper->children,
641 oper->num_children, &A->space, A->atoms);
642 #endif
643 spaces(indent);
644 printf("CALL %s(\n", (char *) op->a_id);
645 for (i = 0; i < op->num_children; i++) {
646 slang_print_tree(&op->children[i], indent+3);
647 if (i + 1 < op->num_children) {
648 spaces(indent + 3);
649 printf(",\n");
650 }
651 }
652 spaces(indent);
653 printf(")\n");
654 break;
655
656 case SLANG_OPER_FIELD:
657 spaces(indent);
658 printf("FIELD %s of\n", (char*) op->a_id);
659 slang_print_tree(&op->children[0], indent+3);
660 break;
661
662 case SLANG_OPER_POSTINCREMENT:
663 spaces(indent);
664 printf("POST++\n");
665 slang_print_tree(&op->children[0], indent+3);
666 break;
667
668 case SLANG_OPER_POSTDECREMENT:
669 spaces(indent);
670 printf("POST--\n");
671 slang_print_tree(&op->children[0], indent+3);
672 break;
673
674 default:
675 printf("unknown op->type %d\n", (int) op->type);
676 }
677
678 }
679
680
681
682 void
683 slang_print_function(const slang_function *f, GLboolean body)
684 {
685 GLuint i;
686
687 #if 0
688 if (_mesa_strcmp((char *) f->header.a_name, "main") != 0)
689 return;
690 #endif
691
692 printf("FUNCTION %s ( scope=%p\n",
693 (char *) f->header.a_name, (void *) f->parameters);
694
695 for (i = 0; i < f->param_count; i++) {
696 print_variable(f->parameters->variables[i], 3);
697 }
698
699 printf(") param scope = %p\n", (void *) f->parameters);
700
701 if (body && f->body)
702 slang_print_tree(f->body, 0);
703 }
704
705
706
707
708
709 const char *
710 slang_type_qual_string(slang_type_qualifier q)
711 {
712 switch (q) {
713 case SLANG_QUAL_NONE:
714 return "none";
715 case SLANG_QUAL_CONST:
716 return "const";
717 case SLANG_QUAL_ATTRIBUTE:
718 return "attribute";
719 case SLANG_QUAL_VARYING:
720 return "varying";
721 case SLANG_QUAL_UNIFORM:
722 return "uniform";
723 case SLANG_QUAL_OUT:
724 return "out";
725 case SLANG_QUAL_INOUT:
726 return "inout";
727 case SLANG_QUAL_FIXEDOUTPUT:
728 return "fixedoutput";
729 case SLANG_QUAL_FIXEDINPUT:
730 return "fixedinputk";
731 default:
732 return "qual?";
733 }
734 }
735
736
737 static const char *
738 slang_type_string(slang_type_specifier_type t)
739 {
740 switch (t) {
741 case SLANG_SPEC_VOID:
742 return "void";
743 case SLANG_SPEC_BOOL:
744 return "bool";
745 case SLANG_SPEC_BVEC2:
746 return "bvec2";
747 case SLANG_SPEC_BVEC3:
748 return "bvec3";
749 case SLANG_SPEC_BVEC4:
750 return "bvec4";
751 case SLANG_SPEC_INT:
752 return "int";
753 case SLANG_SPEC_IVEC2:
754 return "ivec2";
755 case SLANG_SPEC_IVEC3:
756 return "ivec3";
757 case SLANG_SPEC_IVEC4:
758 return "ivec4";
759 case SLANG_SPEC_FLOAT:
760 return "float";
761 case SLANG_SPEC_VEC2:
762 return "vec2";
763 case SLANG_SPEC_VEC3:
764 return "vec3";
765 case SLANG_SPEC_VEC4:
766 return "vec4";
767 case SLANG_SPEC_MAT2:
768 return "mat2";
769 case SLANG_SPEC_MAT3:
770 return "mat3";
771 case SLANG_SPEC_MAT4:
772 return "mat4";
773 case SLANG_SPEC_SAMPLER1D:
774 return "sampler1D";
775 case SLANG_SPEC_SAMPLER2D:
776 return "sampler2D";
777 case SLANG_SPEC_SAMPLER3D:
778 return "sampler3D";
779 case SLANG_SPEC_SAMPLERCUBE:
780 return "samplerCube";
781 case SLANG_SPEC_SAMPLER1DSHADOW:
782 return "sampler1DShadow";
783 case SLANG_SPEC_SAMPLER2DSHADOW:
784 return "sampler2DShadow";
785 case SLANG_SPEC_SAMPLER2DRECT:
786 return "sampler2DRect";
787 case SLANG_SPEC_SAMPLER2DRECTSHADOW:
788 return "sampler2DRectShadow";
789 case SLANG_SPEC_STRUCT:
790 return "struct";
791 case SLANG_SPEC_ARRAY:
792 return "array";
793 default:
794 return "type?";
795 }
796 }
797
798
799 static const char *
800 slang_fq_type_string(const slang_fully_specified_type *t)
801 {
802 static char str[1000];
803 sprintf(str, "%s %s", slang_type_qual_string(t->qualifier),
804 slang_type_string(t->specifier.type));
805 return str;
806 }
807
808
809 void
810 slang_print_type(const slang_fully_specified_type *t)
811 {
812 printf("%s %s", slang_type_qual_string(t->qualifier),
813 slang_type_string(t->specifier.type));
814 }
815
816
817 #if 0
818 static char *
819 slang_var_string(const slang_variable *v)
820 {
821 static char str[1000];
822 sprintf(str, "%s : %s",
823 (char *) v->a_name,
824 slang_fq_type_string(&v->type));
825 return str;
826 }
827 #endif
828
829
830 void
831 slang_print_variable(const slang_variable *v)
832 {
833 printf("Name: %s\n", (char *) v->a_name);
834 printf("Type: %s\n", slang_fq_type_string(&v->type));
835 }
836
837
838 void
839 _slang_print_var_scope(const slang_variable_scope *vars, int indent)
840 {
841 GLuint i;
842
843 spaces(indent);
844 printf("Var scope %p %d vars:\n", (void *) vars, vars->num_variables);
845 for (i = 0; i < vars->num_variables; i++) {
846 spaces(indent + 3);
847 printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
848 }
849 spaces(indent + 3);
850 printf("outer_scope = %p\n", (void*) vars->outer_scope);
851
852 if (vars->outer_scope) {
853 /*spaces(indent + 3);*/
854 _slang_print_var_scope(vars->outer_scope, indent + 3);
855 }
856 }
857
858
859
860 int
861 slang_checksum_tree(const slang_operation *op)
862 {
863 int s = op->num_children;
864 GLuint i;
865
866 for (i = 0; i < op->num_children; i++) {
867 s += slang_checksum_tree(&op->children[i]);
868 }
869 return s;
870 }