diff options
author | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2022-11-19 11:48:19 +0000 |
---|---|---|
committer | Paul Evans <leonerd@leonerd.org.uk> | 2022-11-26 15:47:22 +0000 |
commit | f17d9825ab9b50967fd3d8742cc1bbccec96c049 (patch) | |
tree | 1835ae9ad258f5fadd48b08c96b33887768c3352 /perly.y | |
parent | 5bd919dc87af18e1bce77d3ead83b704a2903292 (diff) | |
download | perl-f17d9825ab9b50967fd3d8742cc1bbccec96c049.tar.gz |
Recognise `//=` and `||=` syntax in signature parameter defaults
These create parameters where the default expression is assigned
whenever the caller did not pass a defined (or true) value. I.e. both if
it is missing, or is present but undef (or false).
Diffstat (limited to 'perly.y')
-rw-r--r-- | perly.y | 36 |
1 files changed, 19 insertions, 17 deletions
@@ -749,15 +749,15 @@ sigslurpsigil: /* @, %, @foo, %foo */ sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */ { - I32 sigil = $sigslurpsigil; - OP *var = $sigvarname; - OP *defexpr = $sigdefault; + I32 sigil = $sigslurpsigil; + OP *var = $sigvarname; + OP *defop = $sigdefault; if (parser->sig_slurpy) yyerror("Multiple slurpy parameters not allowed"); parser->sig_slurpy = (char)sigil; - if (defexpr) + if (defop) yyerror("A slurpy parameter may not have " "a default value"); @@ -769,26 +769,35 @@ sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */ sigdefault : empty | ASSIGNOP - { $$ = newOP(OP_NULL, 0); } + { $$ = newARGDEFELEMOP(0, newOP(OP_NULL, 0), parser->sig_elems); } | ASSIGNOP term - { $$ = $term; } + { + I32 flags = 0; + if ($ASSIGNOP == OP_DORASSIGN) + flags |= OPpARG_IF_UNDEF << 8; + if ($ASSIGNOP == OP_ORASSIGN) + flags |= OPpARG_IF_FALSE << 8; + $$ = newARGDEFELEMOP(flags, $term, parser->sig_elems); + } /* subroutine signature scalar element: e.g. '$x', '$=', '$x = $default' */ sigscalarelem: PERLY_DOLLAR sigvarname sigdefault { - OP *var = $sigvarname; - OP *defexpr = $sigdefault; + OP *var = $sigvarname; + OP *defop = $sigdefault; if (parser->sig_slurpy) yyerror("Slurpy parameter not last"); parser->sig_elems++; - if (defexpr) { + if (defop) { parser->sig_optelems++; + OP *defexpr = cLOGOPx(defop)->op_first; + if ( defexpr->op_type == OP_NULL && !(defexpr->op_flags & OPf_KIDS)) { @@ -796,17 +805,10 @@ sigscalarelem: if (var) yyerror("Optional parameter " "lacks default expression"); - op_free(defexpr); + op_free(defop); } else { /* a normal '=default' expression */ - OP *defop = (OP*)alloc_LOGOP(OP_ARGDEFELEM, - defexpr, - LINKLIST(defexpr)); - /* re-purpose op_targ to hold @_ index */ - defop->op_targ = - (PADOFFSET)(parser->sig_elems - 1); - if (var) { var->op_flags |= OPf_STACKED; (void)op_sibling_splice(var, |