[gtk+/wip/otte/shader: 301/367] gskslnode: Add gsk_sl_node_is_constant()



commit d91cf86335dd586b5b17be6145c067298112831b
Author: Benjamin Otte <otte redhat com>
Date:   Sat Sep 16 21:50:42 2017 +0200

    gskslnode: Add gsk_sl_node_is_constant()
    
    And use it to emit a compile error when trying to assign to a constant
    value.

 gsk/gskslnode.c        |   56 ++++++++++++++++++++++++++++++++++++++++++++---
 gsk/gskslnodeprivate.h |    2 +
 2 files changed, 54 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index 89f2176..9be0574 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -83,10 +83,17 @@ gsk_sl_node_program_get_return_type (GskSlNode *node)
   return NULL;
 }
 
+static gboolean
+gsk_sl_node_program_is_constant (GskSlNode *node)
+{
+  return TRUE;
+}
+
 static const GskSlNodeClass GSK_SL_NODE_PROGRAM = {
   gsk_sl_node_program_free,
   gsk_sl_node_program_print,
-  gsk_sl_node_program_get_return_type
+  gsk_sl_node_program_get_return_type,
+  gsk_sl_node_program_is_constant
 };
 
 /* FUNCTION */
@@ -146,10 +153,17 @@ gsk_sl_node_function_get_return_type (GskSlNode *node)
   return function->return_type;
 }
 
+static gboolean
+gsk_sl_node_function_is_constant (GskSlNode *node)
+{
+  return TRUE;
+}
+
 static const GskSlNodeClass GSK_SL_NODE_FUNCTION = {
   gsk_sl_node_function_free,
   gsk_sl_node_function_print,
-  gsk_sl_node_function_get_return_type
+  gsk_sl_node_function_get_return_type,
+  gsk_sl_node_function_is_constant
 };
 
 /* ASSIGNMENT */
@@ -234,10 +248,19 @@ gsk_sl_node_assignment_get_return_type (GskSlNode *node)
   return gsk_sl_node_get_return_type (assignment->lvalue);
 }
 
+static gboolean
+gsk_sl_node_assignment_is_constant (GskSlNode *node)
+{
+  GskSlNodeAssignment *assignment = (GskSlNodeAssignment *) node;
+
+  return gsk_sl_node_get_return_type (assignment->rvalue);
+}
+
 static const GskSlNodeClass GSK_SL_NODE_ASSIGNMENT = {
   gsk_sl_node_assignment_free,
   gsk_sl_node_assignment_print,
-  gsk_sl_node_assignment_get_return_type
+  gsk_sl_node_assignment_get_return_type,
+  gsk_sl_node_assignment_is_constant
 };
 
 /* CONSTANT */
@@ -315,10 +338,17 @@ gsk_sl_node_constant_get_return_type (GskSlNode *node)
   return gsk_sl_type_get_builtin (constant->type);
 }
 
+static gboolean
+gsk_sl_node_constant_is_constant (GskSlNode *node)
+{
+  return TRUE;
+}
+
 static const GskSlNodeClass GSK_SL_NODE_CONSTANT = {
   gsk_sl_node_constant_free,
   gsk_sl_node_constant_print,
-  gsk_sl_node_constant_get_return_type
+  gsk_sl_node_constant_get_return_type,
+  gsk_sl_node_constant_is_constant
 };
 
 /* API */
@@ -447,11 +477,23 @@ gsk_sl_node_parse_assignment_expression (GskSlNodeProgram  *program,
         return lvalue;
   }
 
+  if (gsk_sl_node_is_constant (lvalue))
+    {
+      gsk_sl_preprocessor_error (stream, "Cannot assign to a constant lvalue.");
+
+      /* Continue parsing like normal here to get more errors */
+      gsk_sl_preprocessor_consume (stream, lvalue);
+      gsk_sl_node_unref (lvalue);
+
+      return gsk_sl_node_parse_assignment_expression (program, stream);
+    }
+
   assign = gsk_sl_node_new (GskSlNodeAssignment, &GSK_SL_NODE_ASSIGNMENT);
   assign->lvalue = lvalue;
   assign->op = token->type;
 
   gsk_sl_preprocessor_consume (stream, (GskSlNode *) assign);
+
   assign->rvalue = gsk_sl_node_parse_assignment_expression (program, stream);
   if (assign->rvalue == NULL)
     {
@@ -617,3 +659,9 @@ gsk_sl_node_get_return_type (GskSlNode *node)
 {
   return node->class->get_return_type (node);
 }
+
+gboolean
+gsk_sl_node_is_constant (GskSlNode *node)
+{
+  return node->class->is_constant (node);
+}
diff --git a/gsk/gskslnodeprivate.h b/gsk/gskslnodeprivate.h
index e5020bf..e41b3a2 100644
--- a/gsk/gskslnodeprivate.h
+++ b/gsk/gskslnodeprivate.h
@@ -38,6 +38,7 @@ struct _GskSlNodeClass {
   void                  (* print)                               (GskSlNode           *node,
                                                                  GString             *string);
   GskSlType *           (* get_return_type)                     (GskSlNode           *node);
+  gboolean              (* is_constant)                         (GskSlNode           *node);
 };
 
 GskSlNode *             gsk_sl_node_new_program                 (GBytes              *source,
@@ -49,6 +50,7 @@ void                    gsk_sl_node_unref                       (GskSlNode
 void                    gsk_sl_node_print                       (GskSlNode           *node,
                                                                  GString             *string);
 GskSlType *             gsk_sl_node_get_return_type             (GskSlNode           *node);
+gboolean                gsk_sl_node_is_constant                 (GskSlNode           *node);
 
 G_END_DECLS
 


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