@@ -21605,6 +21605,26 @@ pm_call_node_command_p(const pm_call_node_t *node) {
2160521605 );
2160621606}
2160721607
21608+ /**
21609+ * Determine if a given write node has a command call as its right-hand side. We
21610+ * need this because command calls as the values of writes cannot be extended by
21611+ * infix operators.
21612+ */
21613+ static inline bool
21614+ pm_write_node_command_p(const pm_node_t *node) {
21615+ pm_node_t *value;
21616+ switch (PM_NODE_TYPE(node)) {
21617+ case PM_CLASS_VARIABLE_WRITE_NODE: value = ((pm_class_variable_write_node_t *) node)->value; break;
21618+ case PM_CONSTANT_PATH_WRITE_NODE: value = ((pm_constant_path_write_node_t *) node)->value; break;
21619+ case PM_CONSTANT_WRITE_NODE: value = ((pm_constant_write_node_t *) node)->value; break;
21620+ case PM_GLOBAL_VARIABLE_WRITE_NODE: value = ((pm_global_variable_write_node_t *) node)->value; break;
21621+ case PM_INSTANCE_VARIABLE_WRITE_NODE: value = ((pm_instance_variable_write_node_t *) node)->value; break;
21622+ case PM_LOCAL_VARIABLE_WRITE_NODE: value = ((pm_local_variable_write_node_t *) node)->value; break;
21623+ default: return false;
21624+ }
21625+ return PM_NODE_TYPE_P(value, PM_CALL_NODE) && pm_call_node_command_p((pm_call_node_t *) value);
21626+ }
21627+
2160821628/**
2160921629 * Parse an expression at the given point of the parser using the given binding
2161021630 * power to parse subsequent chains. If this function finds a syntax error, it
@@ -21689,9 +21709,13 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
2168921709 case PM_INSTANCE_VARIABLE_WRITE_NODE:
2169021710 case PM_LOCAL_VARIABLE_WRITE_NODE:
2169121711 // These expressions are statements, by virtue of the right-hand
21692- // side of their write being an implicit array.
21693- if (PM_NODE_FLAG_P(node, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY) && pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) {
21694- return node;
21712+ // side of their write being an implicit array or a command call.
21713+ // This mirrors parse.y's behavior where `lhs = command_call`
21714+ // reduces to stmt (not expr), preventing and/or from following.
21715+ if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) {
21716+ if (PM_NODE_FLAG_P(node, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY) || pm_write_node_command_p(node)) {
21717+ return node;
21718+ }
2169521719 }
2169621720 break;
2169721721 case PM_CALL_NODE:
0 commit comments