[gtk+/wip/otte/shader: 85/176] gsksl: Builtin constructors are no longer functions



commit 37bb67e16a9d173657d5f7a534d1ba72e7cef977
Author: Benjamin Otte <otte redhat com>
Date:   Tue Oct 3 03:58:40 2017 +0200

    gsksl: Builtin constructors are no longer functions
    
    They don't obey the laws that govern constructors (argument promotion,
    constant amount of predefined types of arguments and so on).
    So we turn constructor calls into their own expression type.
    
    This also dimplifies function call validation because we don't have to
    do two-in-one with constructors in there.
    
    And while doing that, also fix up the rules that govern constructor
    arguments: Matrixes aren't allowed as arguments for matrixes unless
    they're the first and only argument.
    And if scalars are the first and only argument, they behave differently
    than they would otherwise.

 gsk/gskslexpression.c        |  441 +++++++++++++++++++++++++++++++++++-------
 gsk/gskslexpressionprivate.h |    6 +-
 gsk/gskslfunction.c          |   91 +---------
 gsk/gskslfunctionprivate.h   |    2 -
 gsk/gskslstatement.c         |   13 +-
 5 files changed, 379 insertions(+), 174 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 6161499..38f7681 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -713,6 +713,227 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_REFERENCE = {
   gsk_sl_expression_reference_write_spv
 };
 
