[gtk+/wip/otte/shader: 146/151] gsksl: Add gsk_sl_expression_parse_integral_constant()



commit ea2d6573256d53bd5931bd010313ef505bb6895c
Author: Benjamin Otte <otte redhat com>
Date:   Sun Oct 22 01:45:33 2017 +0200

    gsksl: Add gsk_sl_expression_parse_integral_constant()
    
    This is for parsing constant expressions, like array indices or layout
    specifiers.

 gsk/gskslexpression.c        |   79 ++++++++++++++++++++++++++++++++++++++++++
 gsk/gskslexpressionprivate.h |    4 ++
 gsk/gskslqualifier.c         |   36 +------------------
 3 files changed, 84 insertions(+), 35 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 91ad58f..2172df3 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -2891,6 +2891,85 @@ gsk_sl_expression_parse_constant (GskSlScope        *scope,
   return gsk_sl_expression_parse_conditional (scope, stream);
 }
 
+gint
+gsk_sl_expression_parse_integral_constant (GskSlScope        *scope,
+                                           GskSlPreprocessor *preproc,
+                                           gint               minimum,
+                                           gint               maximum)
+{
+  GskSlExpression *expression;
+  GskSlValue *value;
+  GskSlType *type;
+
+  g_return_val_if_fail (minimum < maximum, minimum);
+
+  expression = gsk_sl_expression_parse_constant (scope, preproc);
+  value = gsk_sl_expression_get_constant (expression);
+  gsk_sl_expression_unref (expression);
+
+  if (value == NULL)
+    {
+      gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant.");
+      return minimum;
+    }
+
+  type = gsk_sl_value_get_type (value);
+  if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT)
+    {
+      gint32 i = *(gint32 *) gsk_sl_value_get_data (value);
+
+      if (i < minimum)
+        {
+          gsk_sl_preprocessor_error (preproc, CONSTANT,
+                                     "Constant expression evaluates to %d, but must be at least %d.",
+                                     i, minimum);
+          i = minimum;
+        }
+      else if (i > maximum)
+        {
+          gsk_sl_preprocessor_error (preproc, CONSTANT,
+                                     "Constant expression evaluates to %d, but must be at most %d.",
+                                     i, maximum);
+          i = maximum;
+        }
+
+      return i;
+    }
+  else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT)
+    {
+      guint32 u;
+      gint i;
+
+      u = *(guint32 *) gsk_sl_value_get_data (value);
+
+      if (minimum >= 0 && u < minimum)
+        {
+          gsk_sl_preprocessor_error (preproc, CONSTANT,
+                                     "Constant expression evaluates to %u, but must be at least %d.",
+                                     u, minimum);
+          i = minimum;
+        }
+      else if (maximum > 0 && u > maximum)
+        {
+          gsk_sl_preprocessor_error (preproc, CONSTANT,
+                                     "Constant expression evaluates to %u, but must be at most %d.",
+                                     u, maximum);
+          i = maximum;
+        }
+      else
+        {
+          i = u;
+        }
+
+      return i;
+    }
+  else
+    {
+      gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but 
%s", gsk_sl_type_get_name (type));
+      return minimum;
+    }
+}
+
 GskSlExpression *
 gsk_sl_expression_parse_assignment (GskSlScope        *scope,
                                     GskSlPreprocessor *preproc)
diff --git a/gsk/gskslexpressionprivate.h b/gsk/gskslexpressionprivate.h
index d9dc7a3..15ab40a 100644
--- a/gsk/gskslexpressionprivate.h
+++ b/gsk/gskslexpressionprivate.h
@@ -29,6 +29,10 @@ GskSlExpression *       gsk_sl_expression_parse_assignment      (GskSlScope
                                                                  GskSlPreprocessor      *stream);
 GskSlExpression *       gsk_sl_expression_parse_constant        (GskSlScope             *scope,
                                                                  GskSlPreprocessor      *stream);
+gint                    gsk_sl_expression_parse_integral_constant (GskSlScope           *scope,
+                                                                 GskSlPreprocessor      *preproc,
+                                                                 gint                    minimum,
+                                                                 gint                    maximum);
 GskSlExpression *       gsk_sl_expression_parse_constructor     (GskSlScope             *scope,
                                                                  GskSlPreprocessor      *stream,
                                                                  GskSlType              *type);
diff --git a/gsk/gskslqualifier.c b/gsk/gskslqualifier.c
index cf0bf89..60c3004 100644
--- a/gsk/gskslqualifier.c
+++ b/gsk/gskslqualifier.c
@@ -40,10 +40,7 @@ gsk_sl_qualifier_parse_layout_assignment (GskSlPreprocessor *preproc,
                                           GskSlScope        *scope,
                                           int               *target)
 {
-  GskSlExpression *expression;
   const GskSlToken *token;
-  GskSlValue *value;
-  GskSlType *type;
 
   gsk_sl_preprocessor_consume (preproc, NULL);
   
@@ -55,38 +52,7 @@ gsk_sl_qualifier_parse_layout_assignment (GskSlPreprocessor *preproc,
     }
   gsk_sl_preprocessor_consume (preproc, NULL);
 
-  expression = gsk_sl_expression_parse_constant (scope, preproc);
-  if (expression == NULL)
-    return;
-
-  value = gsk_sl_expression_get_constant (expression);
-  gsk_sl_expression_unref (expression);
-
-  if (value == NULL)
-    {
-      gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant.");
-      return;
-    }
-
-  type = gsk_sl_value_get_type (value);
-  if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT)
-    {
-      gint32 i = *(gint32 *) gsk_sl_value_get_data (value);
-
-      if (i < 0)
-        gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression may not be negative.");
-      else
-        *target = i;
-    }
-  else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT)
-    {
-      *target = *(guint32 *) gsk_sl_value_get_data (value);
-    }
-  else
-    {
-      gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but 
%s", gsk_sl_type_get_name (type));
-    }
-  gsk_sl_value_free (value);
+  *target = gsk_sl_expression_parse_integral_constant (scope, preproc, 0, G_MAXINT);
 }
 
 static void


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