diff options
author | David Mitchell <davem@iabyn.com> | 2022-11-22 13:52:51 +0000 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2023-02-28 20:53:51 +0800 |
commit | e3809a1029508f1bd6720045451293be8f06d4b8 (patch) | |
tree | a4bb8a844365936aa0c171d9243dbdf1317d5b0f /pp_hot.c | |
parent | ad5fedb002a4e7befcb1bd42bd788878f37a0d6e (diff) | |
download | perl-e3809a1029508f1bd6720045451293be8f06d4b8.tar.gz |
add code comments concerning grep and map markstack usage
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -4782,6 +4782,57 @@ PP(pp_subst) PP(pp_grepwhile) { + /* Understanding the stack during a grep. + * + * 'grep expr, args' is implemented in the form of + * grepstart; + * do { + * expr; + * grepwhile; + * } while (args); + * + * The stack examples below are in the form of 'perl -Ds' output, + * where any stack element indexed by PL_markstack_ptr[i] has a star + * just to the right of it. In addition, the corresponding i value + * is displayed under the indexed stack element. + * + * On entry to grepwhile, the stack looks like this: + * + * => * M1..Mn X1 * X2..Xn C * R1..Rn BOOL + * [-2] [-1] [0] + * + * where: + * M1..Mn Accumulated args which have been matched so far. + * X1..Xn Random discardable elements from previous iterations. + * C The current (just processed) arg, still aliased to $_. + * R1..Rn The args remaining to be processed. + * BOOL the result of the just-executed grep expression. + * + * Note that it is easiest to think of the top two stack marks as both + * being one too high, and so it would make more sense to have had the + * marks like this: + * + * => * M1..Mn * X1..Xn * C R1..Rn BOOL + * [-2] [-1] [0] + * + * where the stack is divided neatly into 3 groups: + * - matched, + * - discarded, + * - being, or yet to be, processed. + * But off-by-one is the way it is currently, and it works as long as + * we keep it consistent and bear it in mind. + * + * pp_grepwhile() does the following: + * + * - for a match, replace the X1 pointer with a pointer to C and bump + * PL_markstack_ptr[-1] + * - if more args to process, bump PL_markstack_ptr[0] and update the + * $_ alias, else + * - remove top 3 MARKs and return M1..Mn, or a scalar, + * or void as appropriate. + * + */ + dSP; dPOPss; |