From 6dd3e0f2449b60948d1ae2a8377afcea1fb88000 Mon Sep 17 00:00:00 2001 From: Ruslan Zakirov Date: Sat, 2 Mar 2013 16:57:41 +0400 Subject: index/value array slice operation kvaslice operator that imlements %a[0,2,4] syntax which result in list of index/value pairs. Implemented in consistency with "key/value hash slice" operator. --- pp.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'pp.c') diff --git a/pp.c b/pp.c index 470ebd1681..2dd0fe8d9a 100644 --- a/pp.c +++ b/pp.c @@ -4350,6 +4350,50 @@ PP(pp_aslice) RETURN; } +PP(pp_kvaslice) +{ + dVAR; dSP; dMARK; + AV *const av = MUTABLE_AV(POPs); + I32 lval = (PL_op->op_flags & OPf_MOD); + I32 items = SP - MARK; + + if (PL_op->op_private & OPpMAYBE_LVSUB) { + const I32 flags = is_lvalue_sub(); + if (flags) { + if (!(flags & OPpENTERSUB_INARGS)) + Perl_croak(aTHX_ "Can't modify index/value array slice in list assignment"); + lval = flags; + } + } + + MEXTEND(SP,items); + while (items > 1) { + *(MARK+items*2-1) = *(MARK+items); + items--; + } + items = SP-MARK; + SP += items; + + while (++MARK <= SP) { + SV **svp; + + svp = av_fetch(av, SvIV(*MARK), lval); + if (lval) { + if (!svp || !*svp || *svp == &PL_sv_undef) { + DIE(aTHX_ PL_no_aelem, SvIV(*MARK)); + } + *MARK = sv_mortalcopy(*MARK); + } + *++MARK = svp ? *svp : &PL_sv_undef; + } + if (GIMME != G_ARRAY) { + MARK = SP - items*2; + *++MARK = items > 0 ? *SP : &PL_sv_undef; + SP = MARK; + } + RETURN; +} + /* Smart dereferencing for keys, values and each */ PP(pp_rkeys) { -- cgit v1.2.1