chmod a-x
[mesa.git] / src / mesa / shader / slang / slang_assemble_typeinfo.c
index 340d6c1c585bed44a73ac07265b0a87c13849892..21b31091ea772b236ee53179a9e56ad9ea2d5fdb 100644 (file)
 #include "imports.h"
 #include "slang_assemble.h"
 #include "slang_compile.h"
+#include "slang_error.h"
 
-/*
- * slang_type_specifier
- */
 
 GLvoid
 slang_type_specifier_ctr(slang_type_specifier * self)
@@ -113,7 +111,6 @@ slang_type_specifier_equal(const slang_type_specifier * x,
    return 1;
 }
 
-/* slang_assembly_typeinfo */
 
 GLboolean
 slang_assembly_typeinfo_construct(slang_assembly_typeinfo * ti)
@@ -129,33 +126,54 @@ slang_assembly_typeinfo_destruct(slang_assembly_typeinfo * ti)
    slang_type_specifier_dtr(&ti->spec);
 }
 
-/* _slang_typeof_operation() */
 
+/**
+ * Determine the return type of a function.
+ * \param name  name of the function
+ * \param params  array of function parameters
+ * \param num_params  number of parameters
+ * \param space  namespace to use
+ * \param spec  returns the function's type
+ * \param atoms  atom pool
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
 static GLboolean
-typeof_existing_function(const char *name, slang_operation * params,
-                         GLuint num_params, slang_assembly_name_space * space,
-                         slang_type_specifier * spec, slang_atom_pool * atoms)
+typeof_existing_function(const char *name, const slang_operation * params,
+                         GLuint num_params,
+                         const slang_assembly_name_space * space,
+                         slang_type_specifier * spec,
+                         slang_atom_pool * atoms)
 {
    slang_atom atom;
    GLboolean exists;
 
    atom = slang_atom_pool_atom(atoms, name);
-   if (!_slang_typeof_function
-       (atom, params, num_params, space, spec, &exists, atoms))
+   if (!_slang_typeof_function(atom, params, num_params, space, spec,
+                               &exists, atoms))
       return GL_FALSE;
    return exists;
 }
 
 GLboolean
-_slang_typeof_operation(slang_assemble_ctx * A, slang_operation * op,
+_slang_typeof_operation(const slang_assemble_ctx * A,
+                        const slang_operation * op,
                         slang_assembly_typeinfo * ti)
 {
    return _slang_typeof_operation_(op, &A->space, ti, A->atoms);
 }
 
+
+/**
+ * Determine the return type of an operation.
+ * \param op  the operation node
+ * \param space  the namespace to use
+ * \param ti  the returned type
+ * \param atoms  atom pool
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
 GLboolean
-_slang_typeof_operation_(slang_operation * op,
-                         slang_assembly_name_space * space,
+_slang_typeof_operation_(const slang_operation * op,
+                         const slang_assembly_name_space * space,
                          slang_assembly_typeinfo * ti,
                          slang_atom_pool * atoms)
 {
@@ -187,7 +205,7 @@ _slang_typeof_operation_(slang_operation * op,
    case slang_oper_preincrement:
    case slang_oper_predecrement:
       if (!_slang_typeof_operation_(op->children, space, ti, atoms))
-         return 0;
+         return GL_FALSE;
       break;
    case slang_oper_literal_bool:
    case slang_oper_logicalor:
@@ -211,12 +229,11 @@ _slang_typeof_operation_(slang_operation * op,
    case slang_oper_identifier:
       {
          slang_variable *var;
-
          var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
          if (var == NULL)
-            return GL_FALSE;
+            RETURN_ERROR2("undefined variable", (char *) op->a_id, 0);
          if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier))
-            return GL_FALSE;
+            RETURN_OUT_OF_MEMORY();
          ti->can_be_referenced = GL_TRUE;
          ti->array_len = var->array_len;
       }
@@ -224,7 +241,7 @@ _slang_typeof_operation_(slang_operation * op,
    case slang_oper_sequence:
       /* TODO: check [0] and [1] if they match */
       if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms))
-         return GL_FALSE;
+         RETURN_NIL();
       ti->can_be_referenced = GL_FALSE;
       ti->is_swizzled = GL_FALSE;
       break;
@@ -237,7 +254,7 @@ _slang_typeof_operation_(slang_operation * op,
    case slang_oper_select:
       /* TODO: check [1] and [2] if they match */
       if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms))
-         return GL_FALSE;
+         RETURN_NIL();
       ti->can_be_referenced = GL_FALSE;
       ti->is_swizzled = GL_FALSE;
       break;
