[gtk+/wip/otte/shader: 4/9] gsksl: Parse assignments



commit bbb9046e56642fafea1b462a48173de54aa6338e
Author: Benjamin Otte <otte redhat com>
Date:   Sat Sep 16 19:53:50 2017 +0200

    gsksl: Parse assignments

 gsk/gskslnode.c |  133 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 120 insertions(+), 13 deletions(-)
---
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index 1305647..cef5bbf 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -135,6 +135,85 @@ static const GskSlNodeClass GSK_SL_NODE_FUNCTION = {
   gsk_sl_node_function_print
 };
 
+/* ASSIGNMENT */
+
+typedef struct _GskSlNodeAssignment GskSlNodeAssignment;
+
+struct _GskSlNodeAssignment {
+  GskSlNode parent;
+
+  GskSlTokenType op;
+  GskSlNode *lvalue;
+  GskSlNode *rvalue;
+};
+
+static void
+gsk_sl_node_assignment_free (GskSlNode *node)
+{
+  GskSlNodeAssignment *assignment = (GskSlNodeAssignment *) node;
+
+  gsk_sl_node_unref (assignment->lvalue);
+  if (assignment->rvalue)
+    gsk_sl_node_unref (assignment->rvalue);
+
+  g_slice_free (GskSlNodeAssignment, assignment);
+}
+
+static void
+gsk_sl_node_assignment_print (GskSlNode *node,
+                              GString   *string)
+{
+  GskSlNodeAssignment *assignment = (GskSlNodeAssignment *) node;
+
+  gsk_sl_node_print (assignment->lvalue, string);
+
+  switch (assignment->op)
+  {
+    case GSK_SL_TOKEN_EQUAL:
+      g_string_append (string, " = ");
+      break;
+    case GSK_SL_TOKEN_MUL_ASSIGN:
+      g_string_append (string, " *= ");
+      break;
+    case GSK_SL_TOKEN_DIV_ASSIGN:
+      g_string_append (string, " /= ");
+      break;
+    case GSK_SL_TOKEN_MOD_ASSIGN:
+      g_string_append (string, " %= ");
+      break;
+    case GSK_SL_TOKEN_ADD_ASSIGN:
+      g_string_append (string, " += ");
+      break;
+    case GSK_SL_TOKEN_SUB_ASSIGN:
+      g_string_append (string, " -= ");
+      break;
+    case GSK_SL_TOKEN_LEFT_ASSIGN:
+      g_string_append (string, " <<= ");
+      break;
+    case GSK_SL_TOKEN_RIGHT_ASSIGN:
+      g_string_append (string, " >>= ");
+      break;
+    case GSK_SL_TOKEN_AND_ASSIGN:
+      g_string_append (string, " &= ");
+      break;
+    case GSK_SL_TOKEN_XOR_ASSIGN:
+      g_string_append (string, " ^= ");
+      break;
+    case GSK_SL_TOKEN_OR_ASSIGN:
+      g_string_append (string, " |= ");
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+  gsk_sl_node_print (assignment->rvalue, string);
+}
+
+static const GskSlNodeClass GSK_SL_NODE_ASSIGNMENT = {
+  gsk_sl_node_assignment_free,
+  gsk_sl_node_assignment_print
+};
+
 /* CONSTANT */
 
 typedef struct _GskSlNodeConstant GskSlNodeConstant;
@@ -302,30 +381,58 @@ gsk_sl_node_parse_constant (GskSlNodeProgram *program,
 }
 
 static GskSlNode *
-gsk_sl_node_parse_expression (GskSlNodeProgram *program,
-                              GskSlTokenStream *stream)
+gsk_sl_node_parse_assignment_expression (GskSlNodeProgram *program,
+                                         GskSlTokenStream *stream)
 {
   const GskSlToken *token;
-  GskSlNode *node;
+  GskSlNode *lvalue;
+  GskSlNodeAssignment *assign;
+
+  lvalue = gsk_sl_node_parse_constant (program, stream);
+  if (lvalue == NULL)
+    return NULL;
 
   token = gsk_sl_token_stream_get (stream);
   switch (token->type)
   {
-      case GSK_SL_TOKEN_INTCONSTANT:
-      case GSK_SL_TOKEN_UINTCONSTANT:
-      case GSK_SL_TOKEN_FLOATCONSTANT:
-      case GSK_SL_TOKEN_BOOLCONSTANT:
-      case GSK_SL_TOKEN_DOUBLECONSTANT:
-        node = gsk_sl_node_parse_constant (program, stream);
+      case GSK_SL_TOKEN_EQUAL:
+      case GSK_SL_TOKEN_MUL_ASSIGN:
+      case GSK_SL_TOKEN_DIV_ASSIGN:
+      case GSK_SL_TOKEN_MOD_ASSIGN:
+      case GSK_SL_TOKEN_ADD_ASSIGN:
+      case GSK_SL_TOKEN_SUB_ASSIGN:
+      case GSK_SL_TOKEN_LEFT_ASSIGN:
+      case GSK_SL_TOKEN_RIGHT_ASSIGN:
+      case GSK_SL_TOKEN_AND_ASSIGN:
+      case GSK_SL_TOKEN_XOR_ASSIGN:
+      case GSK_SL_TOKEN_OR_ASSIGN:
         break;
 
-      case GSK_SL_TOKEN_LEFT_PAREN:
       default:
-        node = NULL;
-        break;
+        return lvalue;
   }
 
-  return node;
+  assign = gsk_sl_node_new (GskSlNodeAssignment, &GSK_SL_NODE_ASSIGNMENT);
+  assign->lvalue = lvalue;
+  assign->op = token->type;
+
+  gsk_sl_token_stream_consume (stream, (GskSlNode *) assign);
+  assign->rvalue = gsk_sl_node_parse_assignment_expression (program, stream);
+  if (assign->rvalue == NULL)
+    {
+      gsk_sl_node_unref ((GskSlNode *) assign);
+      return lvalue;
+    }
+
+  return (GskSlNode *) assign;
+}
+
+static GskSlNode *
+gsk_sl_node_parse_expression (GskSlNodeProgram *program,
+                              GskSlTokenStream *stream)
+{
+  /* XXX: Allow comma here */
+  return gsk_sl_node_parse_assignment_expression (program, stream);
 }
 
 static gboolean


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