diff options
author | Nicholas Clark <nick@ccl4.org> | 2007-12-20 21:15:57 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2007-12-20 21:15:57 +0000 |
commit | 878d132a73f5d089e821fedd49aa4835a2786d1d (patch) | |
tree | 5f489d4e731a9809ef0261bfb731eee600f3911a /pp.c | |
parent | 3bdcbd26ea8ce137a02a61d6364dbbb1afb63c19 (diff) | |
download | perl-878d132a73f5d089e821fedd49aa4835a2786d1d.tar.gz |
Implement each @array.
Documentation needed, FIXME for proper 64 bit support of arrays longer
than 2**32, re-order the new ops at the end if merging to 5.10.x.
p4raw-id: //depot/perl@32680
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 61 |
1 files changed, 61 insertions, 0 deletions
@@ -3929,6 +3929,67 @@ PP(pp_aslice) RETURN; } +PP(pp_aeach) +{ + dVAR; + dSP; + AV *array = (AV*)POPs; + const I32 gimme = GIMME_V; + I32 *iterp = Perl_av_iter_p(aTHX_ array); + const IV current = (*iterp)++; + + if (current > av_len(array)) { + *iterp = 0; + if (gimme == G_SCALAR) + RETPUSHUNDEF; + else + RETURN; + } + + EXTEND(SP, 2); + mPUSHi(CopARYBASE_get(PL_curcop) + current); + if (gimme == G_ARRAY) { + SV **const element = av_fetch(array, current, 0); + PUSHs(element ? *element : &PL_sv_undef); + } + RETURN; +} + +PP(pp_akeys) +{ + dVAR; + dSP; + AV *array = (AV*)POPs; + const I32 gimme = GIMME_V; + + *Perl_av_iter_p(aTHX_ array) = 0; + + if (gimme == G_SCALAR) { + dTARGET; + PUSHi(av_len(array) + 1); + } + else if (gimme == G_ARRAY) { + IV n = Perl_av_len(aTHX_ array); + IV i = CopARYBASE_get(PL_curcop); + + EXTEND(SP, n + 1); + + if (PL_op->op_type == OP_AKEYS) { + n += i; + for (; i <= n; i++) { + mPUSHi(i); + } + } + else { + for (i = 0; i <= n; i++) { + SV *const *const elem = Perl_av_fetch(aTHX_ array, i, 0); + PUSHs(elem ? *elem : &PL_sv_undef); + } + } + } + RETURN; +} + /* Associative arrays. */ PP(pp_each) |