+/* CONSTRUCTOR CALL */
+
+typedef struct _GskSlExpressionConstructor GskSlExpressionConstructor;
+
+struct _GskSlExpressionConstructor {
+  GskSlExpression parent;
+
+  GskSlType *type;
+  GskSlExpression **arguments;
+  guint n_arguments;
+};
+
+static void
+gsk_sl_expression_constructor_free (GskSlExpression *expression)
+{
+  GskSlExpressionConstructor *constructor = (GskSlExpressionConstructor *) expression;
+  guint i;
+
+  for (i = 0; i < constructor->n_arguments; i++)
+    {
+      gsk_sl_expression_unref (constructor->arguments[i]);
+    }
+  g_free (constructor->arguments);
+
+  gsk_sl_type_unref (constructor->type);
+
+  g_slice_free (GskSlExpressionConstructor, constructor);
+}
+
+static void
+gsk_sl_expression_constructor_print (const GskSlExpression *expression,
+                                       GskSlPrinter          *printer)
+{
+  const GskSlExpressionConstructor *constructor = (const GskSlExpressionConstructor *) expression;
+  guint i;
+
+  gsk_sl_printer_append (printer, gsk_sl_type_get_name (constructor->type));
+  gsk_sl_printer_append (printer, " (");
+  
+  for (i = 0; i < constructor->n_arguments; i++)
+    {
+      if (i > 0)
+        gsk_sl_printer_append (printer, ", ");
+      gsk_sl_expression_print (constructor->arguments[i], printer);
+    }
+
+  gsk_sl_printer_append (printer, ")");
+}
+
+static GskSlType *
+gsk_sl_expression_constructor_get_return_type (const GskSlExpression *expression)
+{
+  const GskSlExpressionConstructor *constructor = (const GskSlExpressionConstructor *) expression;
+
+  return constructor->type;
+}
+
+static GskSlValue *
+gsk_sl_expression_constructor_get_constant (const GskSlExpression *expression)
+{
+  const GskSlExpressionConstructor *constructor = (const GskSlExpressionConstructor *) expression;
+  GskSlType *type = constructor->type;
+  GskSlValue *values[constructor->n_arguments];
+  GskSlValue *result;
+  guint i;
+
+  for (i = 0; i < constructor->n_arguments; i++)
+    {
+      values[i] = gsk_sl_expression_get_constant (constructor->arguments[i]);
+      if (values[i] == NULL)
+        {
+          guint j;
+          for (j = 0; j < i; j++)
+            gsk_sl_value_free (values[j]);
+          return NULL;
+        }
+    }
+
+  result = gsk_sl_value_new (type);
+
+  if (constructor->n_arguments == 1 && gsk_sl_type_is_scalar (gsk_sl_value_get_type (values[0])))
+    {
+      GskSlScalarType sscalar, dscalar;
+      guchar *sdata, *ddata;
+      gsize dstride;
+      
+      sscalar = gsk_sl_type_get_scalar_type (gsk_sl_value_get_type (values[0]));
+      sdata = gsk_sl_value_get_data (values[0]);
+      dscalar = gsk_sl_type_get_scalar_type (type);
+      ddata = gsk_sl_value_get_data (result);
+      dstride = gsk_sl_scalar_type_get_size (dscalar);
+
+      if (gsk_sl_type_is_scalar (type))
+        {
+          gsk_sl_scalar_type_convert_value (dscalar, ddata, sscalar, sdata);
+        }
+      else if (gsk_sl_type_is_vector (type))
+        {
+          gsize i;
+          for (i = 0; i < gsk_sl_type_get_n_components (type); i++)
+            {
+              gsk_sl_scalar_type_convert_value (dscalar, ddata + i * dstride, sscalar, sdata);
+            }
+        }
+      else if (gsk_sl_type_is_matrix (type))
+        {
+          gsize i, n, step;
+
+          n = gsk_sl_type_get_n_components (type);
+          step = n / gsk_sl_type_get_length (type) + 1;
+          for (i = 0; i < n; i += step)
+            {
+              gsk_sl_scalar_type_convert_value (dscalar, ddata + i * dstride, sscalar, sdata);
+            }
+        }
+    }
+  else if (constructor->n_arguments == 1 && gsk_sl_type_is_matrix (gsk_sl_value_get_type (values[0])) && 
gsk_sl_type_is_matrix (type))
+    {
+      GskSlScalarType sscalar, dscalar;
+      guchar *sdata, *ddata;
+      gsize drows, dcols, srows, scols, r, c, sstride, dstride;
+      
+      sscalar = gsk_sl_type_get_scalar_type (gsk_sl_value_get_type (values[0]));
+      sstride = gsk_sl_scalar_type_get_size (sscalar);
+      sdata = gsk_sl_value_get_data (values[0]);
+      scols = gsk_sl_type_get_length (gsk_sl_value_get_type (values[0]));
+      srows = gsk_sl_type_get_length (gsk_sl_value_get_type (values[0]));
+      dscalar = gsk_sl_type_get_scalar_type (type);
+      dstride = gsk_sl_scalar_type_get_size (dscalar);
+      ddata = gsk_sl_value_get_data (result);
+      dcols = gsk_sl_type_get_length (type);
+      drows = gsk_sl_type_get_length (gsk_sl_type_get_index_type (type));
+
+      for (c = 0; c < scols; c++)
+        {
+          for (r = 0; r < srows; r++)
+            {
+              gsk_sl_scalar_type_convert_value (dscalar,
+                                                ddata + dstride * (c * drows + r),
+                                                sscalar,
+                                                sdata + sstride * (c * srows + r));
+            }
+          for (; r < drows; r++)
+            {
+              gsk_sl_scalar_type_convert_value (dscalar,
+                                                ddata + dstride * (c * drows + r),
+                                                GSK_SL_FLOAT,
+                                                &(float) { c == r ? 1 : 0 });
+            }
+        }
+      for (; c < dcols; c++)
+        {
+          for (r = 0; r < drows; r++)
+            {
+              gsk_sl_scalar_type_convert_value (dscalar,
+                                                ddata + dstride * (c * drows + r),
+                                                GSK_SL_FLOAT,
+                                                &(float) { c == r ? 1 : 0 });
+            }
+        }
+    }
+  else
+    {
+      GskSlScalarType sscalar, dscalar;
+      guchar *sdata, *ddata;
+      gsize i, n, j, si, sn, sstride, dstride;
+      
+      dscalar = gsk_sl_type_get_scalar_type (type);
+      dstride = gsk_sl_scalar_type_get_size (dscalar);
+      n = gsk_sl_type_get_n_components (type);
+      ddata = gsk_sl_value_get_data (result);
+      sscalar = GSK_SL_VOID;
+      sdata = NULL;
+      sstride = 0;
+
+      j = 0;
+      sn = 0;
+      si = 0;
+      for (i = 0; i < n; i++)
+        {
+          if (si == sn)
+            {
+              sscalar = gsk_sl_type_get_scalar_type (gsk_sl_value_get_type (values[j]));
+              sstride = gsk_sl_scalar_type_get_size (sscalar);
+              sdata = gsk_sl_value_get_data (values[j]);
+              si = 0;
+              sn = gsk_sl_type_get_n_components (gsk_sl_value_get_type (values[j]));
+              j++;
+            }
+
+          gsk_sl_scalar_type_convert_value (dscalar,
+                                            ddata + dstride * i,
+                                            sscalar,
+                                            sdata + sstride * si);
+          si++;
+        }
+    }
+
+  for (i = 0; i < constructor->n_arguments; i++)
+    gsk_sl_value_free (values[i]);
+
+  return result;
+}
+
+static guint32
+gsk_sl_expression_constructor_write_spv (const GskSlExpression *expression,
+                                         GskSpvWriter          *writer)
+{
+  g_assert_not_reached ();
+
+  return 0;
+}
+
+static const GskSlExpressionClass GSK_SL_EXPRESSION_CONSTRUCTOR = {
+  gsk_sl_expression_constructor_free,
+  gsk_sl_expression_constructor_print,
+  gsk_sl_expression_constructor_get_return_type,
+  gsk_sl_expression_constructor_get_constant,
+  gsk_sl_expression_constructor_write_spv
+};
+
 /* FUNCTION_CALL */
 
 typedef struct _GskSlExpressionFunctionCall GskSlExpressionFunctionCall;
