From dc519ad2a2a959691f4043c1f81b3dff8262ccb0 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 16 Sep 2017 21:50:42 +0200 Subject: [PATCH] gskslnode: Add gsk_sl_node_is_constant() And use it to emit a compile error when trying to assign to a constant value. --- gsk/gskslnode.c | 56 +++++++++++++++++++++++++++++++++++++++--- gsk/gskslnodeprivate.h | 2 ++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c index 3237642d8a..7fc6ed3ade 100644 --- a/gsk/gskslnode.c +++ b/gsk/gskslnode.c @@ -83,10 +83,17 @@ gsk_sl_node_program_get_return_type (GskSlNode *node) return NULL; } +static gboolean +gsk_sl_node_program_is_constant (GskSlNode *node) +{ + return TRUE; +} + static const GskSlNodeClass GSK_SL_NODE_PROGRAM = { gsk_sl_node_program_free, gsk_sl_node_program_print, - gsk_sl_node_program_get_return_type + gsk_sl_node_program_get_return_type, + gsk_sl_node_program_is_constant }; /* FUNCTION */ @@ -146,10 +153,17 @@ gsk_sl_node_function_get_return_type (GskSlNode *node) return function->return_type; } +static gboolean +gsk_sl_node_function_is_constant (GskSlNode *node) +{ + return TRUE; +} + static const GskSlNodeClass GSK_SL_NODE_FUNCTION = { gsk_sl_node_function_free, gsk_sl_node_function_print, - gsk_sl_node_function_get_return_type + gsk_sl_node_function_get_return_type, + gsk_sl_node_function_is_constant }; /* ASSIGNMENT */ @@ -234,10 +248,19 @@ gsk_sl_node_assignment_get_return_type (GskSlNode *node) return gsk_sl_node_get_return_type (assignment->lvalue); } +static gboolean +gsk_sl_node_assignment_is_constant (GskSlNode *node) +{ + //GskSlNodeAssignment *assignment = (GskSlNodeAssignment *) node; + + return FALSE; +} + static const GskSlNodeClass GSK_SL_NODE_ASSIGNMENT = { gsk_sl_node_assignment_free, gsk_sl_node_assignment_print, - gsk_sl_node_assignment_get_return_type + gsk_sl_node_assignment_get_return_type, + gsk_sl_node_assignment_is_constant }; /* CONSTANT */ @@ -320,10 +343,17 @@ gsk_sl_node_constant_get_return_type (GskSlNode *node) return gsk_sl_type_get_builtin (constant->type); } +static gboolean +gsk_sl_node_constant_is_constant (GskSlNode *node) +{ + return TRUE; +} + static const GskSlNodeClass GSK_SL_NODE_CONSTANT = { gsk_sl_node_constant_free, gsk_sl_node_constant_print, - gsk_sl_node_constant_get_return_type + gsk_sl_node_constant_get_return_type, + gsk_sl_node_constant_is_constant }; /* API */ @@ -452,11 +482,23 @@ gsk_sl_node_parse_assignment_expression (GskSlNodeProgram *program, return lvalue; } + if (gsk_sl_node_is_constant (lvalue)) + { + gsk_sl_preprocessor_error (stream, "Cannot assign to a constant lvalue."); + + /* Continue parsing like normal here to get more errors */ + gsk_sl_preprocessor_consume (stream, lvalue); + gsk_sl_node_unref (lvalue); + + return gsk_sl_node_parse_assignment_expression (program, stream); + } + assign = gsk_sl_node_new (GskSlNodeAssignment, &GSK_SL_NODE_ASSIGNMENT); assign->lvalue = lvalue; assign->op = token->type; gsk_sl_preprocessor_consume (stream, (GskSlNode *) assign); + assign->rvalue = gsk_sl_node_parse_assignment_expression (program, stream); if (assign->rvalue == NULL) { @@ -622,3 +664,9 @@ gsk_sl_node_get_return_type (GskSlNode *node) { return node->class->get_return_type (node); } + +gboolean +gsk_sl_node_is_constant (GskSlNode *node) +{ + return node->class->is_constant (node); +} diff --git a/gsk/gskslnodeprivate.h b/gsk/gskslnodeprivate.h index e5020bfa88..e41b3a26bd 100644 --- a/gsk/gskslnodeprivate.h +++ b/gsk/gskslnodeprivate.h @@ -38,6 +38,7 @@ struct _GskSlNodeClass { void (* print) (GskSlNode *node, GString *string); GskSlType * (* get_return_type) (GskSlNode *node); + gboolean (* is_constant) (GskSlNode *node); }; GskSlNode * gsk_sl_node_new_program (GBytes *source, @@ -49,6 +50,7 @@ void gsk_sl_node_unref (GskSlNode void gsk_sl_node_print (GskSlNode *node, GString *string); GskSlType * gsk_sl_node_get_return_type (GskSlNode *node); +gboolean gsk_sl_node_is_constant (GskSlNode *node); G_END_DECLS