[gtk+/wip/otte/shader: 99/101] gskslstatement: Implement break



commit 22cf0158746fa21b60de6983021caa6f784e6d31
Author: Benjamin Otte <otte redhat com>
Date:   Thu Oct 26 04:43:52 2017 +0200

    gskslstatement: Implement break

 gsk/gskslstatement.c                               |   67 ++++++++++++++++++++
 .../gsksl/errors/break-without-loop-or-switch.glsl |    5 ++
 2 files changed, 72 insertions(+), 0 deletions(-)
---
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index e1d26b4..a9fd8d7 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -339,6 +339,57 @@ static const GskSlStatementClass GSK_SL_STATEMENT_RETURN = {
   gsk_sl_statement_return_write_spv
 };
 
+/* BREAK */
+
+typedef struct _GskSlStatementBreak GskSlStatementBreak;
+
+struct _GskSlStatementBreak {
+  GskSlStatement parent;
+};
+
+static void
+gsk_sl_statement_break_free (GskSlStatement *statement)
+{
+  GskSlStatementBreak *break_statement = (GskSlStatementBreak *) statement;
+
+  g_slice_free (GskSlStatementBreak, break_statement);
+}
+
+static void
+gsk_sl_statement_break_print (const GskSlStatement *statement,
+                               GskSlPrinter         *printer)
+{
+  gsk_sl_printer_append (printer, "break");
+  gsk_sl_printer_append (printer, ";");
+}
+
+static GskSlJump
+gsk_sl_statement_break_get_jump (const GskSlStatement *statement)
+{
+  return GSK_SL_JUMP_BREAK;
+}
+
+static gboolean
+gsk_sl_statement_break_write_spv (const GskSlStatement *statement,
+                                  GskSpvWriter         *writer)
+{
+  guint32 break_id;
+
+  break_id = gsk_spv_writer_get_break_id (writer);
+  g_assert (break_id != 0);
+
+  gsk_spv_writer_branch (writer, break_id);
+
+  return TRUE;
+}
+
+static const GskSlStatementClass GSK_SL_STATEMENT_BREAK = {
+  gsk_sl_statement_break_free,
+  gsk_sl_statement_break_print,
+  gsk_sl_statement_break_get_jump,
+  gsk_sl_statement_break_write_spv
+};
+
 /* DISCARD */
 
 typedef struct _GskSlStatementDiscard GskSlStatementDiscard;
@@ -1116,6 +1167,22 @@ its_a_type:
       }
       break;
 
+    case GSK_SL_TOKEN_BREAK:
+      if (!parse_everything)
+        goto only_expression_and_declaration;
+
+      if (gsk_sl_scope_can_break (scope))
+        {
+          statement = (GskSlStatement *) gsk_sl_statement_new (GskSlStatementBreak, &GSK_SL_STATEMENT_BREAK);
+        }
+      else
+        {
+          gsk_sl_preprocessor_error (preproc, SYNTAX, "\"break\" not allowed here.");
+          statement = gsk_sl_statement_new_error ();
+        }
+      gsk_sl_preprocessor_consume (preproc, statement);
+      break;
+
     case GSK_SL_TOKEN_DISCARD:
       if (!parse_everything)
         goto only_expression_and_declaration;
diff --git a/testsuite/gsksl/errors/break-without-loop-or-switch.glsl 
b/testsuite/gsksl/errors/break-without-loop-or-switch.glsl
new file mode 100644
index 0000000..e34f7e6
--- /dev/null
+++ b/testsuite/gsksl/errors/break-without-loop-or-switch.glsl
@@ -0,0 +1,5 @@
+void
+main ()
+{
+  break;
+}


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