@@ -1266,14 +1487,122 @@ gsk_sl_expression_error_new (void)
 }
 
 GskSlExpression *
+gsk_sl_expression_parse_constructor (GskSlScope        *scope,
+                                     GskSlPreprocessor *stream,
+                                     GskSlType         *type)
+{
+  GskSlExpressionConstructor *call;
+  const GskSlToken *token;
+  gssize missing_args;
+  GPtrArray *arguments;
+
+  call = gsk_sl_expression_new (GskSlExpressionConstructor, &GSK_SL_EXPRESSION_CONSTRUCTOR);
+  call->type = gsk_sl_type_ref (type);
+
+  token = gsk_sl_preprocessor_get (stream);
+  if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
+    {
+      gsk_sl_preprocessor_error (stream, SYNTAX, "Expected opening \"(\" when calling function.");
+      gsk_sl_expression_unref ((GskSlExpression *) call);
+      return gsk_sl_expression_error_new ();
+    }
+  gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
+
+  missing_args = gsk_sl_type_get_n_components (type);
+  arguments = g_ptr_array_new ();
+
+  token = gsk_sl_preprocessor_get (stream);
+  
+  while (TRUE)
+    {
+      GskSlExpression *expression = gsk_sl_expression_parse_assignment (scope, stream);
+
+      if (missing_args == 0)
+        {
+          gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
+                                     "Too many arguments given to builtin constructor, need only %u.",
+                                     arguments->len);
+          missing_args = -1;
+        }
+      else if (missing_args > 0)
+        {
+          GskSlType *return_type = gsk_sl_expression_get_return_type (expression);
+          gsize provided = gsk_sl_type_get_n_components (return_type);
+
+          if (provided == 0)
+            {
+              gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                         "Invalid type %s for builtin constructor",
+                                         gsk_sl_type_get_name (return_type));
+              missing_args = -1;
+            }
+          else if (gsk_sl_type_is_matrix (return_type) && 
+                   gsk_sl_type_is_matrix (type))
+            {
+              if (arguments->len == 0)
+                {
+                  missing_args = 0;
+                }
+              else
+                {
+                  gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                             "Matrix type %s only valid as first argument for %s",
+                                             gsk_sl_type_get_name (return_type),
+                                             gsk_sl_type_get_name (type));
+                  missing_args = -1;
+                }
+            }
+          else
+            {
+              missing_args -= MIN (missing_args, provided);
+            }
+        }
+
+      g_ptr_array_add (arguments, expression);
+      
+      token = gsk_sl_preprocessor_get (stream);
+      if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
+        break;
+      gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
+    }
+
+  if (missing_args > 0)
+    {
+      if (arguments->len != 1 || !gsk_sl_type_is_scalar (gsk_sl_expression_get_return_type 
(g_ptr_array_index (arguments, 0))))
+        {
+          gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
+                                     "Not enough arguments given to builtin constructor, %"G_GSIZE_FORMAT" 
are missing.",
+                                     missing_args);
+          missing_args = -1;
+        }
+    }
+
+  call->n_arguments = arguments->len;
+  call->arguments = (GskSlExpression **) g_ptr_array_free (arguments, FALSE);
+
+  if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
+    {
+      gsk_sl_preprocessor_error (stream, SYNTAX, "Expected closing \")\" after arguments.");
+      gsk_sl_preprocessor_sync (stream, GSK_SL_TOKEN_RIGHT_PAREN);
+    }
+  gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
+
+  if (missing_args < 0)
+    {
+      gsk_sl_expression_unref ((GskSlExpression *) call);
+      return gsk_sl_expression_error_new ();
+    }
+  
+  return (GskSlExpression *) call;
+}
+
+GskSlExpression *
 gsk_sl_expression_parse_function_call (GskSlScope           *scope,
                                        GskSlPreprocessor    *stream,
-                                       GskSlFunctionMatcher *matcher,
-                                       GskSlFunction        *function)
+                                       GskSlFunctionMatcher *matcher)
 {
   GskSlExpressionFunctionCall *call;
   const GskSlToken *token;
-  gssize missing_args; /* only used for builtin constructors */
 
   call = gsk_sl_expression_new (GskSlExpressionFunctionCall, &GSK_SL_EXPRESSION_FUNCTION_CALL);
 
@@ -1286,11 +1615,6 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
     }
   gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
 
