summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-10-08 05:33:46 +0200
committerBenjamin Otte <otte@redhat.com>2017-10-30 02:58:03 +0100
commit115182d6e64bfa08a509f9e9fef66f63504e6228 (patch)
tree77c0f7dcecdb6de0531688eb84dd5d0073f122f3
parent41a0ce46216603b5718a6b120c4956f43fc4a50a (diff)
downloadgtk+-115182d6e64bfa08a509f9e9fef66f63504e6228.tar.gz
gskslexpression: Convert assignment expression to GskSlBinary
This also tightens the checks we do. So the code will now properly error out if you try to assign an int to a matrix or try to &= with a float.
-rw-r--r--gsk/gskslexpression.c97
1 files changed, 44 insertions, 53 deletions
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 28e7346a39..3af2a754d7 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -74,7 +74,7 @@ typedef struct _GskSlExpressionAssignment GskSlExpressionAssignment;
struct _GskSlExpressionAssignment {
GskSlExpression parent;
- GskSlTokenType op;
+ const GskSlBinary *binary;
GskSlExpression *lvalue;
GskSlExpression *rvalue;
};
@@ -85,8 +85,7 @@ gsk_sl_expression_assignment_free (GskSlExpression *expression)
GskSlExpressionAssignment *assignment = (GskSlExpressionAssignment *) expression;
gsk_sl_expression_unref (assignment->lvalue);
- if (assignment->rvalue)
- gsk_sl_expression_unref (assignment->rvalue);
+ gsk_sl_expression_unref (assignment->rvalue);
g_slice_free (GskSlExpressionAssignment, assignment);
}
@@ -98,46 +97,10 @@ gsk_sl_expression_assignment_print (const GskSlExpression *expression,
const GskSlExpressionAssignment *assignment = (const GskSlExpressionAssignment *) expression;
gsk_sl_expression_print (assignment->lvalue, printer);
-
- switch ((guint) assignment->op)
- {
- case GSK_SL_TOKEN_EQUAL:
- gsk_sl_printer_append (printer, " = ");
- break;
- case GSK_SL_TOKEN_MUL_ASSIGN:
- gsk_sl_printer_append (printer, " *= ");
- break;
- case GSK_SL_TOKEN_DIV_ASSIGN:
- gsk_sl_printer_append (printer, " /= ");
- break;
- case GSK_SL_TOKEN_MOD_ASSIGN:
- gsk_sl_printer_append (printer, " %= ");
- break;
- case GSK_SL_TOKEN_ADD_ASSIGN:
- gsk_sl_printer_append (printer, " += ");
- break;
- case GSK_SL_TOKEN_SUB_ASSIGN:
- gsk_sl_printer_append (printer, " -= ");
- break;
- case GSK_SL_TOKEN_LEFT_ASSIGN:
- gsk_sl_printer_append (printer, " <<= ");
- break;
- case GSK_SL_TOKEN_RIGHT_ASSIGN:
- gsk_sl_printer_append (printer, " >>= ");
- break;
- case GSK_SL_TOKEN_AND_ASSIGN:
- gsk_sl_printer_append (printer, " &= ");
- break;
- case GSK_SL_TOKEN_XOR_ASSIGN:
- gsk_sl_printer_append (printer, " ^= ");
- break;
- case GSK_SL_TOKEN_OR_ASSIGN:
- gsk_sl_printer_append (printer, " |= ");
- break;
- default:
- g_assert_not_reached ();
- break;
- }
+ gsk_sl_printer_append (printer, " ");
+ if (assignment->binary)
+ gsk_sl_printer_append (printer, gsk_sl_binary_get_sign (assignment->binary));
+ gsk_sl_printer_append (printer, "= ");
gsk_sl_expression_print (assignment->rvalue, printer);
}
@@ -157,7 +120,7 @@ gsk_sl_expression_assignment_get_constant (const GskSlExpression *expression)
static guint32
gsk_sl_expression_assignment_write_spv (const GskSlExpression *expression,
- GskSpvWriter *writer)
+ GskSpvWriter *writer)
{
g_assert_not_reached ();
@@ -2361,15 +2324,17 @@ gsk_sl_expression_parse_constant (GskSlScope *scope,
GskSlExpression *
gsk_sl_expression_parse_assignment (GskSlScope *scope,
- GskSlPreprocessor *stream)
+ GskSlPreprocessor *preproc)
{
+ const GskSlBinary *binary;
const GskSlToken *token;
- GskSlExpression *lvalue;
+ GskSlExpression *lvalue, *rvalue;
GskSlExpressionAssignment *assign;
+ GskSlType *result_type;
- lvalue = gsk_sl_expression_parse_conditional (scope, stream);
+ lvalue = gsk_sl_expression_parse_conditional (scope, preproc);
- token = gsk_sl_preprocessor_get (stream);
+ token = gsk_sl_preprocessor_get (preproc);
switch ((guint) token->type)
{
case GSK_SL_TOKEN_EQUAL:
@@ -2402,13 +2367,39 @@ gsk_sl_expression_parse_assignment (GskSlScope *scope,
}
#endif
- assign = gsk_sl_expression_new (GskSlExpressionAssignment, &GSK_SL_EXPRESSION_ASSIGNMENT);
- assign->lvalue = lvalue;
- assign->op = token->type;
+ binary = gsk_sl_binary_get_for_token (token->type);
+ gsk_sl_preprocessor_consume (preproc, NULL);
- gsk_sl_preprocessor_consume (stream, (GskSlExpression *) assign);
+ rvalue = gsk_sl_expression_parse_assignment (scope, preproc);
+ if (binary)
+ {
+ result_type = gsk_sl_binary_check_type (binary,
+ preproc,
+ gsk_sl_expression_get_return_type (lvalue),
+ gsk_sl_expression_get_return_type (rvalue));
+ if (result_type == NULL)
+ {
+ gsk_sl_expression_unref (rvalue);
+ return lvalue;
+ }
+ }
+ else
+ {
+ result_type = gsk_sl_expression_get_return_type (rvalue);
+ }
+ if (!gsk_sl_type_can_convert (gsk_sl_expression_get_return_type (lvalue), result_type))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot assign value of type %s to variable of type %s",
+ gsk_sl_type_get_name (result_type),
+ gsk_sl_type_get_name (gsk_sl_expression_get_return_type (lvalue)));
+ gsk_sl_expression_unref (rvalue);
+ return lvalue;
+ }
- assign->rvalue = gsk_sl_expression_parse_assignment (scope, stream);
+ assign = gsk_sl_expression_new (GskSlExpressionAssignment, &GSK_SL_EXPRESSION_ASSIGNMENT);
+ assign->binary = binary;
+ assign->lvalue = lvalue;
+ assign->rvalue = rvalue;
return (GskSlExpression *) assign;
}