GitHub

@@ -3848,29 +3848,31 @@ cases : opt_else

38483848

;

3849384938503850

/* Pattern matching in-clauses for case/in */

3851+

/* in_kwarg is set by lexer when keyword_in is returned */

38513852

in_clauses : opt_else

38523853

{

38533854

$$ = $1 ? list1(new_in(p, NULL, NULL, $1, FALSE)) : 0;

38543855

}

3855-

| keyword_in p_expr then compstmt in_clauses

3856+

| keyword_in p_expr {p->in_kwarg--;} then compstmt in_clauses

38563857

{

3857-

node *in_clause = new_in(p, $2, NULL, $4, FALSE);

3858-

$$ = cons(in_clause, $5);

3858+

node *in_clause = new_in(p, $2, NULL, $5, FALSE);

3859+

$$ = cons(in_clause, $6);

38593860

}

3860-

| keyword_in p_expr modifier_if expr_value then compstmt in_clauses

3861+

| keyword_in p_expr {p->in_kwarg--;} modifier_if expr_value then compstmt in_clauses

38613862

{

3862-

node *in_clause = new_in(p, $2, $4, $6, FALSE);

3863-

$$ = cons(in_clause, $7);

3863+

node *in_clause = new_in(p, $2, $5, $7, FALSE);

3864+

$$ = cons(in_clause, $8);

38643865

}

3865-

| keyword_in p_expr modifier_unless expr_value then compstmt in_clauses

3866+

| keyword_in p_expr {p->in_kwarg--;} modifier_unless expr_value then compstmt in_clauses

38663867

{

3867-

node *in_clause = new_in(p, $2, $4, $6, TRUE);

3868-

$$ = cons(in_clause, $7);

3868+

node *in_clause = new_in(p, $2, $5, $7, TRUE);

3869+

$$ = cons(in_clause, $8);

38693870

}

38703871

;

3871387238723873

/* Pattern expressions for case/in */

38733874

/* Bracket-less array patterns: in 1, 2, x is same as in [1, 2, x] */

3875+

/* Brace-less hash patterns: in a:, b: x is same as in {a:, b: x} */

38743876

p_expr : p_as

38753877

| p_args_head p_as

38763878

{

@@ -3892,6 +3894,21 @@ p_expr : p_as

38923894

{

38933895

$$ = new_pat_array(p, 0, $1, $3);

38943896

}

3897+

| p_hash_elems

3898+

{

3899+

/* Brace-less hash pattern: in a:, b: x */

3900+

$$ = new_pat_hash(p, $1, 0);

3901+

}

3902+

| p_hash_elems ',' p_kwrest

3903+

{

3904+

/* Brace-less hash pattern with kwrest: in a:, **rest */

3905+

$$ = new_pat_hash(p, $1, $3);

3906+

}

3907+

| p_kwrest

3908+

{

3909+

/* Brace-less kwrest only: in **rest */

3910+

$$ = new_pat_hash(p, 0, $1);

3911+

}

38953912

;

3896391338973914

/* Comma-separated pattern list (prefix) */

@@ -4075,7 +4092,8 @@ p_hash_elems : p_hash_elem

40754092

;

4076409340774094

/* Hash pattern element: key: pattern or key: (shorthand) */

4078-

p_hash_elem : tIDENTIFIER tLABEL_TAG p_expr

4095+

/* Use p_as, not p_expr to avoid brace-less recursion inside hash patterns */

4096+

p_hash_elem : tIDENTIFIER tLABEL_TAG p_as

40794097

{

40804098

/* {key: pattern} */

40814099

$$ = cons(new_sym(p, $1), $3);

@@ -4085,7 +4103,7 @@ p_hash_elem : tIDENTIFIER tLABEL_TAG p_expr

40854103

/* {key:} shorthand - binds to variable with same name */

40864104

$$ = cons(new_sym(p, $1), new_pat_var(p, $1));

40874105

}

4088-

| symbol tASSOC p_expr

4106+

| symbol tASSOC p_as

40894107

{

40904108

/* {:"key" => pattern} or {:key => pattern} */

40914109

$$ = cons($1, $3);

@@ -5393,7 +5411,7 @@ toklen(parser_state *p)

53935411

#define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN)

53945412

#define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS)

53955413

#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))

5396-

#define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())

5414+

#define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG() || p->lstate == EXPR_VALUE)

53975415

#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))

5398541653995417

static int32_t

@@ -6855,7 +6873,8 @@ parser_yylex(parser_state *p)

68556873

}

68566874

if (!space_seen && IS_END()) {

68576875

pushback(p, c);

6858-

p->lstate = EXPR_BEG;

6876+

/* In pattern matching context, use EXPR_ARG so newlines are significant */

6877+

p->lstate = p->in_kwarg ? EXPR_ARG : EXPR_BEG;

68596878

return tLABEL_TAG;

68606879

}

68616880

if (IS_END() || ISSPACE(c) || c == '#') {

@@ -7357,6 +7376,10 @@ parser_yylex(parser_state *p)

73577376

return keyword_do_block;

73587377

return keyword_do;

73597378

}

7379+

if (kw->id[0] == keyword_in) {

7380+

/* Set in_kwarg for pattern matching context */

7381+

p->in_kwarg++;

7382+

}

73607383

if (state == EXPR_BEG || state == EXPR_VALUE || state == EXPR_CLASS)

73617384

return kw->id[0];

73627385

else {

Read the original on github.com ↗