-  if (function && gsk_sl_function_is_builtin_constructor (function))
-    missing_args = gsk_sl_type_get_n_components (gsk_sl_function_get_return_type (function));
-  else
-    missing_args = -1;
-
   token = gsk_sl_preprocessor_get (stream);
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
     {
@@ -1301,7 +1625,7 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
         {
           GskSlExpression *expression = gsk_sl_expression_parse_assignment (scope, stream);
 
-          if (function == NULL && matcher == NULL)
+          if (matcher == NULL)
             {
               /* no checking necessary */
             }
@@ -1312,43 +1636,10 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
               gsk_sl_function_matcher_match_argument (matcher, arguments->len, type);
               if (!gsk_sl_function_matcher_has_matches (matcher))
                 {
-                  if (function)
-                    gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
-                                               "Cannot convert argument %u from %s to %s.",
-                                               arguments->len + 1,
-                                               gsk_sl_type_get_name (type),
-                                               gsk_sl_type_get_name (gsk_sl_function_get_argument_type 
(function, arguments->len)));
-                  else
-                    gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
-                                               "No overloaded function available that matches the first %u 
arguments",
-                                               arguments->len + 1);
-
-                  matcher = NULL;
-                  function = NULL;
-                }
-            }
-          else if (missing_args == 0)
-            {
-              gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
-                                         "Too many arguments given to builtin constructor, only the first %u 
are necessary.",
-                                         arguments->len);
-              function = NULL;
-            }
-          else if (missing_args > 0)
-            {
-              GskSlType *type = gsk_sl_expression_get_return_type (expression);
-              gsize provided = gsk_sl_type_get_n_components (type);
-
-              if (provided == 0)
-                {
                   gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
-                                             "Invalid type %s for builtin constructor",
-                                             gsk_sl_type_get_name (type));
-                  function = NULL;
-                }
-              else
-                {
-                  missing_args -= MIN (missing_args, provided);
+                                             "No overloaded function available that matches the first %u 
arguments",
+                                             arguments->len + 1);
+                  matcher = NULL;
                 }
             }
 
@@ -1360,14 +1651,6 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
           gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
         }
 
-      if (missing_args > 0)
-        {
-          gsk_sl_preprocessor_error (stream, ARGUMENT_COUNT,
-                                     "Not enough arguments given to builtin constructor, %"G_GSIZE_FORMAT" 
are missing.",
-                                     missing_args);
-          function = NULL;
-        }
-
       call->n_arguments = arguments->len;
       call->arguments = (GskSlExpression **) g_ptr_array_free (arguments, FALSE);
     }
