diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c index 9dc35e925c..497de04907 100644 --- a/gsk/gskslexpression.c +++ b/gsk/gskslexpression.c @@ -46,7 +46,7 @@ struct _GskSlExpressionClass { void (* print) (const GskSlExpression *expression, GString *string); GskSlType * (* get_return_type) (const GskSlExpression *expression); - gboolean (* is_constant) (const GskSlExpression *expression); + GskSlValue * (* get_constant) (const GskSlExpression *expression); guint32 (* write_spv) (const GskSlExpression *expression, GskSpvWriter *writer); }; @@ -148,10 +148,10 @@ gsk_sl_expression_assignment_get_return_type (const GskSlExpression *expression) return gsk_sl_expression_get_return_type (assignment->lvalue); } -static gboolean -gsk_sl_expression_assignment_is_constant (const GskSlExpression *expression) +static GskSlValue * +gsk_sl_expression_assignment_get_constant (const GskSlExpression *expression) { - return FALSE; + return NULL; } static guint32 @@ -167,7 +167,7 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_ASSIGNMENT = { gsk_sl_expression_assignment_free, gsk_sl_expression_assignment_print, gsk_sl_expression_assignment_get_return_type, - gsk_sl_expression_assignment_is_constant, + gsk_sl_expression_assignment_get_constant, gsk_sl_expression_assignment_write_spv }; @@ -596,13 +596,13 @@ gsk_sl_expression_operation_get_return_type (const GskSlExpression *expression) } } -static gboolean -gsk_sl_expression_operation_is_constant (const GskSlExpression *expression) +static GskSlValue * +gsk_sl_expression_operation_get_constant (const GskSlExpression *expression) { - const GskSlExpressionOperation *operation = (const GskSlExpressionOperation *) expression; + //const GskSlExpressionOperation *operation = (const GskSlExpressionOperation *) expression; - return gsk_sl_expression_is_constant (operation->left) - && gsk_sl_expression_is_constant (operation->right); + /* FIXME: These need constant evaluations */ + return NULL; } static guint32 @@ -618,7 +618,7 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_OPERATION = { gsk_sl_expression_operation_free, gsk_sl_expression_operation_print, gsk_sl_expression_operation_get_return_type, - gsk_sl_expression_operation_is_constant, + gsk_sl_expression_operation_get_constant, gsk_sl_expression_operation_write_spv }; @@ -659,10 +659,11 @@ gsk_sl_expression_reference_get_return_type (const GskSlExpression *expression) return gsk_sl_pointer_type_get_type (gsk_sl_variable_get_type (reference->variable)); } -static gboolean -gsk_sl_expression_reference_is_constant (const GskSlExpression *expression) +static GskSlValue * +gsk_sl_expression_reference_get_constant (const GskSlExpression *expression) { - return FALSE; + /* FIXME: values for constant variables need to be returned here */ + return NULL; } static guint32 @@ -689,7 +690,7 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_REFERENCE = { gsk_sl_expression_reference_free, gsk_sl_expression_reference_print, gsk_sl_expression_reference_get_return_type, - gsk_sl_expression_reference_is_constant, + gsk_sl_expression_reference_get_constant, gsk_sl_expression_reference_write_spv }; @@ -750,10 +751,11 @@ gsk_sl_expression_function_call_get_return_type (const GskSlExpression *expressi return gsk_sl_function_get_return_type (function_call->function); } -static gboolean -gsk_sl_expression_function_call_is_constant (const GskSlExpression *expression) +static GskSlValue * +gsk_sl_expression_function_call_get_constant (const GskSlExpression *expression) { - return FALSE; + /* FIXME: some functions are constant */ + return NULL; } static guint32 @@ -769,7 +771,7 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_FUNCTION_CALL = { gsk_sl_expression_function_call_free, gsk_sl_expression_function_call_print, gsk_sl_expression_function_call_get_return_type, - gsk_sl_expression_function_call_is_constant, + gsk_sl_expression_function_call_get_constant, gsk_sl_expression_function_call_write_spv }; @@ -808,10 +810,12 @@ gsk_sl_expression_constant_get_return_type (const GskSlExpression *expression) return gsk_sl_value_get_type (constant->value); } -static gboolean -gsk_sl_expression_constant_is_constant (const GskSlExpression *expression) +static GskSlValue * +gsk_sl_expression_constant_get_constant (const GskSlExpression *expression) { - return TRUE; + const GskSlExpressionConstant *constant = (const GskSlExpressionConstant *) expression; + + return gsk_sl_value_copy (constant->value); } static guint32 @@ -827,7 +831,7 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_CONSTANT = { gsk_sl_expression_constant_free, gsk_sl_expression_constant_print, gsk_sl_expression_constant_get_return_type, - gsk_sl_expression_constant_is_constant, + gsk_sl_expression_constant_get_constant, gsk_sl_expression_constant_write_spv }; @@ -1601,6 +1605,13 @@ gsk_sl_expression_parse_conditional (GskSlScope *scope, return gsk_sl_expression_parse_logical_or (scope, stream); } +GskSlExpression * +gsk_sl_expression_parse_constant (GskSlScope *scope, + GskSlPreprocessor *stream) +{ + return gsk_sl_expression_parse_conditional (scope, stream); +} + GskSlExpression * gsk_sl_expression_parse_assignment (GskSlScope *scope, GskSlPreprocessor *stream) @@ -1633,6 +1644,7 @@ gsk_sl_expression_parse_assignment (GskSlScope *scope, return lvalue; } +#if 0 if (gsk_sl_expression_is_constant (lvalue)) { gsk_sl_preprocessor_error (stream, "Cannot assign to a return lvalue."); @@ -1643,6 +1655,7 @@ gsk_sl_expression_parse_assignment (GskSlScope *scope, return gsk_sl_expression_parse_assignment (scope, stream); } +#endif assign = gsk_sl_expression_new (GskSlExpressionAssignment, &GSK_SL_EXPRESSION_ASSIGNMENT); assign->lvalue = lvalue; @@ -1704,10 +1717,10 @@ gsk_sl_expression_get_return_type (const GskSlExpression *expression) return expression->class->get_return_type (expression); } -gboolean -gsk_sl_expression_is_constant (const GskSlExpression *expression) +GskSlValue * +gsk_sl_expression_get_constant (const GskSlExpression *expression) { - return expression->class->is_constant (expression); + return expression->class->get_constant (expression); } guint32 diff --git a/gsk/gskslexpressionprivate.h b/gsk/gskslexpressionprivate.h index a526bf3344..214d63425b 100644 --- a/gsk/gskslexpressionprivate.h +++ b/gsk/gskslexpressionprivate.h @@ -27,6 +27,8 @@ GskSlExpression * gsk_sl_expression_parse (GskSlScope GskSlPreprocessor *stream); GskSlExpression * gsk_sl_expression_parse_assignment (GskSlScope *scope, GskSlPreprocessor *stream); +GskSlExpression * gsk_sl_expression_parse_constant (GskSlScope *scope, + GskSlPreprocessor *stream); GskSlExpression * gsk_sl_expression_parse_constructor_call (GskSlScope *scope, GskSlPreprocessor *stream, GskSlType *type); @@ -37,7 +39,7 @@ void gsk_sl_expression_unref (GskSlExpression void gsk_sl_expression_print (const GskSlExpression *expression, GString *string); GskSlType * gsk_sl_expression_get_return_type (const GskSlExpression *expression); -gboolean gsk_sl_expression_is_constant (const GskSlExpression *expression); +GskSlValue * gsk_sl_expression_get_constant (const GskSlExpression *expression); guint32 gsk_sl_expression_write_spv (const GskSlExpression *expression, GskSpvWriter *writer); diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c index 49a63900a0..f7261e8dc6 100644 --- a/gsk/gskslnode.c +++ b/gsk/gskslnode.c @@ -356,7 +356,8 @@ gsk_sl_node_parse_statement (GskSlScope *scope, GskSlDecorations decoration; gboolean success; - success = gsk_sl_decoration_list_parse (preproc, + success = gsk_sl_decoration_list_parse (scope, + preproc, &decoration); type = gsk_sl_type_new_parse (preproc); diff --git a/gsk/gskslpointertype.c b/gsk/gskslpointertype.c index af024b9311..3269e27f0e 100644 --- a/gsk/gskslpointertype.c +++ b/gsk/gskslpointertype.c @@ -20,9 +20,11 @@ #include "gskslpointertypeprivate.h" +#include "gskslexpressionprivate.h" #include "gskslpreprocessorprivate.h" #include "gsksltokenizerprivate.h" #include "gsksltypeprivate.h" +#include "gskslvalueprivate.h" #include "gskspvwriterprivate.h" struct _GskSlPointerType { @@ -79,10 +81,14 @@ gsk_sl_decoration_list_add_simple (GskSlPreprocessor *preproc, static gboolean gsk_sl_decoration_list_parse_assignment (GskSlPreprocessor *preproc, + GskSlScope *scope, GskSlDecorations *list, GskSlDecoration decoration) { + GskSlExpression *expression; const GskSlToken *token; + GskSlValue *value; + GskSlType *type; gboolean success = TRUE; gsk_sl_preprocessor_consume (preproc, NULL); @@ -95,29 +101,41 @@ gsk_sl_decoration_list_parse_assignment (GskSlPreprocessor *preproc, } gsk_sl_preprocessor_consume (preproc, NULL); - /* XXX: This should be a constant expression */ - token = gsk_sl_preprocessor_get (preproc); - if (gsk_sl_token_is (token, GSK_SL_TOKEN_INTCONSTANT)) + expression = gsk_sl_expression_parse_constant (scope, preproc); + if (expression == NULL) + return FALSE; + + value = gsk_sl_expression_get_constant (expression); + gsk_sl_expression_unref (expression); + + if (value == NULL) { - success = gsk_sl_decoration_list_set (preproc, list, decoration, token->i32); - gsk_sl_preprocessor_consume (preproc, NULL); + gsk_sl_preprocessor_error (preproc, "Expression is not constant."); + return FALSE; } - else if (gsk_sl_token_is (token, GSK_SL_TOKEN_UINTCONSTANT)) + + type = gsk_sl_value_get_type (value); + if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT) { - success = gsk_sl_decoration_list_set (preproc, list, decoration, token->u32); - gsk_sl_preprocessor_consume (preproc, NULL); + success = gsk_sl_decoration_list_set (preproc, list, decoration, *(gint32 *) gsk_sl_value_get_data (value)); + } + else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT) + { + success = gsk_sl_decoration_list_set (preproc, list, decoration, *(guint32 *) gsk_sl_value_get_data (value)); } else { - gsk_sl_preprocessor_error (preproc, "Assignment is not an integer."); - return FALSE; + gsk_sl_preprocessor_error (preproc, "Type of expression is not an integer type, but %s", gsk_sl_type_get_name (type)); + success = FALSE; } + gsk_sl_value_free (value); return success; } static gboolean gsk_sl_decoration_list_parse_layout (GskSlPreprocessor *preproc, + GskSlScope *scope, GskSlDecorations *list) { const GskSlToken *token; @@ -140,24 +158,28 @@ gsk_sl_decoration_list_parse_layout (GskSlPreprocessor *preproc, if (g_str_equal (token->str, "location")) { success &= gsk_sl_decoration_list_parse_assignment (preproc, + scope, list, GSK_SL_DECORATION_LAYOUT_LOCATION); } else if (g_str_equal (token->str, "component")) { success &= gsk_sl_decoration_list_parse_assignment (preproc, + scope, list, GSK_SL_DECORATION_LAYOUT_COMPONENT); } else if (g_str_equal (token->str, "binding")) { success &= gsk_sl_decoration_list_parse_assignment (preproc, + scope, list, GSK_SL_DECORATION_LAYOUT_BINDING); } else if (g_str_equal (token->str, "set")) { success &= gsk_sl_decoration_list_parse_assignment (preproc, + scope, list, GSK_SL_DECORATION_LAYOUT_SET); } @@ -187,7 +209,8 @@ gsk_sl_decoration_list_parse_layout (GskSlPreprocessor *preproc, } gboolean -gsk_sl_decoration_list_parse (GskSlPreprocessor *preproc, +gsk_sl_decoration_list_parse (GskSlScope *scope, + GskSlPreprocessor *preproc, GskSlDecorations *list) { const GskSlToken *token; @@ -327,7 +350,7 @@ gsk_sl_decoration_list_parse (GskSlPreprocessor *preproc, } gsk_sl_preprocessor_consume (preproc, NULL); - success &= gsk_sl_decoration_list_parse_layout (preproc, list); + success &= gsk_sl_decoration_list_parse_layout (preproc, scope, list); token = gsk_sl_preprocessor_get (preproc); if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN)) diff --git a/gsk/gskslpointertypeprivate.h b/gsk/gskslpointertypeprivate.h index 08e59d83c5..2624472d4f 100644 --- a/gsk/gskslpointertypeprivate.h +++ b/gsk/gskslpointertypeprivate.h @@ -58,7 +58,8 @@ struct _GskSlDecorations } values[GSK_SL_N_DECORATIONS]; }; -gboolean gsk_sl_decoration_list_parse (GskSlPreprocessor *stream, +gboolean gsk_sl_decoration_list_parse (GskSlScope *scope, + GskSlPreprocessor *stream, GskSlDecorations *list); GskSlPointerType * gsk_sl_pointer_type_new (GskSlType *type, diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c index a5b9e21726..f351996952 100644 --- a/gsk/gskslprogram.c +++ b/gsk/gskslprogram.c @@ -100,7 +100,8 @@ gsk_sl_program_parse_declaration (GskSlProgram *program, gboolean success; char *name; - success = gsk_sl_decoration_list_parse (preproc, + success = gsk_sl_decoration_list_parse (scope, + preproc, &decoration); type = gsk_sl_type_new_parse (preproc);