[gtk+/wip/otte/shader: 1/14] gsksl: Start parsing statements by parsing constants



commit bcab22e7a93e49ba5c2fadfb36c3a955bacb4ab5
Author: Benjamin Otte <otte redhat com>
Date:   Sat Sep 16 15:21:43 2017 +0200

    gsksl: Start parsing statements by parsing constants

 gsk/gskslnode.c |  200 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 193 insertions(+), 7 deletions(-)
---
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index 01d1588..434d885 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -90,6 +90,7 @@ struct _GskSlNodeFunction {
 
   GskSlType *return_type;
   char *name;
+  GSList *statements;
 };
 
 static void
@@ -100,6 +101,7 @@ gsk_sl_node_function_free (GskSlNode *node)
   if (function->return_type)
     gsk_sl_type_unref (function->return_type);
   g_free (function->name);
+  g_slist_free_full (function->statements, (GDestroyNotify) gsk_sl_node_unref);
 
   g_slice_free (GskSlNodeFunction, function);
 }
@@ -109,6 +111,7 @@ gsk_sl_node_function_print (GskSlNode *node,
                             GString   *string)
 {
   GskSlNodeFunction *function = (GskSlNodeFunction *) node;
+  GSList *l;
 
   gsk_sl_type_print (function->return_type, string);
   g_string_append (string, "\n");
@@ -118,6 +121,12 @@ gsk_sl_node_function_print (GskSlNode *node,
   g_string_append (string, ")\n");
 
   g_string_append (string, "{\n");
+  for (l = function->statements; l; l = l->next)
+    {
+      g_string_append (string, "  ");
+      gsk_sl_node_print (l->data, string);
+      g_string_append (string, ";\n");
+    }
   g_string_append (string, "}\n");
 }
 
@@ -126,6 +135,78 @@ static const GskSlNodeClass GSK_SL_NODE_FUNCTION = {
   gsk_sl_node_function_print
 };
 
+/* CONSTANT */
+
+typedef struct _GskSlNodeConstant GskSlNodeConstant;
+
+struct _GskSlNodeConstant {
+  GskSlNode parent;
+
+  GskSlBuiltinType type;
+  union {
+    gint32       i32;
+    guint32      u32;
+    float        f;
+    double       d;
+    gboolean     b;
+  };
+};
+
+static void
+gsk_sl_node_constant_free (GskSlNode *node)
+{
+  GskSlNodeConstant *constant = (GskSlNodeConstant *) node;
+
+  g_slice_free (GskSlNodeConstant, constant);
+}
+
+static void
+gsk_sl_node_constant_print (GskSlNode *node,
+                            GString   *string)
+{
+  GskSlNodeConstant *constant = (GskSlNodeConstant *) node;
+  char buf[G_ASCII_DTOSTR_BUF_SIZE];
+
+  switch (constant->type)
+  {
+    case GSK_SL_FLOAT:
+      g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, constant->f);
+      g_string_append (string, buf);
+      if (strchr (buf, '.') == NULL)
+        g_string_append (string, ".0");
+      break;
+
+    case GSK_SL_DOUBLE:
+      g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, constant->d);
+      g_string_append (string, buf);
+      if (strchr (buf, '.') == NULL)
+        g_string_append (string, ".0");
+      g_string_append (string, "lf");
+      break;
+
+    case GSK_SL_INT:
+      g_string_append_printf (string, "%i", (gint) constant->i32);
+      break;
+
+    case GSK_SL_UINT:
+      g_string_append_printf (string, "%uu", (guint) constant->u32);
+      break;
+
+    case GSK_SL_BOOL:
+      g_string_append (string, constant->b ? "true" : "false");
+      break;
+
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+}
+
+static const GskSlNodeClass GSK_SL_NODE_CONSTANT = {
+  gsk_sl_node_constant_free,
+  gsk_sl_node_constant_print
+};
+
 /* API */
 
 static GskSlNodeFunction *
@@ -174,12 +255,87 @@ gsk_sl_node_parse_function_prototype (GskSlNodeProgram *program,
   return function;
 }
 
