diff options
author | Benjamin Otte <otte@redhat.com> | 2017-10-26 04:43:52 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-10-30 02:58:03 +0100 |
commit | 73ec3734bd8facdfbfff7224e01af6f9c30ae0c9 (patch) | |
tree | cb076ef66e701ec7d0230d6676d446a89b5bdc95 | |
parent | 39a277260f48fc8b1f3eb665e8b9c5a69095b634 (diff) | |
download | gtk+-73ec3734bd8facdfbfff7224e01af6f9c30ae0c9.tar.gz |
gskslstatement: Implement break
-rw-r--r-- | gsk/gskslstatement.c | 67 | ||||
-rw-r--r-- | testsuite/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 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; +} |