As noted by https://github.com/Perl/perl5/issues/24027, while multivar
foreach and refalias foreach have each been available separately for
some time now, it wasn't possible to combine the two until now.
This current implementation does have limits on the number of variables
in total are allowed in a multivariable foreach loop if any are
refaliases (no more than 256), and which ones can be refaliases (none
past the 24th) that are all to do with the way I am abusing the U32
`op_targ` field to store the variable count in the lower 8 bits, and a
bitmask of which vars are refaliases in the upper 24 bits. I decided to
do that as it means I don't have to make the `OP_ITER` op any larger -
such as by expanding it to an UNOP_AUX to give it that extra storage
space. In practice I don't imagine those limits will be a problem for
any practical use-case.
If in a future version we did want to expand on those limits, I think it
would be possible by moving the `refalias_mask` storage to a PV stored
in the UNOP_AUX vector, or somesuch.
Currently these are all scalar variables, but soon I will add the
ability for iteration variables to be refaliases, so they won't
necessarily all be scalars any more.
Prior to this, toke.c and perly.y used the token name `THING` for a
number of apparently totally unrelated reasons. While I haven't
attempted to fix most of them, I did find that the one used for
attribute lists is unrelated to the others, so I have renamed that to
something more sensible and meaningful.
We need to use a dedicated grammar type; or at the very least, not use
`subattrlist` for doing this. The previous use of `subattrlist` had the
side-effect of passing every attribute list for a class via the
`apply_builtin_cv_attributes()` function. That was pointlessly
redundant, though currently harmless. It may stop being harmless in a
future improvement to the way attributes are handled, so best not to do
that any more.
The new structure repurposes the previous `myattrlist` to be a
non-optional attribute list, and defines `optattrlist` to use for both
class and field attributes.
This adds a major new ability to subroutine signatures, allowing callers
to pass parameters by name/value pairs rather than by position.
sub f ($x, $y, :$alpha, :$beta = undef) { ... }
f( 123, 456, alpha => 789 );
Originally specified in
https://github.com/Perl/PPCs/blob/main/ppcs/ppc0024-signature-named-parameters.md
This feature is currently considered experimental.
Function combines call of original `package` and `package_version` when
new namespace statement is detected.
Instead of required three statements usage now consists of single function call.
By defining a helper term for optional defaulting expression we can
remove one of the three alternate cases down to just two. This will help
when adding more code to these action blocks in future,
This simplifies potential callsites from other locations, avoiding their
need to create the special weird OP_ARGELEM fragments. Additionally this
decouples the knowledge that these operations are run on OP_ARGELEM ops
in the first place, allowing for a future version that operates
differently.
This fixes the TODO test in t/op/anonsub.t, but breaks two other tests:
- t/op/anonsub.t
not ok 12 - '{ $x = sub }' is illegal
# Failed test 12 - '{ $x = sub }' is illegal at t/op/anonsub.t line 15
# got 'Global symbol \"$x\" requires explicit package name (did you forget to declare \"my $x\"?) at (eval 12) line 1, <DATA> line 87.\nIllegal declaration of anonymous subroutine at (eval 12) line 1, at EOF\n'
# expected /(?^:^Illegal declaration of anonymous subroutine at)/
- t/lib/croak.t
FILE: lib/croak/toke ; line 644
PROG:
no feature 'apostrophe_as_package_separator';
sub 'Hello'_he_said (_);
EXPECTED:
Illegal declaration of anonymous subroutine at - line 2.
EXIT STATUS: != 0
GOT:
Bareword found where operator expected (Missing operator before "_he_said"?) at - line 2, near "'Hello'_he_said"
Illegal declaration of anonymous subroutine at - line 2, near "sub 'Hello'"
Execution of - aborted due to compilation errors.
EXIT STATUS: 255
not ok 247 - tick in names: initial character of sub name (no feature)
# Failed test 247 - tick in names: initial character of sub name (no feature) at lib/croak/toke line 644
Since we don't immediately error out from the lexer anymore, the parser
may accumulate more errors before failing with "Illegal declaration of
anonymous subroutine".
The tests have been changed to accomodate the new diagnostics.
Fixes#5959.
Provide a subsignature_*() API
Added:
* subsignature_start()
* subsignature_append_slurpy()
* subsignature_append_positional()
* subsignature_finish()
Call these from code blocks in perly.y
Make the actual parser signature struct opaque, hidden in toke.c. This
gives it much more robustness against future modifications.
As these only permit `any BLOCK LIST` and not the deferred-expression
form like `grep EXPR, LIST`, we create a whole new token type, BLKLSTOP,
to represent these. The parser then only accepts the block form and not
the expression form when parsing these.
The idea behind this code was to find the big enum block in perlytmp.h
that looks like:
enum yytokentype {
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
GRAMPROG = 258, /* GRAMPROG */
GRAMEXPR = 259, /* GRAMEXPR */
GRAMBLOCK = 260, /* GRAMBLOCK */
...
};
... and append to it (in perly.h) a series of equivalent macro
definitions, one for each (non-negative) enum symbol:
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
#define GRAMPROG 258
#define GRAMEXPR 259
#define GRAMBLOCK 260
...
However, due to slight formatting changes in the code generated by bison
3+, this code has been essentially dead because the starting regex
didn't match anymore, so $gather_tokens was never set to a true value.
The last time we had token macros in perly.h was before commit
a9f5ab8de628 (in 2016), in which I generated perly.h using bison 3 for
the first time (without noticing the disappearance of the token macros).
We could try to fix the regex logic in regen_perly.pl, but given that no
one has complained about the missing token macros in 8 years (as far as
I know), let's just remove the code. (Yay, accidental scream tests?)
The reeproducer resulted in the "block" OP being both on the parser
stack and attacked to the CV. If an error occurred while parsing the
rest of the list operator clean up would release the OP as attached
to the CV, and the same OP on the parse stack, resulting in a double
free.
It's unclear to me whether bison is intended to support modifying
the parse stack entry like this, but it appears to work here.
Fixes#21724
Previously, the low-precedence `xor` operator did not have a
higher-precedence logical variant, as compared `or` vs `||` and
`and` vs `&&`. This PR adds such an operator syntax, completing the
set.