Beispiel #1
0
static void
print_binary(const slang_operation *op, const char *oper, int indent)
{
   assert(op->num_children == 2);
#if 0
   printf("binary at %p locals=%p outer=%p\n",
          (void *) op,
          (void *) op->locals,
          (void *) op->locals->outer_scope);
#endif
   slang_print_tree(&op->children[0], indent + 3);
   spaces(indent);
   printf("%s at %p locals=%p outer=%p\n",
          oper, (void *) op, (void *) op->locals,
          (void *) op->locals->outer_scope);
   slang_print_tree(&op->children[1], indent + 3);
}
Beispiel #2
0
static void
print_variable(const slang_variable *v, int indent)
{
   spaces(indent);
   printf("VAR ");
   print_type(&v->type);
   printf(" %s (at %p)", (char *) v->a_name, (void *) v);
   if (v->initializer) {
      printf(" :=\n");
      slang_print_tree(v->initializer, indent + 3);
   }
   else {
      printf(";\n");
   }
}
Beispiel #3
0
static void
print_generic2(const slang_operation *op, const char *oper,
               const char *s, int indent)
{
   GLuint i;
   if (oper) {
      spaces(indent);
      printf("%s %s at %p locals=%p outer=%p\n",
             oper, s, (void *) op, (void *) op->locals, 
             (void *) op->locals->outer_scope);
   }
   for (i = 0; i < op->num_children; i++) {
      spaces(indent);
      printf("//child %u of %u:\n", i, op->num_children);
      slang_print_tree(&op->children[i], indent);
   }
}
Beispiel #4
0
void
slang_print_function(const slang_function *f, GLboolean body)
{
   GLuint i;

#if 0
   if (_mesa_strcmp((char *) f->header.a_name, "main") != 0)
     return;
#endif

   printf("FUNCTION %s ( scope=%p\n",
          (char *) f->header.a_name, (void *) f->parameters);

   for (i = 0; i < f->param_count; i++) {
      print_variable(f->parameters->variables[i], 3);
   }

   printf(") param scope = %p\n", (void *) f->parameters);

   if (body && f->body)
      slang_print_tree(f->body, 0);
}
Beispiel #5
0
void
slang_print_tree(const slang_operation *op, int indent)
{
   GLuint i;

   switch (op->type) {

   case SLANG_OPER_NONE:
      spaces(indent);
      printf("SLANG_OPER_NONE\n");
      break;

   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
      spaces(indent);
      printf("{ locals=%p  outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
      print_generic(op, NULL, indent+3);
      spaces(indent);
      printf("}\n");
      break;

   case SLANG_OPER_BLOCK_NEW_SCOPE:
      spaces(indent);
      printf("{{ // new scope  locals=%p outer=%p: ",
             (void *) op->locals,
             (void *) op->locals->outer_scope);
      for (i = 0; i < op->locals->num_variables; i++) {
         printf("%s ", (char *) op->locals->variables[i]->a_name);
      }
      printf("\n");
      print_generic(op, NULL, indent+3);
      spaces(indent);
      printf("}}\n");
      break;

   case SLANG_OPER_VARIABLE_DECL:
      assert(op->num_children == 0 || op->num_children == 1);
      {
         slang_variable *v;
         v = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
         if (v) {
            const slang_variable_scope *scope;
            spaces(indent);
            printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
            print_type(&v->type);
            printf(" %s (%p)", (char *) op->a_id,
                   (void *) find_var(op->locals, op->a_id));

            scope = find_scope(op->locals, op->a_id);
            printf(" (in scope %p) ", (void *) scope);
            assert(scope);
            if (op->num_children == 1) {
               printf(" :=\n");
               slang_print_tree(&op->children[0], indent + 3);
            }
            else if (v->initializer) {
               printf(" := INITIALIZER\n");
               slang_print_tree(v->initializer, indent + 3);
            }
            else {
               printf(";\n");
            }
            /*
            spaces(indent);
            printf("TYPE: ");
            print_type(&v->type);
            spaces(indent);
            printf("ADDR: %d  size: %d\n", v->address, v->size);
            */
         }
         else {
            spaces(indent);
            printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
         }
      }
      break;

   case SLANG_OPER_ASM:
      spaces(indent);
      printf("ASM: %s at %p locals=%p outer=%p\n",
             (char *) op->a_id,
             (void *) op,
             (void *) op->locals,
             (void *) op->locals->outer_scope);
      print_generic(op, "ASM", indent+3);
      break;

   case SLANG_OPER_BREAK:
      spaces(indent);
      printf("BREAK\n");
      break;

   case SLANG_OPER_CONTINUE:
      spaces(indent);
      printf("CONTINUE\n");
      break;

   case SLANG_OPER_DISCARD:
      spaces(indent);
      printf("DISCARD\n");
      break;

   case SLANG_OPER_RETURN:
      spaces(indent);
      printf("RETURN\n");
      if (op->num_children > 0)
         slang_print_tree(&op->children[0], indent + 3);
      break;

   case SLANG_OPER_LABEL:
      spaces(indent);
      printf("LABEL %s\n", (char *) op->a_id);
      break;

   case SLANG_OPER_EXPRESSION:
      spaces(indent);
      printf("EXPR:  locals=%p outer=%p\n",
             (void *) op->locals,
             (void *) op->locals->outer_scope);
      /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
      slang_print_tree(&op->children[0], indent + 3);
      break;

   case SLANG_OPER_IF:
      spaces(indent);
      printf("IF\n");
      slang_print_tree(&op->children[0], indent + 3);
      spaces(indent);
      printf("THEN\n");
      slang_print_tree(&op->children[1], indent + 3);
      spaces(indent);
      printf("ELSE\n");
      slang_print_tree(&op->children[2], indent + 3);
      spaces(indent);
      printf("ENDIF\n");
      break;

   case SLANG_OPER_WHILE:
      assert(op->num_children == 2);
      spaces(indent);
      printf("WHILE LOOP: locals = %p\n", (void *) op->locals);
      indent += 3;
      spaces(indent);
      printf("WHILE cond:\n");
      slang_print_tree(&op->children[0], indent + 3);
      spaces(indent);
      printf("WHILE body:\n");
      slang_print_tree(&op->children[1], indent + 3);
      indent -= 3;
      spaces(indent);
      printf("END WHILE LOOP\n");
      break;

   case SLANG_OPER_DO:
      spaces(indent);
      printf("DO LOOP: locals = %p\n", (void *) op->locals);
      indent += 3;
      spaces(indent);
      printf("DO body:\n");
      slang_print_tree(&op->children[0], indent + 3);
      spaces(indent);
      printf("DO cond:\n");
      slang_print_tree(&op->children[1], indent + 3);
      indent -= 3;
      spaces(indent);
      printf("END DO LOOP\n");
      break;

   case SLANG_OPER_FOR:
      spaces(indent);
      printf("FOR LOOP: locals = %p\n", (void *) op->locals);
      indent += 3;
      spaces(indent);
      printf("FOR init:\n");
      slang_print_tree(&op->children[0], indent + 3);
      spaces(indent);
      printf("FOR condition:\n");
      slang_print_tree(&op->children[1], indent + 3);
      spaces(indent);
      printf("FOR step:\n");
      slang_print_tree(&op->children[2], indent + 3);
      spaces(indent);
      printf("FOR body:\n");
      slang_print_tree(&op->children[3], indent + 3);
      indent -= 3;
      spaces(indent);
      printf("ENDFOR\n");
      /*
      print_generic(op, "FOR", indent + 3);
      */
      break;

   case SLANG_OPER_VOID:
      spaces(indent);
      printf("(oper-void)\n");
      break;

   case SLANG_OPER_LITERAL_BOOL:
      spaces(indent);
      printf("LITERAL (");
      for (i = 0; i < op->literal_size; i++)
         printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
      printf(")\n");

      break;

   case SLANG_OPER_LITERAL_INT:
      spaces(indent);
      printf("LITERAL (");
      for (i = 0; i < op->literal_size; i++)
         printf("%d ", (int) op->literal[i]);
      printf(")\n");
      break;

   case SLANG_OPER_LITERAL_FLOAT:
      spaces(indent);
      printf("LITERAL (");
      for (i = 0; i < op->literal_size; i++)
         printf("%f ", op->literal[i]);
      printf(")\n");
      break;

   case SLANG_OPER_IDENTIFIER:
      {
         const slang_variable_scope *scope;
         spaces(indent);
         if (op->var && op->var->a_name) {
            scope = find_scope(op->locals, op->var->a_name);
            printf("VAR %s  (in scope %p)\n", (char *) op->var->a_name,
                   (void *) scope);
            assert(scope);
         }
         else {
            scope = find_scope(op->locals, op->a_id);
            printf("VAR' %s  (in scope %p) locals=%p outer=%p\n",
                   (char *) op->a_id,
                   (void *) scope,
                   (void *) op->locals,
                   (void *) op->locals->outer_scope);
            assert(scope);
         }
      }
      break;

   case SLANG_OPER_SEQUENCE:
      print_generic(op, "COMMA-SEQ", indent+3);
      break;

   case SLANG_OPER_ASSIGN:
      spaces(indent);
      printf("ASSIGNMENT  locals=%p outer=%p\n",
             (void *) op->locals,
             (void *) op->locals->outer_scope);
      print_binary(op, ":=", indent);
      break;

   case SLANG_OPER_ADDASSIGN:
      spaces(indent);
      printf("ASSIGN\n");
      print_binary(op, "+=", indent);
      break;

   case SLANG_OPER_SUBASSIGN:
      spaces(indent);
      printf("ASSIGN\n");
      print_binary(op, "-=", indent);
      break;

   case SLANG_OPER_MULASSIGN:
      spaces(indent);
      printf("ASSIGN\n");
      print_binary(op, "*=", indent);
      break;

   case SLANG_OPER_DIVASSIGN:
      spaces(indent);
      printf("ASSIGN\n");
      print_binary(op, "/=", indent);
      break;

	/*SLANG_OPER_MODASSIGN,*/
	/*SLANG_OPER_LSHASSIGN,*/
	/*SLANG_OPER_RSHASSIGN,*/
	/*SLANG_OPER_ORASSIGN,*/
	/*SLANG_OPER_XORASSIGN,*/
	/*SLANG_OPER_ANDASSIGN,*/
   case SLANG_OPER_SELECT:
      spaces(indent);
      printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
      assert(op->num_children == 3);
      slang_print_tree(&op->children[0], indent+3);
      spaces(indent);
      printf("?\n");
      slang_print_tree(&op->children[1], indent+3);
      spaces(indent);
      printf(":\n");
      slang_print_tree(&op->children[2], indent+3);
      break;

   case SLANG_OPER_LOGICALOR:
      print_binary(op, "||", indent);
      break;

   case SLANG_OPER_LOGICALXOR:
      print_binary(op, "^^", indent);
      break;

   case SLANG_OPER_LOGICALAND:
      print_binary(op, "&&", indent);
      break;

   /*SLANG_OPER_BITOR*/
   /*SLANG_OPER_BITXOR*/
   /*SLANG_OPER_BITAND*/
   case SLANG_OPER_EQUAL:
      print_binary(op, "==", indent);
      break;

   case SLANG_OPER_NOTEQUAL:
      print_binary(op, "!=", indent);
      break;

   case SLANG_OPER_LESS:
      print_binary(op, "<", indent);
      break;

   case SLANG_OPER_GREATER:
      print_binary(op, ">", indent);
      break;

   case SLANG_OPER_LESSEQUAL:
      print_binary(op, "<=", indent);
      break;

   case SLANG_OPER_GREATEREQUAL:
      print_binary(op, ">=", indent);
      break;

   /*SLANG_OPER_LSHIFT*/
   /*SLANG_OPER_RSHIFT*/
   case SLANG_OPER_ADD:
      print_binary(op, "+", indent);
      break;

   case SLANG_OPER_SUBTRACT:
      print_binary(op, "-", indent);
      break;

   case SLANG_OPER_MULTIPLY:
      print_binary(op, "*", indent);
      break;

   case SLANG_OPER_DIVIDE:
      print_binary(op, "/", indent);
      break;

   /*SLANG_OPER_MODULUS*/
   case SLANG_OPER_PREINCREMENT:
      spaces(indent);
      printf("PRE++\n");
      slang_print_tree(&op->children[0], indent+3);
      break;

   case SLANG_OPER_PREDECREMENT:
      spaces(indent);
      printf("PRE--\n");
      slang_print_tree(&op->children[0], indent+3);
      break;

   case SLANG_OPER_PLUS:
      spaces(indent);
      printf("SLANG_OPER_PLUS\n");
      break;

   case SLANG_OPER_MINUS:
      spaces(indent);
      printf("SLANG_OPER_MINUS\n");
      break;

   /*SLANG_OPER_COMPLEMENT*/
   case SLANG_OPER_NOT:
      spaces(indent);
      printf("NOT\n");
      slang_print_tree(&op->children[0], indent+3);
      break;

   case SLANG_OPER_SUBSCRIPT:
      spaces(indent);
      printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
             (void *) op->locals,
             (void *) op->locals->outer_scope);
      print_generic(op, NULL, indent+3);
      break;

   case SLANG_OPER_CALL:
#if 0
         slang_function *fun
            = _slang_function_locate(A->space.funcs, oper->a_id,
                                     oper->children,
                                     oper->num_children, &A->space, A->atoms);
#endif
      spaces(indent);
      printf("CALL %s(\n", (char *) op->a_id);
      for (i = 0; i < op->num_children; i++) {
         slang_print_tree(&op->children[i], indent+3);
         if (i + 1 < op->num_children) {
            spaces(indent + 3);
            printf(",\n");
         }
      }
      spaces(indent);
      printf(")\n");
      break;

   case SLANG_OPER_METHOD:
      spaces(indent);
      printf("METHOD CALL %s.%s\n", (char *) op->a_obj, (char *) op->a_id);
      break;

   case SLANG_OPER_FIELD:
      spaces(indent);
      printf("FIELD %s of\n", (char*) op->a_id);
      slang_print_tree(&op->children[0], indent+3);
      break;

   case SLANG_OPER_POSTINCREMENT:
      spaces(indent);
      printf("POST++\n");
      slang_print_tree(&op->children[0], indent+3);
      break;

   case SLANG_OPER_POSTDECREMENT:
      spaces(indent);
      printf("POST--\n");
      slang_print_tree(&op->children[0], indent+3);
      break;

   default:
      printf("unknown op->type %d\n", (int) op->type);
   }

}
Beispiel #6
0
/**
 * Adapt the arguments for a function call to match the parameters of
 * the given function.
 * This is for:
 * 1. converting/casting argument types to match parameters
 * 2. breaking up vector/matrix types into individual components to
 *    satisfy constructors.
 */
