summaryrefslogtreecommitdiff
path: root/perly.y
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2022-11-19 11:48:19 +0000
committerPaul Evans <leonerd@leonerd.org.uk>2022-11-26 15:47:22 +0000
commitf17d9825ab9b50967fd3d8742cc1bbccec96c049 (patch)
tree1835ae9ad258f5fadd48b08c96b33887768c3352 /perly.y
parent5bd919dc87af18e1bce77d3ead83b704a2903292 (diff)
downloadperl-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.y36
1 files changed, 19 insertions, 17 deletions
diff --git a/perly.y b/perly.y
index 1cb83cc9e5..23c8dd6ee8 100644
--- a/perly.y
+++ b/perly.y
@@ -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,