diff --git a/src/prism.c b/src/prism.c index 358cd04956..87ff82c00e 100644 --- a/src/prism.c +++ b/src/prism.c @@ -20895,6 +20895,23 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t * } } +static void +validate_local_variable_assignment_with_call(pm_parser_t *parser, pm_node_t *node) { + if (PM_NODE_TYPE_P(node, PM_LOCAL_VARIABLE_WRITE_NODE)) { + pm_local_variable_write_node_t* cast = (pm_local_variable_write_node_t *)node; + if (PM_NODE_TYPE_P(cast->value, PM_CALL_NODE)) { + pm_call_node_t *call_node = (pm_call_node_t *)cast->value; + if (call_node->arguments != NULL) { + if (call_node->opening_loc.start == NULL) { + pm_node_t *arguments = (pm_node_t *)call_node->arguments; + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, arguments, PM_ERR_LAMBDA_OPEN); + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, arguments, PM_ERR_EXPECT_LPAREN_REQ_PARAMETER); + } + } + } + } +} + static inline pm_node_t * parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, uint16_t depth) { pm_token_t token = parser->current; @@ -21317,6 +21334,8 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t parser_lex(parser); pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + validate_local_variable_assignment_with_call(parser, node); + validate_local_variable_assignment_with_call(parser, right); return (pm_node_t *) pm_and_node_create(parser, node, &token, right); } case PM_TOKEN_KEYWORD_OR: @@ -21324,6 +21343,8 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t parser_lex(parser); pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + validate_local_variable_assignment_with_call(parser, node); + validate_local_variable_assignment_with_call(parser, right); return (pm_node_t *) pm_or_node_create(parser, node, &token, right); } case PM_TOKEN_EQUAL_TILDE: { @@ -21542,6 +21563,8 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t parser_lex(parser); pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_IF_PREDICATE, (uint16_t) (depth + 1)); + validate_local_variable_assignment_with_call(parser, node); + validate_local_variable_assignment_with_call(parser, predicate); return (pm_node_t *) pm_if_node_modifier_create(parser, node, &keyword, predicate); } case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: { @@ -21549,6 +21572,8 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t parser_lex(parser); pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_UNLESS_PREDICATE, (uint16_t) (depth + 1)); + validate_local_variable_assignment_with_call(parser, node); + validate_local_variable_assignment_with_call(parser, predicate); return (pm_node_t *) pm_unless_node_modifier_create(parser, node, &keyword, predicate); } case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: { diff --git a/test/prism/errors/assignment_in_and_operator_without_parentheses.txt b/test/prism/errors/assignment_in_and_operator_without_parentheses.txt new file mode 100644 index 0000000000..e63a957b5a --- /dev/null +++ b/test/prism/errors/assignment_in_and_operator_without_parentheses.txt @@ -0,0 +1,4 @@ +1 and a = p 2 + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_in_if_condition_without_parentheses.txt b/test/prism/errors/assignment_in_if_condition_without_parentheses.txt new file mode 100644 index 0000000000..45962ff9ca --- /dev/null +++ b/test/prism/errors/assignment_in_if_condition_without_parentheses.txt @@ -0,0 +1,4 @@ +1 if a = p 2 + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_in_or_operator_without_parentheses.txt b/test/prism/errors/assignment_in_or_operator_without_parentheses.txt new file mode 100644 index 0000000000..231fa558f5 --- /dev/null +++ b/test/prism/errors/assignment_in_or_operator_without_parentheses.txt @@ -0,0 +1,4 @@ +1 or a = p 2 + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_in_unless_condition_without_parentheses.txt b/test/prism/errors/assignment_in_unless_condition_without_parentheses.txt new file mode 100644 index 0000000000..733de8395a --- /dev/null +++ b/test/prism/errors/assignment_in_unless_condition_without_parentheses.txt @@ -0,0 +1,4 @@ +1 unless a = p 2 + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_with_method_call_without_parentheses_and_and_operator.txt b/test/prism/errors/assignment_with_method_call_without_parentheses_and_and_operator.txt new file mode 100644 index 0000000000..5ccc26cd8a --- /dev/null +++ b/test/prism/errors/assignment_with_method_call_without_parentheses_and_and_operator.txt @@ -0,0 +1,4 @@ +a = p 1 and 2 + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_with_method_call_without_parentheses_and_modifier_if.txt b/test/prism/errors/assignment_with_method_call_without_parentheses_and_modifier_if.txt new file mode 100644 index 0000000000..fa5e9c8ac4 --- /dev/null +++ b/test/prism/errors/assignment_with_method_call_without_parentheses_and_modifier_if.txt @@ -0,0 +1,4 @@ +a = p 1 if true + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_with_method_call_without_parentheses_and_modifier_unless.txt b/test/prism/errors/assignment_with_method_call_without_parentheses_and_modifier_unless.txt new file mode 100644 index 0000000000..a397051f11 --- /dev/null +++ b/test/prism/errors/assignment_with_method_call_without_parentheses_and_modifier_unless.txt @@ -0,0 +1,4 @@ +a = p 1 unless true + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter + diff --git a/test/prism/errors/assignment_with_method_call_without_parentheses_and_or_operator.txt b/test/prism/errors/assignment_with_method_call_without_parentheses_and_or_operator.txt new file mode 100644 index 0000000000..2522dd5f46 --- /dev/null +++ b/test/prism/errors/assignment_with_method_call_without_parentheses_and_or_operator.txt @@ -0,0 +1,4 @@ +a = p 1 or 2 + ^ expected a `do` keyword or a `{` to open the lambda block + ^ expected a `(` to start a required parameter +