@@ -247,36 +264,36 @@ _slang_typeof_operation_(slang_operation * op,
       /*case slang_oper_lshift: */
       /*case slang_oper_rshift: */
    case slang_oper_add:
-      if (!typeof_existing_function
-          ("+", op->children, 2, space, &ti->spec, atoms))
-         return GL_FALSE;
+      if (!typeof_existing_function("+", op->children, 2, space,
+                                    &ti->spec, atoms))
+         RETURN_NIL();
       break;
    case slang_oper_subtract:
-      if (!typeof_existing_function
-          ("-", op->children, 2, space, &ti->spec, atoms))
-         return GL_FALSE;
+      if (!typeof_existing_function("-", op->children, 2, space,
+                                    &ti->spec, atoms))
+         RETURN_NIL();
       break;
    case slang_oper_multiply:
-      if (!typeof_existing_function
-          ("*", op->children, 2, space, &ti->spec, atoms))
-         return GL_FALSE;
+      if (!typeof_existing_function("*", op->children, 2, space,
+                                    &ti->spec, atoms))
+         RETURN_NIL();
       break;
    case slang_oper_divide:
-      if (!typeof_existing_function
-          ("/", op->children, 2, space, &ti->spec, atoms))
-         return GL_FALSE;
+      if (!typeof_existing_function("/", op->children, 2, space,
+                                    &ti->spec, atoms))
+         RETURN_NIL();
       break;
       /*case slang_oper_modulus: */
    case slang_oper_plus:
       if (!_slang_typeof_operation_(op->children, space, ti, atoms))
-         return GL_FALSE;
+         RETURN_NIL();
       ti->can_be_referenced = GL_FALSE;
       ti->is_swizzled = GL_FALSE;
       break;
    case slang_oper_minus:
-      if (!typeof_existing_function
-          ("-", op->children, 1, space, &ti->spec, atoms))
-         return GL_FALSE;
+      if (!typeof_existing_function("-", op->children, 1, space,
+                                    &ti->spec, atoms))
+         RETURN_NIL();
       break;
       /*case slang_oper_complement: */
    case slang_oper_subscript:
@@ -284,23 +301,23 @@ _slang_typeof_operation_(slang_operation * op,
          slang_assembly_typeinfo _ti;
 
          if (!slang_assembly_typeinfo_construct(&_ti))
-            return GL_FALSE;
+            RETURN_NIL();
          if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) {
             slang_assembly_typeinfo_destruct(&_ti);
-            return GL_FALSE;
+            RETURN_NIL();
          }
          ti->can_be_referenced = _ti.can_be_referenced;
          if (_ti.spec.type == slang_spec_array) {
             if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
                slang_assembly_typeinfo_destruct(&_ti);
-               return GL_FALSE;
+               RETURN_NIL();
             }
          }
          else {
             if (!_slang_type_is_vector(_ti.spec.type)
                 && !_slang_type_is_matrix(_ti.spec.type)) {
                slang_assembly_typeinfo_destruct(&_ti);
-               return GL_FALSE;
+               RETURN_ERROR("cannot index a non-array type", 0);
             }
             ti->spec.type = _slang_type_base(_ti.spec.type);
          }
