view release on metacpan or search on metacpan
doc/OLD_CHANGES.md view on Meta::CPAN
* support for method attributes was added
* some warnings fixed
* separate recognition of constant subs
* rewrote continue block handling, now recognizing for loops
* added more control of expanding control structures
# Changes between 0.60 and 0.61 (mostly by Robin Houston)
* many bug-fixes
* support for pragmas and 'use'
* support for the little-used $[ variable
* support for `__DATA__` sections
* UTF-8 support
* `BEGIN`, `CHECK`, `INIT` and `END` blocks
* scoping of subroutine declarations fixed
* compile-time output from the input program can be suppressed, so that the output is just the deparsed code. (a change to O.pm in fact)
* `our()` declarations
* *all* the known bugs are now listed in the BUGS section
* comprehensive test mechanism (TEST -deparse)
# Changes between 0.62 and 0.63 (mostly by Rafael Garcia-Suarez)
lib/B/DeparseTree/P518.pm view on Meta::CPAN
# Like dq(), but different
sub re_dq {
my $self = shift;
my ($op, $extended) = @_;
my ($re_dq_info, $fmt);
my $type = $op->name;
my ($re, @texts);
my $opts = {};
if ($type eq "const") {
return info_from_text($op, $self, '$[', 're_dq_const', {})
if $op->private & OPpCONST_ARYBASE;
my $unbacked = B::Deparse::re_unback($self->const_sv($op)->as_string);
return B::Deparse::re_uninterp_extended(escape_extended_re($unbacked))
if $extended;
return B::Deparse::re_uninterp(B::Deparse::escape_str($unbacked));
} elsif ($type eq "concat") {
my $first = $self->re_dq($op->first, $extended);
my $last = $self->re_dq($op->last, $extended);
return B::Deparse::re_dq_disambiguate($first, $last);
} elsif ($type eq "uc") {
lib/B/DeparseTree/P522.pm view on Meta::CPAN
# Like dq(), but different
sub re_dq {
my $self = shift;
my ($op, $extended) = @_;
my ($re_dq_info, $fmt);
my $type = $op->name;
my ($re, @texts);
my $opts = {};
if ($type eq "const") {
return info_from_text($op, $self, '$[', 're_dq_const', {})
if $op->private & OPpCONST_ARYBASE;
my $unbacked = B::Deparse::re_unback($self->const_sv($op)->as_string);
return B::Deparse::re_uninterp_extended(escape_extended_re($unbacked))
if $extended;
return B::Deparse::re_uninterp(B::Deparse::escape_str($unbacked));
} elsif ($type eq "concat") {
my $first = $self->re_dq($op->first, $extended);
my $last = $self->re_dq($op->last, $extended);
return B::Deparse::re_dq_disambiguate($first, $last);
} elsif ($type eq "uc") {
lib/B/DeparseTree/P526.pm view on Meta::CPAN
}
# Like dq(), but different
sub re_dq {
my $self = shift;
my ($op) = @_;
my ($re_dq_info, $fmt);
my $type = $op->name;
if ($type eq "const") {
return '$[' if $op->private & OPpCONST_ARYBASE;
my $unbacked = B::Deparse::re_unback($self->const_sv($op)->as_string);
return B::Deparse::re_uninterp(escape_re($unbacked));
} elsif ($type eq "concat") {
my $first = $self->re_dq($op->first);
my $last = $self->re_dq($op->last);
return B::Deparse::re_dq_disambiguate($first, $last);
} elsif ($type eq "uc") {
$re_dq_info = $self->re_dq($op->first->sibling);
$fmt = '\U%c\E';
$type .= ' uc';
lib/B/DeparseTree/P526c.pm view on Meta::CPAN
}
# Like dq(), but different
sub re_dq {
my $self = shift;
my ($op) = @_;
my ($re_dq_info, $fmt);
my $type = $op->name;
if ($type eq "const") {
return '$[' if $op->private & OPpCONST_ARYBASE;
my $unbacked = B::Deparse::re_unback($self->const_sv($op)->as_string);
return B::Deparse::re_uninterp(escape_re($unbacked));
} elsif ($type eq "concat") {
my $first = $self->re_dq($op->first);
my $last = $self->re_dq($op->last);
return B::Deparse::re_dq_disambiguate($first, $last);
} elsif ($type eq "uc") {
$re_dq_info = $self->re_dq($op->first->sibling);
$fmt = '\U%c\E';
$type .= ' uc';
lib/B/DeparseTree/PP.pm view on Meta::CPAN
push @exprs, $false_info;
$type .= ' else';
}
return $self->info_from_template($type, $op, $fmt, \@args_spec, \@exprs);
}
sub pp_const {
my $self = shift;
my($op, $cx) = @_;
if ($op->private & OPpCONST_ARYBASE) {
return $self->info_from_string('const $[', $op, '$[');
}
# if ($op->private & OPpCONST_BARE) { # trouble with '=>' autoquoting
# return $self->const_sv($op)->PV;
# }
my $sv = $self->const_sv($op);
return $self->const($sv, $cx);;
}
# Handle subroutine calls. These are a bit complicated.
# NOTE: this is not right for CPerl, so it needs to be split out.
lib/B/DeparseTree/PPfns.pm view on Meta::CPAN
}
elsif (ref $val) {
@names = @$val;
}
else {
@names = split' ', $val;
}
$hint_bits |= $strict_bits{$_} for @names;
}
elsif ($name eq '$[') {
if (OPpCONST_ARYBASE) {
$arybase = $val;
} else {
croak "\$[ can't be non-zero on this perl" unless $val == 0;
}
}
elsif ($name eq 'integer'
|| $name eq 'bytes'
|| $name eq 'utf8') {
require "$name.pm";
if ($val) {
$hint_bits |= ${$::{"${name}::"}{"hint_bits"}};
}
lib/B/DeparseTree/PPfns.pm view on Meta::CPAN
my $lhs = $self->deparse_binop_left($op, $left, $prec);
my $rhs = $self->deparse_binop_right($op, $right, $prec);
return $self->info_from_template(".$eq", $op,
"%c .$eq %c", undef, [$lhs, $rhs],
{maybe_parens => [$self, $cx, $prec]});
}
# Handle pp_dbstate, and pp_nextstate and COP ops.
#
# Notice how subs and formats are inserted between statements here;
# also $[ assignments and pragmas.
sub cops
{
my ($self, $op, $cx, $name) = @_;
$self->{'curcop'} = $op;
my @texts = ();
my $opts = {};
my @args_spec = ();
my $fmt = '%;';
lib/B/DeparseTree/PPfns.pm view on Meta::CPAN
$opts->{'omit_next_semicolon'} = 1;
}
my $stash = $op->stashpv;
if ($stash ne $self->{'curstash'}) {
push @texts, $self->keyword("package") . " $stash;";
$self->{'curstash'} = $stash;
}
if (OPpCONST_ARYBASE && $self->{'arybase'} != $op->arybase) {
push @texts, '$[ = '. $op->arybase .";";
$self->{'arybase'} = $op->arybase;
}
my $warnings = $op->warnings;
my $warning_bits;
if ($warnings->isa("B::SPECIAL") && $$warnings == 4) {
$warning_bits = $warnings::Bits{"all"} & WARN_MASK;
}
elsif ($warnings->isa("B::SPECIAL") && $$warnings == 5) {
$warning_bits = $warnings::NONE;
lib/B/DeparseTree/PPfns.pm view on Meta::CPAN
return "/$from/$to/";
}
}
sub dq($$$)
{
my ($self, $op, $parent) = @_;
my $type = $op->name;
my $info;
if ($type eq "const") {
return info_from_text($op, $self, '$[', 'dq constant ary', {}) if $op->private & OPpCONST_ARYBASE;
return info_from_text($op, $self,
B::Deparse::uninterp(B::Deparse::escape_str(B::Deparse::unback($self->const_sv($op)->as_string))),
'dq constant', {});
} elsif ($type eq "concat") {
my $first = $self->dq($op->first, $op);
my $last = $self->dq($op->last, $op);
# FIXME: convert to newer conventions
# Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]", "$foo\::bar"
($last->{text} =~ /^[A-Z\\\^\[\]_?]/ &&
lib/B/DeparseTree/PPfns.pm view on Meta::CPAN
Carp::confess("unhandled condition in maybe_parens_unop");
}
sub maybe_qualify {
my ($self,$prefix,$name) = @_;
my $v = ($prefix eq '$#' ? '@' : $prefix) . $name;
return $name if !$prefix || $name =~ /::/;
return $self->{'curstash'}.'::'. $name
if
$name =~ /^(?!\d)\w/ # alphabetic
&& $v !~ /^\$[ab]\z/ # not $a or $b
&& !$globalnames{$name} # not a global name
&& $self->{hints} & $strict_bits{vars} # strict vars
&& !$self->B::Deparse::lex_in_scope($v,1) # no "our"
or $self->B::Deparse::lex_in_scope($v); # conflicts with "my" variable
return $name;
}
# FIXME: need a way to pass in skipped_ops
# FIXME: see if we can move to some 5.xx-specific module
sub maybe_targmy
lib/B/DeparseTree/TreeMain.pm view on Meta::CPAN
my @text;
my $stash = $op->stashpv;
if ($stash ne $self->{'curstash'}) {
push @text, $self->keyword("package") . " $stash;\n";
$self->{'curstash'} = $stash;
}
if (OPpCONST_ARYBASE && $self->{'arybase'} != $op->arybase) {
push @text, '$[ = '. $op->arybase .";\n";
$self->{'arybase'} = $op->arybase;
}
my $warnings = $op->warnings;
my $warning_bits;
if ($warnings->isa("B::SPECIAL") && $$warnings == 4) {
$warning_bits = $warnings::Bits{"all"} & WARN_MASK;
}
elsif ($warnings->isa("B::SPECIAL") && $$warnings == 5) {
$warning_bits = $warnings::NONE;