+static GskSlNode *
+gsk_sl_node_parse_constant (GskSlNodeProgram *program,
+                            GskSlTokenStream *stream)
+{
+  GskSlNodeConstant *constant;
+  const GskSlToken *token;
+
+  constant = gsk_sl_node_new (GskSlNodeConstant, &GSK_SL_NODE_CONSTANT);
+
+  token = gsk_sl_token_stream_get (stream);
+  switch (token->type)
+  {
+    case GSK_SL_TOKEN_INTCONSTANT:
+      constant->type = GSK_SL_INT;
+      constant->i32 = token->i32;
+      break;
+
+    case GSK_SL_TOKEN_UINTCONSTANT:
+      constant->type = GSK_SL_UINT;
+      constant->u32 = token->u32;
+      break;
+
+    case GSK_SL_TOKEN_FLOATCONSTANT:
+      constant->type = GSK_SL_FLOAT;
+      constant->f = token->f;
+      break;
+
+    case GSK_SL_TOKEN_BOOLCONSTANT:
+      constant->type = GSK_SL_BOOL;
+      constant->b = token->b;
+      break;
+
+    case GSK_SL_TOKEN_DOUBLECONSTANT:
+      constant->type = GSK_SL_DOUBLE;
+      constant->d = token->d;
+      break;
+
+    default:
+      g_assert_not_reached ();
+      return NULL;
+  }
+  gsk_sl_token_stream_consume (stream, (GskSlNode *) constant);
+
+  return (GskSlNode *) constant;
+}
+
+static GskSlNode *
+gsk_sl_node_parse_expression (GskSlNodeProgram *program,
+                              GskSlTokenStream *stream)
+{
+  const GskSlToken *token;
+  GskSlNode *node;
+
+  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);
+        break;
+
+      case GSK_SL_TOKEN_LEFT_PAREN:
+      default:
+        node = NULL;
+        break;
+  }
+
+  return node;
+}
+
 static gboolean
 gsk_sl_node_parse_function_definition (GskSlNodeProgram *program,
                                        GskSlTokenStream *stream)
 {
   GskSlNodeFunction *function;
   const GskSlToken *token;
+  GskSlNode *node;
+  gboolean result = TRUE;
 
   function = gsk_sl_node_parse_function_prototype (program, stream);
   if (function == NULL)
@@ -201,18 +357,48 @@ gsk_sl_node_parse_function_definition (GskSlNodeProgram *program,
     }
   gsk_sl_token_stream_consume (stream, (GskSlNode *) function);
 
-  token = gsk_sl_token_stream_get (stream);
-  if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE))
+  while (TRUE)
     {
-      gsk_sl_token_stream_error (stream, "Expected a closing \"}\"");
-      gsk_sl_node_unref ((GskSlNode *) function);
-      return NULL;
+      token = gsk_sl_token_stream_get (stream);
+      switch (token->type)
+      {
+      case GSK_SL_TOKEN_SEMICOLON:
+        gsk_sl_token_stream_consume (stream, (GskSlNode *) function);
+        break;
+
+      case GSK_SL_TOKEN_EOF:
+        gsk_sl_token_stream_error (stream, "Unexpected end of function, expected \"}\"");
+        goto out;
+
+      case GSK_SL_TOKEN_RIGHT_BRACE:
+        goto out;
+
+      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:
+      case GSK_SL_TOKEN_LEFT_PAREN:
+        node = gsk_sl_node_parse_expression (program, stream);
+        if (node)
+          function->statements = g_slist_append (function->statements, node);
+        else
+          result = FALSE;
+        break;
+
+      default:
+        gsk_sl_token_stream_error (stream, "Unexpected token in stream.");
+        gsk_sl_token_stream_consume (stream, (GskSlNode *) function);
+        result = FALSE;
+        break;
+      }
     }
+
+out:
   gsk_sl_token_stream_consume (stream, (GskSlNode *) function);
 
   program->functions = g_slist_prepend (program->functions, function);
-
-  return TRUE;
+  return result;
 }
 
 static gboolean


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