@@ -311,10 +328,9 @@ _slang_typeof_operation_(slang_operation * op,
       {
          GLboolean exists;
 
-         if (!_slang_typeof_function
-             (op->a_id, op->children, op->num_children, space, &ti->spec,
-              &exists, atoms))
-            return GL_FALSE;
+         if (!_slang_typeof_function(op->a_id, op->children, op->num_children,
+                                     space, &ti->spec, &exists, atoms))
+            RETURN_NIL();
          if (!exists) {
             slang_struct *s =
                slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
@@ -323,14 +339,14 @@ _slang_typeof_operation_(slang_operation * op,
                ti->spec._struct =
                   (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
                if (ti->spec._struct == NULL)
-                  return GL_FALSE;
+                  RETURN_NIL();
                if (!slang_struct_construct(ti->spec._struct)) {
                   slang_alloc_free(ti->spec._struct);
                   ti->spec._struct = NULL;
-                  return GL_FALSE;
+                  RETURN_NIL();
                }
                if (!slang_struct_copy(ti->spec._struct, s))
-                  return GL_FALSE;
+                  RETURN_NIL();
             }
             else {
                const char *name;
@@ -339,7 +355,7 @@ _slang_typeof_operation_(slang_operation * op,
                name = slang_atom_pool_id(atoms, op->a_id);
                type = slang_type_specifier_type_from_string(name);
                if (type == slang_spec_void)
-                  return GL_FALSE;
+                  RETURN_ERROR2("function not found", name, 0);
                ti->spec.type = type;
             }
          }
@@ -350,24 +366,23 @@ _slang_typeof_operation_(slang_operation * op,
          slang_assembly_typeinfo _ti;
 
          if (!slang_assembly_typeinfo_construct(&_ti))
-            return GL_FALSE;
+            RETURN_NIL();
          if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) {
             slang_assembly_typeinfo_destruct(&_ti);
-            return GL_FALSE;
+            RETURN_NIL();
          }
          if (_ti.spec.type == slang_spec_struct) {
             slang_variable *field;
 
-            field =
-               _slang_locate_variable(_ti.spec._struct->fields, op->a_id,
-                                      GL_FALSE);
+            field = _slang_locate_variable(_ti.spec._struct->fields, op->a_id,
+                                           GL_FALSE);
             if (field == NULL) {
                slang_assembly_typeinfo_destruct(&_ti);
-               return GL_FALSE;
+               RETURN_NIL();
             }
             if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
                slang_assembly_typeinfo_destruct(&_ti);
-               return GL_FALSE;
+               RETURN_NIL();
             }
             ti->can_be_referenced = _ti.can_be_referenced;
          }
@@ -377,15 +392,17 @@ _slang_typeof_operation_(slang_operation * op,
             slang_type_specifier_type base;
 
             /* determine the swizzle of the field expression */
+#if 000
             if (!_slang_type_is_vector(_ti.spec.type)) {
                slang_assembly_typeinfo_destruct(&_ti);
-               return GL_FALSE;
+               RETURN_ERROR("Can't swizzle scalar expression", 0);
             }
+#endif
             rows = _slang_type_dim(_ti.spec.type);
             swizzle = slang_atom_pool_id(atoms, op->a_id);
             if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
                slang_assembly_typeinfo_destruct(&_ti);
-               return GL_FALSE;
+               RETURN_ERROR("Bad swizzle", 0);
             }
             ti->is_swizzled = GL_TRUE;
             ti->can_be_referenced = _ti.can_be_referenced
@@ -457,38 +474,49 @@ _slang_typeof_operation_(slang_operation * op,
    case slang_oper_postincrement:
    case slang_oper_postdecrement:
       if (!_slang_typeof_operation_(op->children, space, ti, atoms))
-         return GL_FALSE;
+         RETURN_NIL();
       ti->can_be_referenced = GL_FALSE;
       ti->is_swizzled = GL_FALSE;
       break;
    default:
-      return GL_FALSE;
+      RETURN_NIL();
    }
 
    return GL_TRUE;
 }
 
-/* _slang_typeof_function() */
 
+
+/**
+ * Determine the return type of a function.
+ * \param a_name  the function name
+ * \param param  function parameters (overloading)
+ * \param num_params  number of parameters to function
+ * \param space  namespace to search
+ * \param exists  returns GL_TRUE or GL_FALSE to indicate existance of function
+ * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
+ */
 GLboolean
-_slang_typeof_function(slang_atom a_name, slang_operation * params,
-                       GLuint num_params, slang_assembly_name_space * space,
+_slang_typeof_function(slang_atom a_name, const slang_operation * params,
+                       GLuint num_params,
+                       const slang_assembly_name_space * space,
                        slang_type_specifier * spec, GLboolean * exists,
                        slang_atom_pool * atoms)
 {
-   slang_function *fun;
-
-   fun =
-      _slang_locate_function(space->funcs, a_name, params, num_params, space,
-                             atoms);
+   slang_function *fun = _slang_locate_function(space->funcs, a_name, params,
+                                                num_params, space, atoms);
    *exists = fun != NULL;
-   if (fun == NULL)
-      return GL_TRUE;
+   if (!fun)
+      return GL_TRUE;  /* yes, not false */
    return slang_type_specifier_copy(spec, &fun->header.type.specifier);
 }
 
-/* _slang_type_is_matrix() */
 
+
+/**
+ * Determine if a type is a matrix.
+ * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
+ */
 GLboolean
 _slang_type_is_matrix(slang_type_specifier_type ty)
 {
@@ -502,8 +530,11 @@ _slang_type_is_matrix(slang_type_specifier_type ty)
    }
 }
 
-/* _slang_type_is_vector() */
 
+/**
+ * Determine if a type is a vector.
+ * \return GL_TRUE if is a vector, GL_FALSE otherwise.
+ */
 GLboolean
 _slang_type_is_vector(slang_type_specifier_type ty)
 {
@@ -523,8 +554,10 @@ _slang_type_is_vector(slang_type_specifier_type ty)
    }
 }
 
-/* _slang_type_base_of_vector() */
 
+/**
+ * Given a vector type, return the type of the vector's elements
+ */
 slang_type_specifier_type
 _slang_type_base(slang_type_specifier_type ty)
 {
@@ -555,8 +588,10 @@ _slang_type_base(slang_type_specifier_type ty)
    }
 }
 
-/* _slang_type_dim */
 
+/**
+ * Return the dimensionality of a vector or matrix type.
+ */
 GLuint
 _slang_type_dim(slang_type_specifier_type ty)
 {