summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-10-26 04:43:52 +0200
committerBenjamin Otte <otte@redhat.com>2017-10-30 02:58:03 +0100
commit73ec3734bd8facdfbfff7224e01af6f9c30ae0c9 (patch)
treecb076ef66e701ec7d0230d6676d446a89b5bdc95
parent39a277260f48fc8b1f3eb665e8b9c5a69095b634 (diff)
downloadgtk+-73ec3734bd8facdfbfff7224e01af6f9c30ae0c9.tar.gz
gskslstatement: Implement break
-rw-r--r--gsk/gskslstatement.c67
-rw-r--r--testsuite/gsksl/errors/break-without-loop-or-switch.glsl5
2 files changed, 72 insertions, 0 deletions
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index e1d26b4e0e..a9fd8d7e68 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 0000000000..e34f7e62e3
--- /dev/null
+++ b/testsuite/gsksl/errors/break-without-loop-or-switch.glsl
@@ -0,0 +1,5 @@
+void
+main ()
+{
+ break;
+}