@@ -1377,23 +1660,22 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
       gsk_sl_function_matcher_match_n_arguments (matcher, call->n_arguments);
       if (!gsk_sl_function_matcher_has_matches (matcher))
         {
-          if (function)
-            gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
-                                       "Function %s needs %"G_GSIZE_FORMAT" arguments, but %u given.",
-                                       gsk_sl_function_get_name (function),
-                                       gsk_sl_function_get_n_arguments (function),
-                                       call->n_arguments);
-          else
-            gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
-                                       "No overloaded function available that matches this call");
-          function = NULL;
+          gsk_sl_preprocessor_error (stream, TYPE_MISMATCH,
+                                     "No overloaded function available with %u arguments.",
+                                     call->n_arguments);
+          matcher = NULL;
         }
       else
         {
-          function = gsk_sl_function_matcher_get_match (matcher);
-          if (function == NULL)
-            gsk_sl_preprocessor_error (stream, UNIQUENESS,
-                                       "Cannot find unique match for overloaded function.");
+          call->function = gsk_sl_function_matcher_get_match (matcher);
+          if (call->function)
+            gsk_sl_function_ref (call->function);
+          else
+            {
+              gsk_sl_preprocessor_error (stream, UNIQUENESS,
+                                         "Cannot find unique match for overloaded function.");
+              matcher = NULL;
+            }
         }           
     }
 
@@ -1401,16 +1683,16 @@ gsk_sl_expression_parse_function_call (GskSlScope           *scope,
     {
       gsk_sl_preprocessor_error (stream, SYNTAX, "Expected closing \")\" after arguments.");
       gsk_sl_preprocessor_sync (stream, GSK_SL_TOKEN_RIGHT_PAREN);
+      matcher = NULL;
     }
   gsk_sl_preprocessor_consume (stream, (GskSlExpression *) call);
 
-  if (function == NULL)
+  if (matcher == NULL)
     {
       gsk_sl_expression_unref ((GskSlExpression *) call);
       return gsk_sl_expression_error_new ();
     }
   
-  call->function = gsk_sl_function_ref (function);
   return (GskSlExpression *) call;
 }
 
