⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deparse.pm

📁 Altera recommends the following system configuration: * Pentium II 400 with 512-MB system memory (fa
💻 PM
📖 第 1 页 / 共 5 页
字号:
	}	$line =~ s/\cK;?//g;    }    return join("\n", @lines);}sub deparse_sub {    my $self = shift;    my $cv = shift;    my $proto = "";    if ($cv->FLAGS & SVf_POK) {	$proto = "(". $cv->PV . ") ";    }    if ($cv->CvFLAGS & (CVf_METHOD|CVf_LOCKED|CVf_LVALUE)) {        $proto .= ": ";        $proto .= "lvalue " if $cv->CvFLAGS & CVf_LVALUE;        $proto .= "locked " if $cv->CvFLAGS & CVf_LOCKED;        $proto .= "method " if $cv->CvFLAGS & CVf_METHOD;    }    local($self->{'curcv'}) = $cv;    local($self->{'curstash'}) = $self->{'curstash'};    if (not null $cv->ROOT) {	# skip leavesub	return $proto . "{\n\t" . 	    $self->deparse($cv->ROOT->first, 0) . "\n\b}\n";     } else { # XSUB?	return $proto  . "{}\n";    }}sub deparse_format {    my $self = shift;    my $form = shift;    my @text;    local($self->{'curcv'}) = $form;    local($self->{'curstash'}) = $self->{'curstash'};    my $op = $form->ROOT;    my $kid;    $op = $op->first->first; # skip leavewrite, lineseq    while (not null $op) {	$op = $op->sibling; # skip nextstate	my @exprs;	$kid = $op->first->sibling; # skip pushmark	push @text, $self->const_sv($kid)->PV;	$kid = $kid->sibling;	for (; not null $kid; $kid = $kid->sibling) {	    push @exprs, $self->deparse($kid, 0);	}	push @text, join(", ", @exprs)."\n" if @exprs;	$op = $op->sibling;    }    return join("", @text) . ".";}sub is_scope {    my $op = shift;    return $op->name eq "leave" || $op->name eq "scope"      || $op->name eq "lineseq"	|| ($op->name eq "null" && class($op) eq "UNOP" 	    && (is_scope($op->first) || $op->first->name eq "enter"));}sub is_state {    my $name = $_[0]->name;    return $name eq "nextstate" || $name eq "dbstate" || $name eq "setstate";}sub is_miniwhile { # check for one-line loop (`foo() while $y--')    my $op = shift;    return (!null($op) and null($op->sibling) 	    and $op->name eq "null" and class($op) eq "UNOP"	    and (($op->first->name =~ /^(and|or)$/		  and $op->first->first->sibling->name eq "lineseq")		 or ($op->first->name eq "lineseq"		     and not null $op->first->first->sibling		     and $op->first->first->sibling->name eq "unstack")		 ));}sub is_scalar {    my $op = shift;    return ($op->name eq "rv2sv" or	    $op->name eq "padsv" or	    $op->name eq "gv" or # only in array/hash constructs	    $op->flags & OPf_KIDS && !null($op->first)	      && $op->first->name eq "gvsv");}sub maybe_parens {    my $self = shift;    my($text, $cx, $prec) = @_;    if ($prec < $cx              # unary ops nest just fine	or $prec == $cx and $cx != 4 and $cx != 16 and $cx != 21	or $self->{'parens'})    {	$text = "($text)";	# In a unop, let parent reuse our parens; see maybe_parens_unop	$text = "\cS" . $text if $cx == 16;	return $text;    } else {	return $text;    }}# same as above, but get around the `if it looks like a function' rulesub maybe_parens_unop {    my $self = shift;    my($name, $kid, $cx) = @_;    if ($cx > 16 or $self->{'parens'}) {	return "$name(" . $self->deparse($kid, 1) . ")";    } else {	$kid = $self->deparse($kid, 16);	if (substr($kid, 0, 1) eq "\cS") {	    # use kid's parens	    return $name . substr($kid, 1);	} elsif (substr($kid, 0, 1) eq "(") {	    # avoid looks-like-a-function trap with extra parens	    # (`+' can lead to ambiguities)	    return "$name(" . $kid  . ")";	} else {	    return "$name $kid";	}    }}sub maybe_parens_func {    my $self = shift;    my($func, $text, $cx, $prec) = @_;    if ($prec <= $cx or substr($text, 0, 1) eq "(" or $self->{'parens'}) {	return "$func($text)";    } else {	return "$func $text";    }}sub maybe_local {    my $self = shift;    my($op, $cx, $text) = @_;    if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {        if (want_scalar($op)) {	    return "local $text";	} else {	    return $self->maybe_parens_func("local", $text, $cx, 16);	}    } else {	return $text;    }}sub maybe_targmy {    my $self = shift;    my($op, $cx, $func, @args) = @_;    if ($op->private & OPpTARGET_MY) {	my $var = $self->padname($op->targ);	my $val = $func->($self, $op, 7, @args);	return $self->maybe_parens("$var = $val", $cx, 7);    } else {	return $func->($self, $op, $cx, @args);    }}sub padname_sv {    my $self = shift;    my $targ = shift;    return (($self->{'curcv'}->PADLIST->ARRAY)[0]->ARRAY)[$targ];}sub maybe_my {    my $self = shift;    my($op, $cx, $text) = @_;    if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {	if (want_scalar($op)) {	    return "my $text";	} else {	    return $self->maybe_parens_func("my", $text, $cx, 16);	}    } else {	return $text;    }}# The following OPs don't have functions:# pp_padany -- does not exist after parsing# pp_rcatline -- does not existsub pp_enter { # see also leave    cluck "unexpected OP_ENTER";    return "XXX";}sub pp_pushmark { # see also list    cluck "unexpected OP_PUSHMARK";    return "XXX";}sub pp_leavesub { # see also deparse_sub    cluck "unexpected OP_LEAVESUB";    return "XXX";}sub pp_leavewrite { # see also deparse_format    cluck "unexpected OP_LEAVEWRITE";    return "XXX";}sub pp_method { # see also entersub    cluck "unexpected OP_METHOD";    return "XXX";}sub pp_regcmaybe { # see also regcomp    cluck "unexpected OP_REGCMAYBE";    return "XXX";}sub pp_regcreset { # see also regcomp    cluck "unexpected OP_REGCRESET";    return "XXX";}sub pp_substcont { # see also subst    cluck "unexpected OP_SUBSTCONT";    return "XXX";}sub pp_grepstart { # see also grepwhile    cluck "unexpected OP_GREPSTART";    return "XXX";}sub pp_mapstart { # see also mapwhile    cluck "unexpected OP_MAPSTART";    return "XXX";}sub pp_flip { # see also flop    cluck "unexpected OP_FLIP";    return "XXX";}sub pp_iter { # see also leaveloop    cluck "unexpected OP_ITER";    return "XXX";}sub pp_enteriter { # see also leaveloop    cluck "unexpected OP_ENTERITER";    return "XXX";}sub pp_enterloop { # see also leaveloop    cluck "unexpected OP_ENTERLOOP";    return "XXX";}sub pp_leaveeval { # see also entereval    cluck "unexpected OP_LEAVEEVAL";    return "XXX";}sub pp_entertry { # see also leavetry    cluck "unexpected OP_ENTERTRY";    return "XXX";}sub lineseq {    my $self = shift;    my(@ops) = @_;    my($expr, @exprs);    for (my $i = 0; $i < @ops; $i++) {	$expr = "";	if (is_state $ops[$i]) {	    $expr = $self->deparse($ops[$i], 0);	    $i++;	    last if $i > $#ops;	}	if (!is_state $ops[$i] and $ops[$i+1] and !null($ops[$i+1]) and	    $ops[$i+1]->name eq "leaveloop" and $self->{'expand'} < 3)	{	    push @exprs, $expr . $self->for_loop($ops[$i], 0);	    $i++;	    next;	}	$expr .= $self->deparse($ops[$i], 0);	push @exprs, $expr if length $expr;    }    return join(";\n", @exprs);}sub scopeop {    my($real_block, $self, $op, $cx) = @_;    my $kid;    my @kids;    local($self->{'curstash'}) = $self->{'curstash'} if $real_block;    if ($real_block) {	$kid = $op->first->sibling; # skip enter	if (is_miniwhile($kid)) {	    my $top = $kid->first;	    my $name = $top->name;	    if ($name eq "and") {		$name = "while";	    } elsif ($name eq "or") {		$name = "until";	    } else { # no conditional -> while 1 or until 0		return $self->deparse($top->first, 1) . " while 1";	    }	    my $cond = $top->first;	    my $body = $cond->sibling->first; # skip lineseq	    $cond = $self->deparse($cond, 1);	    $body = $self->deparse($body, 1);	    return "$body $name $cond";	}    } else {	$kid = $op->first;    }    for (; !null($kid); $kid = $kid->sibling) {	push @kids, $kid;    }    if ($cx > 0) { # inside an expression, (a do {} while for lineseq)	return "do { " . $self->lineseq(@kids) . " }";    } else {	return $self->lineseq(@kids) . ";";    }}sub pp_scope { scopeop(0, @_); }sub pp_lineseq { scopeop(0, @_); }sub pp_leave { scopeop(1, @_); }# The BEGIN {} is used here because otherwise this code isn't executed# when you run B::Deparse on itself.my %globalnames;BEGIN { map($globalnames{$_}++, "SIG", "STDIN", "STDOUT", "STDERR", "INC",	    "ENV", "ARGV", "ARGVOUT", "_"); }sub gv_name {    my $self = shift;    my $gv = shift;    my $stash = $gv->STASH->NAME;    my $name = $gv->SAFENAME;    if ($stash eq $self->{'curstash'} or $globalnames{$name}	or $name =~ /^[^A-Za-z_]/)    {	$stash = "";    } else {	$stash = $stash . "::";    }    if ($name =~ /^\^../) {        $name = "{$name}";       # ${^WARNING_BITS} etc    }    return $stash . $name;}# Notice how subs and formats are inserted between statements heresub pp_nextstate {    my $self = shift;    my($op, $cx) = @_;    my @text;    @text = $op->label . ": " if $op->label;    my $seq = $op->cop_seq;    while (scalar(@{$self->{'subs_todo'}})	   and $seq > $self->{'subs_todo'}[0][0]) {	push @text, $self->next_todo;    }    my $stash = $op->stashpv;    if ($stash ne $self->{'curstash'}) {	push @text, "package $stash;\n";	$self->{'curstash'} = $stash;    }    if ($self->{'linenums'}) {	push @text, "\f#line " . $op->line . 	  ' "' . $op->file, qq'"\n';    }    return join("", @text);}sub pp_dbstate { pp_nextstate(@_) }sub pp_setstate { pp_nextstate(@_) }sub pp_unstack { return "" } # see also leaveloopsub baseop {    my $self = shift;    my($op, $cx, $name) = @_;    return $name;}sub pp_stub { baseop(@_, "()") }sub pp_wantarray { baseop(@_, "wantarray") }sub pp_fork { baseop(@_, "fork") }sub pp_wait { maybe_targmy(@_, \&baseop, "wait") }sub pp_getppid { maybe_targmy(@_, \&baseop, "getppid") }sub pp_time { maybe_targmy(@_, \&baseop, "time") }sub pp_tms { baseop(@_, "times") }sub pp_ghostent { baseop(@_, "gethostent") }sub pp_gnetent { baseop(@_, "getnetent") }sub pp_gprotoent { baseop(@_, "getprotoent") }sub pp_gservent { baseop(@_, "getservent") }sub pp_ehostent { baseop(@_, "endhostent") }sub pp_enetent { baseop(@_, "endnetent") }sub pp_eprotoent { baseop(@_, "endprotoent") }sub pp_eservent { baseop(@_, "endservent") }sub pp_gpwent { baseop(@_, "getpwent") }sub pp_spwent { baseop(@_, "setpwent") }sub pp_epwent { baseop(@_, "endpwent") }sub pp_ggrent { baseop(@_, "getgrent") }sub pp_sgrent { baseop(@_, "setgrent") }sub pp_egrent { baseop(@_, "endgrent") }sub pp_getlogin { baseop(@_, "getlogin") }sub POSTFIX () { 1 }# I couldn't think of a good short name, but this is the category of# symbolic unary operators with interesting precedencesub pfixop {    my $self = shift;    my($op, $cx, $name, $prec, $flags) = (@_, 0);    my $kid = $op->first;    $kid = $self->deparse($kid, $prec);    return $self->maybe_parens(($flags & POSTFIX) ? "$kid$name" : "$name$kid",			       $cx, $prec);}sub pp_preinc { pfixop(@_, "++", 23) }sub pp_predec { pfixop(@_, "--", 23) }sub pp_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }sub pp_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }sub pp_i_preinc { pfixop(@_, "++", 23) }sub pp_i_predec { pfixop(@_, "--", 23) }sub pp_i_postinc { maybe_targmy(@_, \&pfixop, "++", 23, POSTFIX) }sub pp_i_postdec { maybe_targmy(@_, \&pfixop, "--", 23, POSTFIX) }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -