File Coverage

blib/lib/Language/Expr/Compiler/perl.pm
Criterion Covered Total %
statement 782 797 98.1
branch 95 138 68.8
condition 13 25 52.0
subroutine 197 197 100.0
pod 2 33 6.0
total 1089 1190 91.5


line stmt bran cond sub pod time code
1             package Language::Expr::Compiler::perl;
2              
3             our $DATE = '2016-06-29'; # DATE
4             our $VERSION = '0.27'; # VERSION
5              
6 2     2   53 use 5.010;
  2         4  
7 2     2   6 use strict;
  2         3  
  2         36  
8 2     2   7 use warnings;
  2         2  
  2         47  
9              
10 2     2   725 use Role::Tiny::With;
  2         6862  
  2         103  
11 2     2   722 use parent 'Language::Expr::Compiler::Base';
  2         464  
  2         10  
12             with 'Language::Expr::CompilerRole';
13              
14 2     2   465 use boolean;
  2         743  
  2         9  
15              
16             sub rule_pair_simple {
17 10     10 0 18 my ($self, %args) = @_;
18 10         15 my $match = $args{match};
19 10         209 "$match->{key} => $match->{value}";
20             }
21              
22             sub rule_pair_string {
23 6     6 0 10 my ($self, %args) = @_;
24 6         11 my $match = $args{match};
25 6         122 "$match->{key} => $match->{value}";
26             }
27              
28             sub rule_or_xor {
29 8     8 0 15 my ($self, %args) = @_;
30 8         7 my $match = $args{match};
31 8         8 my @res;
32 8         7 push @res, shift @{$match->{operand}};
  8         17  
33 8         9 for my $term (@{$match->{operand}}) {
  8         14  
34 8   50     7 my $op = shift @{$match->{op}//=[]};
  8         22  
35 8 50       13 last unless $op;
36 8 100       15 if ($op eq '||') { push @res, " || $term" }
  4 50       12  
    0          
37 4         10 elsif ($op eq '//') { push @res, " // $term" }
38             # add parenthesis because perl's xor precendence is low
39 0         0 elsif ($op eq '^^') { @res = ("(", @res, " xor $term)") }
40             }
41 8         10 join "", grep {defined} @res;
  16         187  
42             }
43              
44             sub rule_and {
45 4     4 0 9 my ($self, %args) = @_;
46 4         4 my $match = $args{match};
47 4         6 my @res;
48 4         4 push @res, shift @{$match->{operand}};
  4         9  
49 4         6 for my $term (@{$match->{operand}}) {
  4         8  
50 4   50     4 my $op = shift @{$match->{op}//=[]};
  4         12  
51 4 50       8 last unless $op;
52 4 50       9 if ($op eq '&&') { @res = ("((", @res, " && $term) || false)") }
  4         20  
53             }
54 4         7 join "", grep {defined} @res;
  12         108  
55             }
56              
57             sub rule_ternary {
58 10     10 0 19 my ($self, %args) = @_;
59 10         10 my $match = $args{match};
60 10         11 my $opd = $match->{operand};
61 10         219 "$opd->[0] ? $opd->[1] : $opd->[2]";
62             }
63              
64             sub rule_bit_or_xor {
65 2     2 0 3 my ($self, %args) = @_;
66 2         15 my $match = $args{match};
67 2         2 my @res;
68 2         2 push @res, shift @{$match->{operand}};
  2         6  
69 2         3 for my $term (@{$match->{operand}}) {
  2         6  
70 2   50     2 my $op = shift @{$match->{op}//=[]};
  2         5  
71 2 50       6 last unless $op;
72 2 100       7 if ($op eq '|') { push @res, " | $term" }
  1 50       3  
73 1         4 elsif ($op eq '^') { push @res, " ^ $term" }
74             }
75 2         3 join "", grep {defined} @res;
  4         49  
76             }
77              
78             sub rule_bit_and {
79 1     1 0 2 my ($self, %args) = @_;
80 1         2 my $match = $args{match};
81 1         2 my @res;
82 1         1 push @res, shift @{$match->{operand}};
  1         2  
83 1         1 for my $term (@{$match->{operand}}) {
  1         2  
84 1   50     1 my $op = shift @{$match->{op}//=[]};
  1         4  
85 1 50       3 last unless $op;
86 1 50       3 if ($op eq '&') { push @res, " & $term" }
  1         3  
87             }
88 1         2 join "", grep {defined} @res;
  2         23  
89             }
90              
91             sub rule_comparison3 {
92 29     29 0 49 my ($self, %args) = @_;
93 29         34 my $match = $args{match};
94 29         35 my @res;
95 29         25 push @res, shift @{$match->{operand}};
  29         69  
96 29         27 for my $term (@{$match->{operand}}) {
  29         66  
97 29   50     20 my $op = shift @{$match->{op}//=[]};
  29         72  
98 29 50       49 last unless $op;
99 29 100       63 if ($op eq '<=>') { push @res, " <=> $term" }
  22 50       56  
100 7         19 elsif ($op eq 'cmp') { push @res, " cmp $term" }
101             }
102 29         39 join "", grep {defined} @res;
  58         667  
103             }
104              
105             sub rule_comparison {
106 53     53 0 82 my ($self, %args) = @_;
107 53         59 my $match = $args{match};
108 53         53 my @opds;
109 53         41 push @opds, shift @{$match->{operand}};
  53         104  
110 53 50       87 return '' unless defined $opds[0];
111 53         40 my @ops;
112 53         48 for my $term (@{$match->{operand}}) {
  53         103  
113 60         45 push @opds, $term;
114 60   50     43 my $op = shift @{$match->{op}//=[]};
  60         126  
115 60 50       102 last unless $op;
116 60 100       226 if ($op eq '==' ) { push @ops, '==' }
  17 100       28  
    100          
    50          
    100          
    100          
    100          
    50          
    0          
    0          
    0          
    0          
117 4         7 elsif ($op eq '!=' ) { push @ops, '!=' }
118 3         4 elsif ($op eq 'eq' ) { push @ops, 'eq' }
119 0         0 elsif ($op eq 'ne' ) { push @ops, 'ne' }
120 4         7 elsif ($op eq '<' ) { push @ops, '<' }
121 3         5 elsif ($op eq '<=' ) { push @ops, '<=' }
122 24         35 elsif ($op eq '>' ) { push @ops, '>' }
123 5         10 elsif ($op eq '>=' ) { push @ops, '>=' }
124 0         0 elsif ($op eq 'lt' ) { push @ops, 'lt' }
125 0         0 elsif ($op eq 'le' ) { push @ops, 'le' }
126 0         0 elsif ($op eq 'gt' ) { push @ops, 'gt' }
127 0         0 elsif ($op eq 'ge' ) { push @ops, 'ge' }
128             }
129 53 50       99 return $opds[0] unless @ops;
130 53         49 my @res;
131             my $lastopd;
132 0         0 my ($opd1, $opd2);
133 53         101 while (@ops) {
134 60         73 my $op = pop @ops;
135 60 100       82 if (defined($lastopd)) {
136 7         8 $opd2 = $lastopd;
137 7         8 $opd1 = pop @opds;
138             } else {
139 53         48 $opd2 = pop @opds;
140 53         50 $opd1 = pop @opds;
141             }
142 60 100       80 if (@res) {
143 7         20 @res = ("(($opd1 $op $opd2) ? ", @res, " : false)");
144             } else {
145 53         123 push @res, "($opd1 $op $opd2 ? true:false)";
146             }
147 60         113 $lastopd = $opd1;
148             }
149 53         1181 join "", @res;
150             }
151              
152             sub rule_bit_shift {
153 4     4 0 9 my ($self, %args) = @_;
154 4         5 my $match = $args{match};
155 4         4 my @res;
156 4         4 push @res, shift @{$match->{operand}};
  4         6  
157 4         3 for my $term (@{$match->{operand}}) {
  4         9  
158 4   50     2 my $op = shift @{$match->{op}//=[]};
  4         9  
159 4 50       8 last unless $op;
160 4 100       9 if ($op eq '>>') { push @res, " >> $term" }
  2 50       5  
161 2         5 elsif ($op eq '<<') { push @res, " << $term" }
162             }
163 4         5 join "", grep {defined} @res;
  8         92  
164             }
165              
166             sub rule_add {
167 23     23 0 46 my ($self, %args) = @_;
168 23         30 my $match = $args{match};
169 23         19 my @res;
170 23         22 push @res, shift @{$match->{operand}};
  23         56  
171 23         25 for my $term (@{$match->{operand}}) {
  23         48  
172 40   50     25 my $op = shift @{$match->{op}//=[]};
  40         94  
173 40 50       62 last unless $op;
174 40 100       61 if ($op eq '.') { push @res, " . $term" }
  2         4  
175 40 100       61 if ($op eq '+') { push @res, " + $term" }
  33         64  
176 40 100       71 if ($op eq '-') { push @res, " - $term" }
  5         11  
177             }
178 23         34 join "", grep {defined} @res;
  63         579  
179             }
180              
181             sub rule_mult {
182 19     19 0 32 my ($self, %args) = @_;
183 19         24 my $match = $args{match};
184 19         16 my @res;
185 19         21 push @res, shift @{$match->{operand}};
  19         36  
186 19         19 for my $term (@{$match->{operand}}) {
  19         36  
187 27   50     22 my $op = shift @{$match->{op}//=[]};
  27         64  
188 27 50       40 last unless $op;
189 27 100       54 if ($op eq '*') { push @res, " * $term" }
  13         29  
190 27 100       35 if ($op eq '/') { push @res, " / $term" }
  6         10  
191 27 100       44 if ($op eq '%') { push @res, " % $term" }
  3         5  
192 27 100       49 if ($op eq 'x') { push @res, " x $term" }
  5         10  
193             }
194 19         23 join "", grep {defined} @res;
  46         484  
195             }
196              
197             sub rule_unary {
198 12     12 0 16 my ($self, %args) = @_;
199 12         16 my $match = $args{match};
200 12         10 my @res;
201 12         16 push @res, $match->{operand};
202 12   50     13 for my $op (reverse @{$match->{op}//=[]}) {
  12         35  
203 17 50       25 last unless $op;
204             # use paren because --x or ++x is interpreted as pre-decrement/increment
205 17 100       31 if ($op eq '!') { @res = ("(", @res, " ? false:true)") }
  5         11  
206 17 100       23 if ($op eq '-') { @res = ("-(", @res, ")") }
  11         20  
207 17 100       31 if ($op eq '~') { @res = ("~(", @res, ")") }
  1         4  
208             }
209 12         17 join "", grep {defined} @res;
  46         306  
210             }
211              
212             sub rule_power {
213 3     3 0 6 my ($self, %args) = @_;
214 3         5 my $match = $args{match};
215 3         3 my @res;
216 3         3 push @res, shift @{$match->{operand}};
  3         6  
217 3         3 for my $term (@{$match->{operand}}) {
  3         7  
218 4         8 push @res, " ** $term";
219             }
220 3         5 join "", grep {defined} @res;
  7         71  
221             }
222              
223             sub rule_subscripting_var {
224 8     8 0 14 my ($self, %args) = @_;
225 8         21 $self->rule_subscripting_expr(%args);
226             }
227              
228             sub rule_subscripting_expr {
229 27     27 0 45 my ($self, %args) = @_;
230 27         48 my $match = $args{match};
231 27         34 my $opd = $match->{operand};
232 27   50     27 my @ss = @{$match->{subscript}//=[]};
  27         85  
233 27 50       54 return $opd unless @ss;
234 27         29 my $res;
235 27         58 for my $s (@ss) {
236 28 100       44 $opd = $res if defined($res);
237 28         119 $res = qq!(do { my (\$v) = ($opd); my (\$s) = ($s); !.
238             qq!if (ref(\$v) eq 'HASH') { \$v->{\$s} } !.
239             qq!elsif (ref(\$v) eq 'ARRAY') { \$v->[\$s] } else { !.
240             qq!die "Invalid subscript \$s for \$v" } })!;
241             }
242 27         580 $res;
243             }
244              
245             sub rule_array {
246 35     35 0 71 my ($self, %args) = @_;
247 35         60 my $match = $args{match};
248 35         47 "[" . join(", ", @{ $match->{element} }) . "]";
  35         811  
249             }
250              
251             sub rule_hash {
252 12     12 0 23 my ($self, %args) = @_;
253 12         16 my $match = $args{match};
254 12         12 "{" . join(", ", @{ $match->{pair} }). "}";
  12         272  
255             }
256              
257             sub rule_undef {
258 5     5 0 191 "undef";
259             }
260              
261             sub rule_squotestr {
262 10     10 0 19 my ($self, %args) = @_;
263             join(" . ",
264 10         23 map { $self->_quote($_->{value}) }
265 10         11 @{ $self->parse_squotestr($args{match}{part}) });
  10         37  
266             }
267              
268             sub rule_dquotestr {
269 64     64 0 124 my ($self, %args) = @_;
270             my @tmp =
271             map { $_->{type} eq 'VAR' ?
272             $self->rule_var(match=>{var=>$_->{value}}) :
273             $self->_quote($_->{value})
274 64 100       204 }
275 64         60 @{ $self->parse_dquotestr($args{match}{part}) };
  64         243  
276 64 50       147 if (@tmp > 1) {
277 0         0 "(". join(" . ", @tmp) . ")[0]";
278             } else {
279 64         1571 $tmp[0];
280             }
281             }
282              
283             sub rule_bool {
284 2     2 0 4 my ($self, %args) = @_;
285 2         3 my $match = $args{match};
286 2 100       5 if ($match->{bool} eq 'true') { "true" } else { "false" }
  1         19  
  1         30  
287             }
288              
289             sub rule_num {
290 318     318 0 481 my ($self, %args) = @_;
291 318         306 my $match = $args{match};
292 318 50       749 if ($match->{num} eq 'inf') { '"Inf"' }
  0 50       0  
293 0         0 elsif ($match->{num} eq 'nan') { '"NaN"' }
294 318         6660 else { $match->{num}+0 }
295             }
296              
297             sub rule_var {
298 97     97 0 179 my ($self, %args) = @_;
299 97         128 my $match = $args{match};
300 97 50       280 if ($self->hook_var) {
301 0         0 my $res = $self->hook_var->($match->{var});
302 0 0       0 return $res if defined($res);
303             }
304 97         2640 return "\$$match->{var}";
305             }
306              
307             sub rule_func {
308 37     37 0 59 my ($self, %args) = @_;
309 37         39 my $match = $args{match};
310 37         53 my $f = $match->{func_name};
311 37         34 my $args = $match->{args};
312 37 50       101 if ($self->hook_func) {
313 0         0 my $res = $self->hook_func->($f, @$args);
314 0 0       0 return $res if defined($res);
315             }
316 37         265 my $fmap = $self->func_mapping->{$f};
317 37 50       235 $f = $fmap if $fmap;
318 37         891 "$f(".join(", ", @$args).")";
319             }
320              
321             sub _map_grep_usort {
322 31     31   55 my ($self, $which, %args) = @_;
323 31         36 my $match = $args{match};
324 31         46 my $ary = $match->{array};
325 31         40 my $expr = $match->{expr};
326              
327 31 100       89 my $perlop = $which eq 'map' ? 'map' : $which eq 'grep' ? 'grep' : 'sort';
    100          
328 31         127 my $uuid = $self->new_marker('subexpr', $expr);
329 31         857 "[$perlop({ TODO-$uuid } \@{$ary})]";
330             }
331              
332             sub rule_func_map {
333 13     13 0 26 my ($self, %args) = @_;
334 13         50 $self->_map_grep_usort('map', %args);
335             }
336              
337             sub rule_func_grep {
338 6     6 0 13 my ($self, %args) = @_;
339 6         26 $self->_map_grep_usort('grep', %args);
340             }
341              
342             sub rule_func_usort {
343 12     12 0 29 my ($self, %args) = @_;
344 12         46 $self->_map_grep_usort('usort', %args);
345             }
346              
347             sub rule_parenthesis {
348 31     31 0 49 my ($self, %args) = @_;
349 31         33 my $match = $args{match};
350 31         669 "(" . $match->{answer} . ")";
351             }
352              
353       221 0   sub expr_preprocess {}
354              
355             sub expr_postprocess {
356 188     188 0 420 my ($self, %args) = @_;
357 188         212 my $result = $args{result};
358 188         545 $result;
359             }
360              
361             # can't use regex here (perl segfaults), at least in 5.10.1, because
362             # we are in one big re::gr regex.
363             sub _quote {
364 72     72   75 my ($self, $str) = @_;
365 72         59 my @c;
366 72         180 for my $c (split '', $str) {
367 156         128 my $o = ord($c);
368 156 100 66     640 if ($c eq '"') { push @c, '\\"' }
  3 100       3  
    100          
    100          
    100          
    50          
369 4         7 elsif ($c eq "\\") { push @c, "\\\\" }
370 3         4 elsif ($c eq '$') { push @c, "\\\$" }
371 2         4 elsif ($c eq '@') { push @c, '\\@' }
372 138         170 elsif ($o >= 32 && $o <= 127) { push @c, $c }
373 0         0 elsif ($o > 255) { push @c, sprintf("\\x{%04x}", $o) }
374 6         20 else { push @c, sprintf("\\x%02x", $o) }
375             }
376 72         475 '"' . join("", @c) . '"';
377             }
378              
379             sub compile {
380 190     190 1 15937 require Language::Expr::Parser;
381              
382 190         218 my ($self, $expr) = @_;
383 190         437 my $res = Language::Expr::Parser::parse_expr($expr, $self);
384 157         156 for my $m (@{ $self->markers }) {
  157         413  
385 31         158 my $type = $m->[0];
386 31 50       70 next unless $type eq 'subexpr';
387 31         46 my $uuid = $m->[1];
388 31         34 my $subexpr = $m->[2];
389 31         71 my $subres = Language::Expr::Parser::parse_expr($subexpr, $self);
390 31         702 $res =~ s/TODO-$uuid/$subres/g;
391             }
392 157         2285 $self->markers([]);
393 157         11344 $res;
394             }
395              
396             sub eval {
397 156     156 1 78587 my ($self, $expr) = @_;
398 156     1   298 my $res = eval "package Language::Expr::Compiler::perl; no strict; " . $self->compile($expr);
  1     1   4  
  1     1   2  
  1     1   18  
  1     1   4  
  1     1   1  
  1     1   11  
  1     1   4  
  1     1   2  
  1     1   14  
  1     1   4  
  1     1   2  
  1     1   17  
  1     1   4  
  1     1   2  
  1     1   16  
  1     1   24  
  1     1   1  
  1     1   30  
  1     1   5  
  1     1   1  
  1     1   21  
  1     1   5  
  1     1   2  
  1     1   18  
  1     1   4  
  1     1   1  
  1     1   18  
  1     1   4  
  1     1   1  
  1     1   20  
  1     1   29  
  1     1   2  
  1     1   35  
  1     1   5  
  1     1   1  
  1     1   42  
  1     1   5  
  1     1   1  
  1     1   28  
  1     1   5  
  1     1   1  
  1     1   27  
  1     1   17  
  1     1   1  
  1     1   27  
  1     1   5  
  1     1   1  
  1     1   27  
  1     1   5  
  1     1   2  
  1     1   15  
  1     1   4  
  1     1   1  
  1     1   15  
  1     1   5  
  1     1   1  
  1     1   14  
  1     1   4  
  1     1   2  
  1     1   15  
  1     1   4  
  1     1   1  
  1     1   34  
  1     1   4  
  1     1   2  
  1     1   27  
  1     1   4  
  1     1   2  
  1     1   34  
  1     1   5  
  1     1   1  
  1     1   30  
  1     1   4  
  1     1   1  
  1     1   27  
  1     1   5  
  1     1   2  
  1     1   18  
  1     1   4  
  1     1   2  
  1     1   25  
  1     1   4  
  1     1   2  
  1     1   25  
  1     1   4  
  1     1   1  
  1     1   23  
  1     1   5  
  1     1   1  
  1     1   25  
  1     1   4  
  1     1   1  
  1     1   39  
  1     1   4  
  1     1   2  
  1     1   24  
  1     1   5  
  1     1   1  
  1     1   24  
  1     1   4  
  1     1   1  
  1     1   26  
  1     1   5  
  1     1   1  
  1     1   25  
  1     1   5  
  1     1   1  
  1     1   26  
  1     1   5  
  1     1   1  
  1     1   24  
  1     1   4  
  1     1   1  
  1     1   25  
  1     1   4  
  1     1   1  
  1     1   28  
  1     1   5  
  1     1   2  
  1     1   31  
  1     1   5  
  1     1   3  
  1     1   34  
  1     1   4  
  1     1   2  
  1     1   37  
  1     1   5  
  1     1   2  
  1     1   20  
  1     1   4  
  1     1   2  
  1     1   38  
  1     1   5  
  1     1   2  
  1     1   38  
  1     1   5  
  1     1   1  
  1     1   14  
  1     1   5  
  1     1   2  
  1     1   19  
  1     1   5  
  1     1   2  
  1     1   37  
  1     1   4  
  1     1   2  
  1     1   31  
  1     1   5  
  1     1   1  
  1     1   13  
  1     1   4  
  1     1   1  
  1     1   16  
  1     1   6  
  1     1   1  
  1         23  
  1         4  
  1         2  
  1         15  
  1         5  
  1         1  
  1         37  
  1         6  
  1         1  
  1         36  
  1         7  
  1         1  
  1         48  
  1         6  
  1         1  
  1         47  
  1         6  
  1         1  
  1         45  
  1         6  
  1         1  
  1         47  
  1         4  
  1         1  
  1         15  
  1         4  
  1         2  
  1         17  
  1         4  
  1         1  
  1         14  
  1         4  
  1         2  
  1         16  
  1         4  
  1         1  
  1         17  
  1         5  
  1         1  
  1         19  
  1         5  
  1         1  
  1         18  
  1         4  
  1         2  
  1         15  
  1         4  
  1         1  
  1         20  
  1         4  
  1         2  
  1         15  
  1         4  
  1         1  
  1         16  
  1         4  
  1         1  
  1         18  
  1         6  
  1         1  
  1         16  
  1         4  
  1         2  
  1         16  
  1         7  
  1         2  
  1         28  
  1         5  
  1         1  
  1         19  
  1         4  
  1         2  
  1         15  
  1         4  
  1         1  
  1         17  
  1         5  
  1         1  
  1         27  
  1         4  
  1         2  
  1         27  
  1         4  
  1         2  
  1         50  
  1         5  
  1         1  
  1         16  
  1         4  
  1         1  
  1         16  
  1         5  
  1         1  
  1         15  
  1         4  
  1         1  
  1         14  
  1         5  
  1         1  
  1         14  
  1         4  
  1         2  
  1         14  
  1         4  
  1         1  
  1         14  
  1         5  
  1         2  
  1         16  
  1         4  
  1         1  
  1         15  
  1         4  
  1         2  
  1         17  
  1         4  
  1         1  
  1         13  
  1         5  
  1         1  
  1         19  
  1         4  
  1         1  
  1         17  
  1         3  
  1         2  
  1         12  
  1         4  
  1         1  
  1         13  
  1         5  
  1         1  
  1         14  
  1         3  
  1         2  
  1         14  
  1         6  
  1         1  
  1         19  
  1         4  
  1         1  
  1         19  
  1         4  
  1         2  
  1         17  
  1         4  
  1         1  
  1         18  
  1         4  
  1         1  
  1         13  
  1         6  
  1         2  
  1         20  
  1         5  
  1         1  
  1         18  
  1         5  
  1         1  
  1         17  
  1         5  
  1         1  
  1         18  
  1         4  
  1         2  
  1         17  
  1         4  
  1         1  
  1         17  
  1         4  
  1         1  
  1         18  
  1         4  
  1         1  
  1         18  
  1         5  
  1         1  
  1         18  
  1         5  
  1         1  
  1         19  
  1         5  
  1         1  
  1         18  
  1         5  
  1         2  
  1         18  
  1         5  
  1         2  
  1         17  
  1         5  
  1         1  
  1         15  
  1         5  
  1         1  
  1         15  
  1         3  
  1         2  
  1         17  
  1         5  
  1         2  
  1         17  
  1         5  
  1         2  
  1         14  
  1         5  
  1         1  
  1         28  
  1         6  
  1         2  
  1         28  
  1         4  
  1         2  
  1         16  
  1         4  
  1         2  
  1         173  
  1         4  
  1         2  
  1         22  
  1         5  
  1         2  
  1         18  
  1         5  
  1         1  
  1         75  
  1         4  
  1         2  
  1         62  
  1         5  
  1         1  
  1         74  
  1         7  
  1         2  
  1         79  
  1         6  
  1         2  
  1         74  
  1         6  
  1         1  
  1         81  
  1         5  
  1         1  
  1         76  
  1         5  
  1         2  
  1         81  
  1         5  
  1         1  
  1         112  
  1         5  
  1         2  
  1         24  
  1         4  
  1         2  
  1         27  
  1         5  
  1         3  
  1         30  
  1         4  
  1         2  
  1         24  
  1         5  
  1         1  
  1         45  
  1         6  
  1         1  
  1         34  
  1         7  
  1         1  
  1         41  
  1         6  
  1         1  
  1         109  
  1         4  
  1         2  
  1         27  
  1         7  
  1         1  
  1         61  
  1         7  
  1         2  
  1         52  
  1         6  
  1         1  
  1         55  
  1         7  
  1         2  
  1         120  
  1         5  
  1         1  
  1         24  
  1         6  
  1         1  
  1         54  
  1         6  
  1         1  
  1         47  
  1         7  
  1         1  
  1         53  
  1         7  
  1         1  
  1         154  
  1         7  
  1         1  
  1         193  
  1         7  
  1         2  
  1         162  
  1         7  
  1         1  
  1         64  
399 156 100       1123 die if $@;
400 149         617 $res;
401             }
402              
403             1;
404             # ABSTRACT: Compile Language::Expr expression to Perl
405              
406             __END__
407              
408             =pod
409              
410             =encoding UTF-8
411              
412             =head1 NAME
413              
414             Language::Expr::Compiler::perl - Compile Language::Expr expression to Perl
415              
416             =head1 VERSION
417              
418             This document describes version 0.27 of Language::Expr::Compiler::perl (from Perl distribution Language-Expr), released on 2016-06-29.
419              
420             =head1 SYNOPSIS
421              
422             use Language::Expr::Compiler::Perl;
423             my $plc = Language::Expr::Compiler::Perl->new;
424             print $plc->perl('1 ^^ 2'); # prints '1 xor 2'
425              
426             =head1 DESCRIPTION
427              
428             Compiles Language::Expr expression to Perl code. Some notes:
429              
430             =over 4
431              
432             =item * Emitted Perl code version
433              
434             Emitted Perl code requires Perl 5.10 (it uses 5.10's "//" defined-or
435             operator) and also the L<boolean> module (it uses 'true' and 'false'
436             objects).
437              
438             =item * Perliness
439              
440             The emitted Perl code will follow Perl's notion of true and false,
441             e.g. the expression '"" || "0" || 2' will result to 2 since Perl
442             thinks that "" and "0" are false. It is also weakly typed like Perl,
443             i.e. allows '1 + "2"' to become 3.
444              
445             =item * Variables by default simply use Perl variables.
446              
447             E.g. $a becomes $a, and so on. Be careful not to make variables which
448             are invalid in Perl, e.g. $.. or ${foo/bar} (but ${foo::bar} is okay
449             because it translates to $foo::bar).
450              
451             You can customize this behaviour by subclassing rule_var() or by providing a
452             hook_var() (see documentation in L<Language::Expr::Compiler::Base>).
453              
454             =item * Functions by default simply use Perl functions.
455              
456             Unless those specified in func_mapping. For example, if
457             $compiler->func_mapping->{foo} = "Foo::do_it", then the expression
458             'foo(1)' will be compiled into 'Foo::do_it(1)'.
459              
460             You can customize this behaviour by subclassing rule_func() or by providing a
461             hook_func() (see documentation in L<Language::Expr::Compiler::Base>).
462              
463             =back
464              
465             =head1 METHODS
466              
467             =for Pod::Coverage ^(rule|expr)_.+
468              
469             =head2 compile($expr) => $perl_code
470              
471             Convert Language::Expr expression into Perl code. Dies if there is syntax error
472             in expression.
473              
474             =head2 eval($expr) => any
475              
476             Convert Language::Expr expression into Perl code and then eval() it.
477              
478             =head1 HOMEPAGE
479              
480             Please visit the project's homepage at L<https://metacpan.org/release/Language-Expr>.
481              
482             =head1 SOURCE
483              
484             Source repository is at L<https://github.com/perlancar/perl-Language-Expr>.
485              
486             =head1 BUGS
487              
488             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Language-Expr>
489              
490             When submitting a bug or request, please include a test-file or a
491             patch to an existing test-file that illustrates the bug or desired
492             feature.
493              
494             =head1 AUTHOR
495              
496             perlancar <perlancar@cpan.org>
497              
498             =head1 COPYRIGHT AND LICENSE
499              
500             This software is copyright (c) 2016 by perlancar@cpan.org.
501              
502             This is free software; you can redistribute it and/or modify it under
503             the same terms as the Perl 5 programming language system itself.
504              
505             =cut