GLboolean
_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
                  const slang_name_space * space,
                  slang_atom_pool * atoms, slang_info_log *log)
{
   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
   const int numParams = fun->param_count - haveRetValue;
   int i;
   int dbg = 0;

   if (dbg) printf("Adapt %d args to %d parameters\n",
                   callOper->num_children, numParams);

   /* Only try adapting for constructors */
   if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
      return GL_FALSE;

   if (callOper->num_children != numParams) {
      /* number of arguments doesn't match number of parameters */

      if (fun->kind == SLANG_FUNC_CONSTRUCTOR) {
         /* For constructor calls, we can try to unroll vector/matrix args
          * into individual floats/ints and try to match the function params.
          */
         for (i = 0; i < numParams; i++) {
            slang_typeinfo argType;
            GLint argSz, j;

            /* Get type of arg[i] */
            if (!slang_typeinfo_construct(&argType))
               return GL_FALSE;
            if (!_slang_typeof_operation_(&callOper->children[i], space,
                                          &argType, atoms, log)) {
               slang_typeinfo_destruct(&argType);
               return GL_FALSE;
            }

            /*
            paramSz = _slang_sizeof_type_specifier(&paramVar->type.specifier);
            assert(paramSz == 1);
            */
            argSz = _slang_sizeof_type_specifier(&argType.spec);
            if (argSz > 1) {
               slang_operation origArg;
               /* break up arg[i] into components */
               if (dbg)
                  printf("Break up arg %d from 1 to %d elements\n", i, argSz);

               slang_operation_construct(&origArg);
               slang_operation_copy(&origArg,
                                    &callOper->children[i]);

               /* insert argSz-1 new children/args */
               for (j = 0; j < argSz - 1; j++) {
                  (void) slang_operation_insert(&callOper->num_children,
                                                &callOper->children, i);
               }

               /* replace arg[i+j] with subscript/index oper */
               for (j = 0; j < argSz; j++) {
                  callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
                  callOper->children[i + j].num_children = 2;
                  callOper->children[i + j].children = slang_operation_new(2);
                  slang_operation_copy(&callOper->children[i + j].children[0],
                                       &origArg);
                  callOper->children[i + j].children[1].type
                     = SLANG_OPER_LITERAL_INT;
                  callOper->children[i + j].children[1].literal[0] = j;
               }

            }
         } /* for i */
      }
      else {
         /* non-constructor function: number of args must match number
          * of function params.
          */
         return GL_FALSE; /* caller will record an error msg */
      }
   }

   if (callOper->num_children < numParams) {
      /* still not enough args for all params */
      return GL_FALSE;
   }
   else if (callOper->num_children > numParams) {
      /* now too many arguments */
      /* XXX this isn't always an error, see spec */
      return GL_FALSE;
   }

   /*
    * Second phase, argument casting.
    * Example:
    *   void foo(int i, bool b) {}
    *   x = foo(3.15, 9);
    * Gets translated into:
    *   x = foo(int(3.15), bool(9))
    */
   for (i = 0; i < numParams; i++) {
      slang_typeinfo argType;
      slang_variable *paramVar = fun->parameters->variables[i];

      /* Get type of arg[i] */
      if (!slang_typeinfo_construct(&argType))
         return GL_FALSE;
      if (!_slang_typeof_operation_(&callOper->children[i], space,
                                    &argType, atoms, log)) {
         slang_typeinfo_destruct(&argType);
         return GL_FALSE;
      }

      /* see if arg type matches parameter type */
      if (!slang_type_specifier_equal(&argType.spec,
                                      &paramVar->type.specifier)) {
         /* need to adapt arg type to match param type */
         const char *constructorName =
            slang_type_specifier_type_to_string(paramVar->type.specifier.type);
         slang_operation *child = slang_operation_new(1);

         slang_operation_copy(child, &callOper->children[i]);
         child->locals->outer_scope = callOper->children[i].locals;

         callOper->children[i].type = SLANG_OPER_CALL;
         callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
         callOper->children[i].num_children = 1;
         callOper->children[i].children = child;
      }

      slang_typeinfo_destruct(&argType);
   }

   if (dbg) {
      printf("===== New call to %s with adapted arguments ===============\n",
             (char*) fun->header.a_name);
      slang_print_tree(callOper, 5);
   }

   return GL_TRUE;
}