File Coverage

blib/lib/Devel/Chitin/OpTree/LOGOP.pm
Criterion Covered Total %
statement 74 77 96.1
branch 24 26 92.3
condition 14 21 66.6
subroutine 18 19 94.7
pod 0 13 0.0
total 130 156 83.3


line stmt bran cond sub pod time code
1             package Devel::Chitin::OpTree::LOGOP;
2 35     35   250 use base 'Devel::Chitin::OpTree::UNOP';
  35         64  
  35         4682  
3              
4             our $VERSION = '0.16';
5              
6 35     35   188 use strict;
  35         59  
  35         678  
7 35     35   147 use warnings;
  35         53  
  35         32794  
8              
9             sub other {
10 44     44 0 146 shift->{children}->[1];
11             }
12              
13 0     0 0 0 sub pp_entertry { '' }
14              
15             sub pp_regcomp {
16 7     7 0 16 my $self = shift;
17 7         32 my %params = @_;
18              
19 7         28 my $rx_op = $self->first;
20 7         25 my $rx_op_name = $rx_op->op->name;
21 7 100 66     49 $rx_op = $rx_op->first if ($rx_op_name eq 'regcmaybe'
22             or $rx_op_name eq 'regcreset');
23              
24 7         16 my $deparsed;
25 7         53 join('', $rx_op->deparse(skip_parens => 1,
26             skip_quotes => 1,
27             skip_concat => 1,
28             join_with => '',
29             %params));
30             }
31              
32             sub pp_substcont {
33 1     1 0 4 my $self = shift;
34 1         4 join('', $self->first->deparse(skip_concat => 1, skip_quotes => 1));
35             }
36              
37             # The arrangement looks like this
38             # mapwhile
39             # mapstart
40             # padrange
41             # null
42             # block-or-expr
43             # ...
44             # list-0
45             # list-1
46             # ...
47             sub pp_mapwhile {
48 4     4 0 13 _deparse_map_grep(shift, 'map');
49             }
50              
51             sub pp_grepwhile {
52 4     4 0 15 _deparse_map_grep(shift, 'grep');
53             }
54              
55             sub _deparse_map_grep {
56 8     8   22 my($self, $function) = @_;
57              
58 8         24 my $mapstart = $self->first;
59 8         28 my $children = $mapstart->children;
60              
61 8         22 my $block_or_expr = $mapstart->children->[1]->first;
62 8 100       24 $block_or_expr = $block_or_expr->first if $block_or_expr->is_null;
63              
64 8         31 my @map_params = map { $_->deparse } @$children[2 .. $#$children];
  12         39  
65 8 100       29 if ($block_or_expr->is_scopelike) {
66             # map { ... } @list
67 4   66     25 my $use_parens = (@map_params > 1 or substr($map_params[0], 0, 1) ne '@');
68              
69 4 100       17 "${function} " . $block_or_expr->deparse . ' '
    100          
70             . ($use_parens ? '(' : '')
71             . join(', ', @map_params)
72             . ($use_parens ? ')' : '');
73              
74             } else {
75             # map(expr, @list)
76              
77 4         18 "${function}("
78             . $block_or_expr->deparse
79             . ', '
80             . join(', ', @map_params)
81             . ')';
82             }
83             }
84              
85             sub pp_and {
86 8     8 0 17 my $self = shift;
87 8         21 my $left = $self->first->deparse;
88 8         28 my $right = $self->other->deparse(force_multiline => 1);
89 8 100       31 if ($self->is_if_statement) {
    100          
90 3         11 $left = _format_if_conditional($left);
91 3         17 "if ($left) $right";
92              
93             } elsif ($self->is_postfix_if) {
94 1         6 "$right if $left";
95              
96             } else {
97 4         21 "$left && $right";
98             }
99             }
100              
101             sub pp_or {
102 4     4 0 8 my $self = shift;
103 4 100       11 if ($self->is_if_statement) {
    100          
104 1         2 my $condition;
105 1 50 33     12 if ($self->first->is_null
106             and $self->first->_ex_name eq 'pp_not'
107             ) {
108             # starting with 5.12
109 0         0 $condition = $self->first->first->deparse;
110             } else {
111             # perl 5.10.1 and older
112 1         4 $condition = $self->first->deparse;
113             }
114 1         3 $condition = _format_if_conditional($condition);
115 1         3 my $code = $self->other->deparse(force_multiline => 1);
116 1         5 "unless ($condition) $code";
117              
118             } elsif ($self->is_postfix_if) {
119 1         12 $self->other->deparse . ' unless ' . $self->first->deparse;
120              
121             } else {
122 2         5 $self->first->deparse . ' || ' . $self->other->deparse;
123             }
124             }
125              
126             sub pp_dor {
127 1     1 0 4 my $self = shift;
128 1         6 $self->first->deparse . ' // ' . $self->other->deparse;
129             }
130              
131             sub _format_if_conditional {
132 10     10   13 my $code = shift;
133 10 50       27 if (index($code, ';') == 0) {
134 0         0 substr($code, 1);
135             } else {
136 10         20 $code;
137             }
138             }
139              
140 1     1 0 7 sub pp_andassign { _and_or_assign(shift, '&&=') }
141 1     1 0 6 sub pp_orassign { _and_or_assign(shift, '||=') }
142 1     1 0 5 sub pp_dorassign { _and_or_assign(shift, '//=') }
143             sub _and_or_assign {
144 3     3   9 my($self, $op) = @_;
145 3         23 my $var = $self->first->deparse;
146 3         17 my $value = $self->other->first->deparse; # skip over sassign (other)
147 3         21 join(' ', $var, $op, $value);
148             }
149              
150             sub pp_cond_expr {
151 7     7 0 14 my $self = shift;
152 7         18 my $children = $self->children;
153              
154 7         18 my($cond, $true, $false) = @$children;
155 7         19 my $cond_code = $cond->deparse();
156 7         21 my $true_code = $true->deparse(force_multiline => 1);
157 7         19 my $false_code = $false->deparse(force_multiline => 1);
158              
159 7 100 100     18 if ($true->is_scopelike and $false->is_scopelike) {
    100 66        
      66        
      66        
160 2         7 $cond_code = _format_if_conditional($cond_code);
161 2         12 "if ($cond_code) $true_code else $false_code";
162              
163             } elsif ($true->is_scopelike
164             and $false->is_null
165             and ( $false->first->op->name eq 'cond_expr' or $false->first->op->name eq 'and' )
166             ) {
167 4         10 $cond_code = _format_if_conditional($cond_code);
168 4         25 "if ($cond_code) $true_code els$false_code";
169              
170             } else {
171 1         7 $cond->deparse . ' ? ' . $true->deparse . ' : ' . $false->deparse;
172             }
173             }
174              
175             1;
176              
177             __END__