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