diff options
author | Benjamin Otte <otte@redhat.com> | 2017-10-22 01:45:33 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-10-30 02:58:03 +0100 |
commit | 7e9aa97fd5581639ea13fdbb2b6f196359406e9d (patch) | |
tree | 70ca5561a66080d967d93a455deac46bff31dfd8 | |
parent | 38bc5f3d37e2caaf1b95bcc198a231adb42012d8 (diff) | |
download | gtk+-7e9aa97fd5581639ea13fdbb2b6f196359406e9d.tar.gz |
gsksl: Add gsk_sl_expression_parse_integral_constant()
This is for parsing constant expressions, like array indices or layout
specifiers.
-rw-r--r-- | gsk/gskslexpression.c | 74 | ||||
-rw-r--r-- | gsk/gskslexpressionprivate.h | 4 | ||||
-rw-r--r-- | gsk/gskslqualifier.c | 36 |
3 files changed, 79 insertions, 35 deletions
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c index 21cb1d1cc9..5b2c7bb5a4 100644 --- a/gsk/gskslexpression.c +++ b/gsk/gskslexpression.c @@ -2890,6 +2890,80 @@ gsk_sl_expression_parse_constant (GskSlScope *scope, return gsk_sl_expression_parse_conditional (scope, stream); } +gint32 +gsk_sl_expression_parse_integral_constant (GskSlScope *scope, + GskSlPreprocessor *preproc, + gint32 minimum, + guint32 maximum) +{ + GskSlExpression *expression; + GskSlValue *value; + GskSlType *type; + + g_return_val_if_fail (minimum < maximum, minimum); + + expression = gsk_sl_expression_parse_constant (scope, preproc); + value = gsk_sl_expression_get_constant (expression); + gsk_sl_expression_unref (expression); + + if (value == NULL) + { + gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant."); + return minimum; + } + + type = gsk_sl_value_get_type (value); + if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT) + { + gint32 i = *(gint32 *) gsk_sl_value_get_data (value); + + if (i < minimum) + { + gsk_sl_preprocessor_error (preproc, CONSTANT, + "Constant expression evaluates to %d, but must be at least %d.", + i, minimum); + i = minimum; + } + else if (i > 0 && i > maximum) + { + gsk_sl_preprocessor_error (preproc, CONSTANT, + "Constant expression evaluates to %d, but must be at most %d.", + i, maximum); + i = maximum; + } + + return i; + } + else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT) + { + guint32 u; + + u = *(guint32 *) gsk_sl_value_get_data (value); + + if (minimum >= 0 && u < minimum) + { + gsk_sl_preprocessor_error (preproc, CONSTANT, + "Constant expression evaluates to %u, but must be at least %d.", + u, minimum); + u = minimum; + } + else if (u > maximum) + { + gsk_sl_preprocessor_error (preproc, CONSTANT, + "Constant expression evaluates to %u, but must be at most %d.", + u, maximum); + u = maximum; + } + + return u; + } + else + { + gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but %s", gsk_sl_type_get_name (type)); + return minimum; + } +} + GskSlExpression * gsk_sl_expression_parse_assignment (GskSlScope *scope, GskSlPreprocessor *preproc) diff --git a/gsk/gskslexpressionprivate.h b/gsk/gskslexpressionprivate.h index d9dc7a3a2d..080e5995bb 100644 --- a/gsk/gskslexpressionprivate.h +++ b/gsk/gskslexpressionprivate.h @@ -29,6 +29,10 @@ GskSlExpression * gsk_sl_expression_parse_assignment (GskSlScope GskSlPreprocessor *stream); GskSlExpression * gsk_sl_expression_parse_constant (GskSlScope *scope, GskSlPreprocessor *stream); +gint32 gsk_sl_expression_parse_integral_constant (GskSlScope *scope, + GskSlPreprocessor *preproc, + gint32 minimum, + guint32 maximum); GskSlExpression * gsk_sl_expression_parse_constructor (GskSlScope *scope, GskSlPreprocessor *stream, GskSlType *type); diff --git a/gsk/gskslqualifier.c b/gsk/gskslqualifier.c index cf0bf89d63..60c3004308 100644 --- a/gsk/gskslqualifier.c +++ b/gsk/gskslqualifier.c @@ -40,10 +40,7 @@ gsk_sl_qualifier_parse_layout_assignment (GskSlPreprocessor *preproc, GskSlScope *scope, int *target) { - GskSlExpression *expression; const GskSlToken *token; - GskSlValue *value; - GskSlType *type; gsk_sl_preprocessor_consume (preproc, NULL); @@ -55,38 +52,7 @@ gsk_sl_qualifier_parse_layout_assignment (GskSlPreprocessor *preproc, } gsk_sl_preprocessor_consume (preproc, NULL); - expression = gsk_sl_expression_parse_constant (scope, preproc); - if (expression == NULL) - return; - - value = gsk_sl_expression_get_constant (expression); - gsk_sl_expression_unref (expression); - - if (value == NULL) - { - gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant."); - return; - } - - type = gsk_sl_value_get_type (value); - if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT) - { - gint32 i = *(gint32 *) gsk_sl_value_get_data (value); - - if (i < 0) - gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression may not be negative."); - else - *target = i; - } - else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT) - { - *target = *(guint32 *) gsk_sl_value_get_data (value); - } - else - { - gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but %s", gsk_sl_type_get_name (type)); - } - gsk_sl_value_free (value); + *target = gsk_sl_expression_parse_integral_constant (scope, preproc, 0, G_MAXINT); } static void |