@@ -1440,7 +1722,7 @@ gsk_sl_expression_parse_primary (GskSlScope        *scope,
             gsk_sl_preprocessor_consume (stream, NULL);
             constructor = gsk_sl_function_new_constructor (type);
             gsk_sl_function_matcher_init (&matcher, g_list_prepend (NULL, constructor));
-            expr = gsk_sl_expression_parse_function_call (scope, stream, &matcher, constructor);
+            expr = gsk_sl_expression_parse_function_call (scope, stream, &matcher);
             gsk_sl_function_matcher_finish (&matcher);
             gsk_sl_function_unref (constructor);
 
@@ -1460,9 +1742,7 @@ gsk_sl_expression_parse_primary (GskSlScope        *scope,
             if (!gsk_sl_function_matcher_has_matches (&matcher))
               gsk_sl_preprocessor_error (stream, DECLARATION, "No function named \"%s\".", name);
             
-            expr = gsk_sl_expression_parse_function_call (scope, stream,
-                                                          &matcher,
-                                                          gsk_sl_function_matcher_get_match (&matcher));
+            expr = gsk_sl_expression_parse_function_call (scope, stream, &matcher);
 
             gsk_sl_function_matcher_finish (&matcher);
           }
@@ -1584,15 +1864,28 @@ gsk_sl_expression_parse_primary (GskSlScope        *scope,
     case GSK_SL_TOKEN_DMAT4X2:
     case GSK_SL_TOKEN_DMAT4X3:
     case GSK_SL_TOKEN_DMAT4X4:
+      {
+        GskSlExpression *expression;
+        GskSlType *type;
+
+        type = gsk_sl_type_new_parse (scope, stream);
+        expression = gsk_sl_expression_parse_constructor (scope, stream, type);
+        gsk_sl_type_unref (type);
+
+        return expression;
+      }
     case GSK_SL_TOKEN_STRUCT:
       {
+        GskSlFunctionMatcher matcher;
         GskSlFunction *constructor;
         GskSlExpression *expression;
         GskSlType *type;
 
         type = gsk_sl_type_new_parse (scope, stream);
         constructor = gsk_sl_function_new_constructor (type);
-        expression = gsk_sl_expression_parse_function_call (scope, stream, NULL, constructor);
+        gsk_sl_function_matcher_init (&matcher, g_list_prepend (NULL, constructor));
+        expression = gsk_sl_expression_parse_function_call (scope, stream, &matcher);
+        gsk_sl_function_matcher_finish (&matcher);
         gsk_sl_function_unref (constructor);
         gsk_sl_type_unref (type);
 
diff --git a/gsk/gskslexpressionprivate.h b/gsk/gskslexpressionprivate.h
index 3c169e8..0247ad6 100644
--- a/gsk/gskslexpressionprivate.h
+++ b/gsk/gskslexpressionprivate.h
@@ -29,10 +29,12 @@ GskSlExpression *       gsk_sl_expression_parse_assignment      (GskSlScope
                                                                  GskSlPreprocessor      *stream);
 GskSlExpression *       gsk_sl_expression_parse_constant        (GskSlScope             *scope,
                                                                  GskSlPreprocessor      *stream);
+GskSlExpression *       gsk_sl_expression_parse_constructor     (GskSlScope             *scope,
+                                                                 GskSlPreprocessor      *stream,
+                                                                 GskSlType              *type);
 GskSlExpression *       gsk_sl_expression_parse_function_call   (GskSlScope             *scope,
                                                                  GskSlPreprocessor      *stream,
-                                                                 GskSlFunctionMatcher   *matcher,
-                                                                 GskSlFunction          *function);
+                                                                 GskSlFunctionMatcher   *matcher);
 
 GskSlExpression *       gsk_sl_expression_ref                   (GskSlExpression        *expression);
 void                    gsk_sl_expression_unref                 (GskSlExpression        *expression);
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 79117b8..2f98e35 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -72,78 +72,6 @@ gsk_sl_function_alloc (const GskSlFunctionClass *klass,
 
 /* CONSTRUCTOR */
 
-typedef struct _GskSlFunctionBuiltinConstructor GskSlFunctionBuiltinConstructor;
-
-struct _GskSlFunctionBuiltinConstructor {
-  GskSlFunction parent;
-
-  GskSlType *type;
-};
-
-static void
-gsk_sl_function_builtin_constructor_free (GskSlFunction *function)
-{
-  GskSlFunctionBuiltinConstructor *builtin_constructor = (GskSlFunctionBuiltinConstructor *) function;
-
-  gsk_sl_type_unref (builtin_constructor->type);
-
-  g_slice_free (GskSlFunctionBuiltinConstructor, builtin_constructor);
-}
-
-static GskSlType *
-gsk_sl_function_builtin_constructor_get_return_type (const GskSlFunction *function)
-{
-  const GskSlFunctionBuiltinConstructor *builtin_constructor = (const GskSlFunctionBuiltinConstructor *) 
function;
-
-  return builtin_constructor->type;
-}
-
-static const char *
-gsk_sl_function_builtin_constructor_get_name (const GskSlFunction *function)
-{
-  const GskSlFunctionBuiltinConstructor *builtin_constructor = (const GskSlFunctionBuiltinConstructor *) 
function;
-
-  return gsk_sl_type_get_name (builtin_constructor->type);
-}
-
-static gsize
-gsk_sl_function_builtin_constructor_get_n_arguments (const GskSlFunction *function)
-{
-  return 0;
-}
-
-static GskSlType *
-gsk_sl_function_builtin_constructor_get_argument_type (const GskSlFunction *function,
-                                                       gsize                i)
-{
-  return NULL;
-}
-
-static void
-gsk_sl_function_builtin_constructor_print (const GskSlFunction *function,
-                                           GskSlPrinter        *printer)
-{
-}
-
-static guint32
-gsk_sl_function_builtin_constructor_write_spv (const GskSlFunction *function,
-                                               GskSpvWriter        *writer)
-{
-  return 0;
-}
-
-static const GskSlFunctionClass GSK_SL_FUNCTION_BUILTIN_CONSTRUCTOR = {
-  gsk_sl_function_builtin_constructor_free,
-  gsk_sl_function_builtin_constructor_get_return_type,
-  gsk_sl_function_builtin_constructor_get_name,
-  gsk_sl_function_builtin_constructor_get_n_arguments,
-  gsk_sl_function_builtin_constructor_get_argument_type,
-  gsk_sl_function_builtin_constructor_print,
-  gsk_sl_function_builtin_constructor_write_spv,
-};
-
-/* CONSTRUCTOR */
-
 typedef struct _GskSlFunctionConstructor GskSlFunctionConstructor;
 
 struct _GskSlFunctionConstructor {
@@ -461,18 +389,7 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_DECLARED = {
 GskSlFunction *
 gsk_sl_function_new_constructor (GskSlType *type)
 {
-  if (gsk_sl_type_is_scalar (type) ||
-      gsk_sl_type_is_vector (type) ||
-      gsk_sl_type_is_matrix (type))
-    {
-      GskSlFunctionBuiltinConstructor *constructor;
-
-      constructor = gsk_sl_function_new (GskSlFunctionBuiltinConstructor, 
&GSK_SL_FUNCTION_BUILTIN_CONSTRUCTOR);
-      constructor->type = gsk_sl_type_ref (type);
-
-      return &constructor->parent;
-    }
-  else if (gsk_sl_type_is_struct (type))
+  if (gsk_sl_type_is_struct (type))
     {
       GskSlFunctionConstructor *constructor;
 
@@ -633,12 +550,6 @@ gsk_sl_function_unref (GskSlFunction *function)
   function->class->free (function);
 }
 
-gboolean
-gsk_sl_function_is_builtin_constructor (const GskSlFunction *function)
-{
-  return function->class == &GSK_SL_FUNCTION_BUILTIN_CONSTRUCTOR;
-}
-
 GskSlType *
 gsk_sl_function_get_return_type (const GskSlFunction *function)
 {
diff --git a/gsk/gskslfunctionprivate.h b/gsk/gskslfunctionprivate.h
index 1d5cbd3..321d195 100644
--- a/gsk/gskslfunctionprivate.h
+++ b/gsk/gskslfunctionprivate.h
@@ -35,8 +35,6 @@ GskSlFunction *         gsk_sl_function_new_parse               (GskSlScope
 GskSlFunction *         gsk_sl_function_ref                     (GskSlFunction          *function);
 void                    gsk_sl_function_unref                   (GskSlFunction          *function);
 
-gboolean                gsk_sl_function_is_builtin_constructor  (const GskSlFunction    *function);
-
 void                    gsk_sl_function_print                   (const GskSlFunction    *function,
                                                                  GskSlPrinter           *printer);
 
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index 85687da..7ae7cf6 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -757,23 +757,24 @@ its_a_type:
         if (token->type == GSK_SL_TOKEN_LEFT_PAREN)
           {
             GskSlStatementExpression *statement_expression;
-            GskSlFunction *constructor;
                 
-            constructor = gsk_sl_function_new_constructor (type);
             statement_expression = gsk_sl_statement_new (GskSlStatementExpression, 
&GSK_SL_STATEMENT_EXPRESSION);
-            if (gsk_sl_function_is_builtin_constructor (constructor))
+            if (gsk_sl_type_is_scalar (type) || gsk_sl_type_is_vector (type) || gsk_sl_type_is_matrix (type))
               {
-                statement_expression->expression = gsk_sl_expression_parse_function_call (scope, preproc, 
NULL, constructor);
+                statement_expression->expression = gsk_sl_expression_parse_constructor (scope, preproc, 
type);
               }
             else
               {
+                GskSlFunction *constructor;
                 GskSlFunctionMatcher matcher;
+
+                constructor = gsk_sl_function_new_constructor (type);
                 gsk_sl_function_matcher_init (&matcher, g_list_prepend (NULL, constructor));
-                statement_expression->expression = gsk_sl_expression_parse_function_call (scope, preproc, 
&matcher, constructor);
+                statement_expression->expression = gsk_sl_expression_parse_function_call (scope, preproc, 
&matcher);
                 gsk_sl_function_matcher_finish (&matcher);
+                gsk_sl_function_unref (constructor);
               }
             statement = (GskSlStatement *) statement_expression;
-            gsk_sl_function_unref (constructor);
           }
         else
           {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]