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-07-01'; # DATE
4             our $VERSION = '0.28'; # VERSION
5              
6 2     2   39 use 5.010;
  2         4  
7 2     2   7 use strict;
  2         2  
  2         36  
8 2     2   6 use warnings;
  2         1  
  2         43  
9              
10 2     2   723 use Role::Tiny::With;
  2         6697  
  2         117  
11 2     2   694 use parent 'Language::Expr::Compiler::Base';
  2         432  
  2         8  
12             with 'Language::Expr::CompilerRole';
13              
14 2     2   397 use boolean;
  2         669  
  2         7  
15              
16             sub rule_pair_simple {
17 10     10 0 16 my ($self, %args) = @_;
18 10         11 my $match = $args{match};
19 10         198 "$match->{key} => $match->{value}";
20             }
21              
22             sub rule_pair_string {
23 6     6 0 9 my ($self, %args) = @_;
24 6         7 my $match = $args{match};
25 6         117 "$match->{key} => $match->{value}";
26             }
27              
28             sub rule_or_xor {
29 8     8 0 14 my ($self, %args) = @_;
30 8         9 my $match = $args{match};
31 8         5 my @res;
32 8         5 push @res, shift @{$match->{operand}};
  8         14  
33 8         5 for my $term (@{$match->{operand}}) {
  8         14  
34 8   50     6 my $op = shift @{$match->{op}//=[]};
  8         18  
35 8 50       11 last unless $op;
36 8 100       16 if ($op eq '||') { push @res, " || $term" }
  4 50       10  
    0          
37 4         9 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         9 join "", grep {defined} @res;
  16         192  
42             }
43              
44             sub rule_and {
45 4     4 0 6 my ($self, %args) = @_;
46 4         4 my $match = $args{match};
47 4         3 my @res;
48 4         2 push @res, shift @{$match->{operand}};
  4         7  
49 4         6 for my $term (@{$match->{operand}}) {
  4         6  
50 4   50     4 my $op = shift @{$match->{op}//=[]};
  4         10  
51 4 50       5 last unless $op;
52 4 50       8 if ($op eq '&&') { @res = ("((", @res, " && $term) || false)") }
  4         13  
53             }
54 4         5 join "", grep {defined} @res;
  12         91  
55             }
56              
57             sub rule_ternary {
58 10     10 0 14 my ($self, %args) = @_;
59 10         9 my $match = $args{match};
60 10         9 my $opd = $match->{operand};
61 10         226 "$opd->[0] ? $opd->[1] : $opd->[2]";
62             }
63              
64             sub rule_bit_or_xor {
65 2     2 0 4 my ($self, %args) = @_;
66 2         3 my $match = $args{match};
67 2         1 my @res;
68 2         3 push @res, shift @{$match->{operand}};
  2         4  
69 2         2 for my $term (@{$match->{operand}}) {
  2         5  
70 2   50     1 my $op = shift @{$match->{op}//=[]};
  2         7  
71 2 50       3 last unless $op;
72 2 100       6 if ($op eq '|') { push @res, " | $term" }
  1 50       3  
73 1         4 elsif ($op eq '^') { push @res, " ^ $term" }
74             }
75 2         4 join "", grep {defined} @res;
  4         43  
76             }
77              
78             sub rule_bit_and {
79 1     1 0 3 my ($self, %args) = @_;
80 1         2 my $match = $args{match};
81 1         1 my @res;
82 1         1 push @res, shift @{$match->{operand}};
  1         3  
83 1         1 for my $term (@{$match->{operand}}) {
  1         2  
84 1   50     1 my $op = shift @{$match->{op}//=[]};
  1         4  
85 1 50       2 last unless $op;
86 1 50       3 if ($op eq '&') { push @res, " & $term" }
  1         2  
87             }
88 1         2 join "", grep {defined} @res;
  2         23  
89             }
90              
91             sub rule_comparison3 {
92 29     29 0 54 my ($self, %args) = @_;
93 29         33 my $match = $args{match};
94 29         23 my @res;
95 29         22 push @res, shift @{$match->{operand}};
  29         58  
96 29         26 for my $term (@{$match->{operand}}) {
  29         54  
97 29   50     20 my $op = shift @{$match->{op}//=[]};
  29         68  
98 29 50       50 last unless $op;
99 29 100       52 if ($op eq '<=>') { push @res, " <=> $term" }
  22 50       52  
100 7         16 elsif ($op eq 'cmp') { push @res, " cmp $term" }
101             }
102 29         39 join "", grep {defined} @res;
  58         683  
103             }
104              
105             sub rule_comparison {
106 53     53 0 76 my ($self, %args) = @_;
107 53         51 my $match = $args{match};
108 53         44 my @opds;
109 53         35 push @opds, shift @{$match->{operand}};
  53         92  
110 53 50       106 return '' unless defined $opds[0];
111 53         32 my @ops;
112 53         41 for my $term (@{$match->{operand}}) {
  53         87  
113 60         51 push @opds, $term;
114 60   50     38 my $op = shift @{$match->{op}//=[]};
  60         114  
115 60 50       90 last unless $op;
116 60 100       193 if ($op eq '==' ) { push @ops, '==' }
  17 100       26  
    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         37 elsif ($op eq '>' ) { push @ops, '>' }
123 5         8 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       95 return $opds[0] unless @ops;
130 53         39 my @res;
131             my $lastopd;
132 0         0 my ($opd1, $opd2);
133 53         94 while (@ops) {
134 60         56 my $op = pop @ops;
135 60 100       86 if (defined($lastopd)) {
136 7         6 $opd2 = $lastopd;
137 7         9 $opd1 = pop @opds;
138             } else {
139 53         48 $opd2 = pop @opds;
140 53         46 $opd1 = pop @opds;
141             }
142 60 100       65 if (@res) {
143 7         20 @res = ("(($opd1 $op $opd2) ? ", @res, " : false)");
144             } else {
145 53         105 push @res, "($opd1 $op $opd2 ? true:false)";
146             }
147 60         106 $lastopd = $opd1;
148             }
149 53         1190 join "", @res;
150             }
151              
152             sub rule_bit_shift {
153 4     4 0 7 my ($self, %args) = @_;
154 4         4 my $match = $args{match};
155 4         4 my @res;
156 4         3 push @res, shift @{$match->{operand}};
  4         7  
157 4         5 for my $term (@{$match->{operand}}) {
  4         5  
158 4   50     4 my $op = shift @{$match->{op}//=[]};
  4         10  
159 4 50       5 last unless $op;
160 4 100       9 if ($op eq '>>') { push @res, " >> $term" }
  2 50       6  
161 2         6 elsif ($op eq '<<') { push @res, " << $term" }
162             }
163 4         5 join "", grep {defined} @res;
  8         90  
164             }
165              
166             sub rule_add {
167 23     23 0 39 my ($self, %args) = @_;
168 23         26 my $match = $args{match};
169 23         18 my @res;
170 23         23 push @res, shift @{$match->{operand}};
  23         40  
171 23         18 for my $term (@{$match->{operand}}) {
  23         37  
172 40   50     28 my $op = shift @{$match->{op}//=[]};
  40         74  
173 40 50       52 last unless $op;
174 40 100       62 if ($op eq '.') { push @res, " . $term" }
  2         4  
175 40 100       55 if ($op eq '+') { push @res, " + $term" }
  33         58  
176 40 100       70 if ($op eq '-') { push @res, " - $term" }
  5         9  
177             }
178 23         24 join "", grep {defined} @res;
  63         564  
179             }
180              
181             sub rule_mult {
182 19     19 0 30 my ($self, %args) = @_;
183 19         19 my $match = $args{match};
184 19         17 my @res;
185 19         16 push @res, shift @{$match->{operand}};
  19         30  
186 19         18 for my $term (@{$match->{operand}}) {
  19         32  
187 27   50     21 my $op = shift @{$match->{op}//=[]};
  27         51  
188 27 50       48 last unless $op;
189 27 100       46 if ($op eq '*') { push @res, " * $term" }
  13         24  
190 27 100       42 if ($op eq '/') { push @res, " / $term" }
  6         10  
191 27 100       39 if ($op eq '%') { push @res, " % $term" }
  3         7  
192 27 100       43 if ($op eq 'x') { push @res, " x $term" }
  5         11  
193             }
194 19         21 join "", grep {defined} @res;
  46         433  
195             }
196              
197             sub rule_unary {
198 12     12 0 19 my ($self, %args) = @_;
199 12         15 my $match = $args{match};
200 12         8 my @res;
201 12         17 push @res, $match->{operand};
202 12   50     11 for my $op (reverse @{$match->{op}//=[]}) {
  12         62  
203 17 50       26 last unless $op;
204             # use paren because --x or ++x is interpreted as pre-decrement/increment
205 17 100       25 if ($op eq '!') { @res = ("(", @res, " ? false:true)") }
  5         10  
206 17 100       26 if ($op eq '-') { @res = ("-(", @res, ")") }
  11         19  
207 17 100       29 if ($op eq '~') { @res = ("~(", @res, ")") }
  1         3  
208             }
209 12         11 join "", grep {defined} @res;
  46         301  
210             }
211              
212             sub rule_power {
213 3     3 0 4 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         6  
218 4         9 push @res, " ** $term";
219             }
220 3         5 join "", grep {defined} @res;
  7         71  
221             }
222              
223             sub rule_subscripting_var {
224 8     8 0 12 my ($self, %args) = @_;
225 8         21 $self->rule_subscripting_expr(%args);
226             }
227              
228             sub rule_subscripting_expr {
229 27     27 0 41 my ($self, %args) = @_;
230 27         33 my $match = $args{match};
231 27         37 my $opd = $match->{operand};
232 27   50     24 my @ss = @{$match->{subscript}//=[]};
  27         75  
233 27 50       53 return $opd unless @ss;
234 27         17 my $res;
235 27         44 for my $s (@ss) {
236 28 100       45 $opd = $res if defined($res);
237 28         100 $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         570 $res;
243             }
244              
245             sub rule_array {
246 35     35 0 64 my ($self, %args) = @_;
247 35         44 my $match = $args{match};
248 35         36 "[" . join(", ", @{ $match->{element} }) . "]";
  35         806  
249             }
250              
251             sub rule_hash {
252 12     12 0 22 my ($self, %args) = @_;
253 12         13 my $match = $args{match};
254 12         12 "{" . join(", ", @{ $match->{pair} }). "}";
  12         258  
255             }
256              
257             sub rule_undef {
258 5     5 0 177 "undef";
259             }
260              
261             sub rule_squotestr {
262 10     10 0 22 my ($self, %args) = @_;
263             join(" . ",
264 10         20 map { $self->_quote($_->{value}) }
265 10         11 @{ $self->parse_squotestr($args{match}{part}) });
  10         31  
266             }
267              
268             sub rule_dquotestr {
269 64     64 0 99 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       192 }
275 64         62 @{ $self->parse_dquotestr($args{match}{part}) };
  64         211  
276 64 50       140 if (@tmp > 1) {
277 0         0 "(". join(" . ", @tmp) . ")[0]";
278             } else {
279 64         1516 $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       7 if ($match->{bool} eq 'true') { "true" } else { "false" }
  1         38  
  1         20  
287             }
288              
289             sub rule_num {
290 318     318 0 479 my ($self, %args) = @_;
291 318         308 my $match = $args{match};
292 318 50       690 if ($match->{num} eq 'inf') { '"Inf"' }
  0 50       0  
293 0         0 elsif ($match->{num} eq 'nan') { '"NaN"' }
294 318         6621 else { $match->{num}+0 }
295             }
296              
297             sub rule_var {
298 97     97 0 156 my ($self, %args) = @_;
299 97         111 my $match = $args{match};
300 97 50       232 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         2539 return "\$$match->{var}";
305             }
306              
307             sub rule_func {
308 37     37 0 62 my ($self, %args) = @_;
309 37         42 my $match = $args{match};
310 37         37 my $f = $match->{func_name};
311 37         36 my $args = $match->{args};
312 37 50       93 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         245 my $fmap = $self->func_mapping->{$f};
317 37 50       247 $f = $fmap if $fmap;
318 37         911 "$f(".join(", ", @$args).")";
319             }
320              
321             sub _map_grep_usort {
322 31     31   51 my ($self, $which, %args) = @_;
323 31         40 my $match = $args{match};
324 31         42 my $ary = $match->{array};
325 31         32 my $expr = $match->{expr};
326              
327 31 100       92 my $perlop = $which eq 'map' ? 'map' : $which eq 'grep' ? 'grep' : 'sort';
    100          
328 31         96 my $uuid = $self->new_marker('subexpr', $expr);
329 31         851 "[$perlop({ TODO-$uuid } \@{$ary})]";
330             }
331              
332             sub rule_func_map {
333 13     13 0 25 my ($self, %args) = @_;
334 13         38 $self->_map_grep_usort('map', %args);
335             }
336              
337             sub rule_func_grep {
338 6     6 0 12 my ($self, %args) = @_;
339 6         19 $self->_map_grep_usort('grep', %args);
340             }
341              
342             sub rule_func_usort {
343 12     12 0 26 my ($self, %args) = @_;
344 12         43 $self->_map_grep_usort('usort', %args);
345             }
346              
347             sub rule_parenthesis {
348 31     31 0 45 my ($self, %args) = @_;
349 31         30 my $match = $args{match};
350 31         674 "(" . $match->{answer} . ")";
351             }
352              
353       221 0   sub expr_preprocess {}
354              
355             sub expr_postprocess {
356 188     188 0 427 my ($self, %args) = @_;
357 188         216 my $result = $args{result};
358 188         535 $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   77 my ($self, $str) = @_;
365 72         48 my @c;
366 72         160 for my $c (split '', $str) {
367 156         134 my $o = ord($c);
368 156 100 66     600 if ($c eq '"') { push @c, '\\"' }
  3 100       5  
    100          
    100          
    100          
    50          
369 4         7 elsif ($c eq "\\") { push @c, "\\\\" }
370 3         4 elsif ($c eq '$') { push @c, "\\\$" }
371 2         3 elsif ($c eq '@') { push @c, '\\@' }
372 138         169 elsif ($o >= 32 && $o <= 127) { push @c, $c }
373 0         0 elsif ($o > 255) { push @c, sprintf("\\x{%04x}", $o) }
374 6         24 else { push @c, sprintf("\\x%02x", $o) }
375             }
376 72         449 '"' . join("", @c) . '"';
377             }
378              
379             sub compile {
380 190     190 1 12647 require Language::Expr::Parser;
381              
382 190         206 my ($self, $expr) = @_;
383 190         400 my $res = Language::Expr::Parser::parse_expr($expr, $self);
384 157         152 for my $m (@{ $self->markers }) {
  157         369  
385 31         138 my $type = $m->[0];
386 31 50       66 next unless $type eq 'subexpr';
387 31         37 my $uuid = $m->[1];
388 31         34 my $subexpr = $m->[2];
389 31         70 my $subres = Language::Expr::Parser::parse_expr($subexpr, $self);
390 31         616 $res =~ s/TODO-$uuid/$subres/g;
391             }
392 157         2035 $self->markers([]);
393 157         10462 $res;
394             }
395              
396             sub eval {
397 156     156 1 58224 my ($self, $expr) = @_;
398 156     1   251 my $res = eval "package Language::Expr::Compiler::perl; no strict; " . $self->compile($expr);
  1     1   4  
  1     1   1  
  1     1   15  
  1     1   4  
  1     1   1  
  1     1   11  
  1     1   5  
  1     1   0  
  1     1   13  
  1     1   4  
  1     1   1  
  1     1   12  
  1     1   4  
  1     1   1  
  1     1   14  
  1     1   4  
  1     1   1  
  1     1   17  
  1     1   5  
  1     1   2  
  1     1   12  
  1     1   4  
  1     1   1  
  1     1   15  
  1     1   5  
  1     1   1  
  1     1   16  
  1     1   5  
  1     1   1  
  1     1   15  
  1     1   6  
  1     1   2  
  1     1   28  
  1     1   4  
  1     1   1  
  1     1   26  
  1     1   4  
  1     1   1  
  1     1   23  
  1     1   4  
  1     1   1  
  1     1   23  
  1     1   4  
  1     1   1  
  1     1   23  
  1     1   5  
  1     1   1  
  1     1   22  
  1     1   4  
  1     1   2  
  1     1   14  
  1     1   8  
  1     1   2  
  1     1   22  
  1     1   5  
  1     1   1  
  1     1   16  
  1     1   4  
  1     1   1  
  1     1   14  
  1     1   5  
  1     1   1  
  1     1   32  
  1     1   6  
  1     1   1  
  1     1   28  
  1     1   4  
  1     1   2  
  1     1   30  
  1     1   4  
  1     1   2  
  1     1   25  
  1     1   4  
  1     1   1  
  1     1   24  
  1     1   5  
  1     1   1  
  1     1   16  
  1     1   6  
  1     1   1  
  1     1   37  
  1     1   4  
  1     1   1  
  1     1   24  
  1     1   5  
  1     1   1  
  1     1   22  
  1     1   4  
  1     1   2  
  1     1   22  
  1     1   5  
  1     1   1  
  1     1   22  
  1     1   4  
  1     1   2  
  1     1   22  
  1     1   4  
  1     1   1  
  1     1   23  
  1     1   4  
  1     1   1  
  1     1   22  
  1     1   4  
  1     1   2  
  1     1   39  
  1     1   5  
  1     1   2  
  1     1   22  
  1     1   5  
  1     1   1  
  1     1   23  
  1     1   4  
  1     1   1  
  1     1   23  
  1     1   5  
  1     1   1  
  1     1   27  
  1     1   4  
  1     1   1  
  1     1   27  
  1     1   4  
  1     1   1  
  1     1   27  
  1     1   4  
  1     1   2  
  1     1   19  
  1     1   4  
  1     1   1  
  1     1   20  
  1     1   4  
  1     1   1  
  1     1   33  
  1     1   5  
  1     1   1  
  1     1   33  
  1     1   4  
  1     1   1  
  1     1   13  
  1     1   4  
  1     1   1  
  1     1   13  
  1     1   5  
  1     1   1  
  1     1   30  
  1     1   4  
  1     1   1  
  1     1   30  
  1     1   4  
  1     1   1  
  1     1   13  
  1     1   4  
  1     1   1  
  1     1   15  
  1     1   4  
  1     1   2  
  1         14  
  1         7  
  1         2  
  1         23  
  1         6  
  1         1  
  1         35  
  1         5  
  1         1  
  1         26  
  1         4  
  1         1  
  1         33  
  1         4  
  1         1  
  1         32  
  1         17  
  1         2  
  1         34  
  1         6  
  1         1  
  1         34  
  1         5  
  1         1  
  1         18  
  1         5  
  1         1  
  1         15  
  1         4  
  1         1  
  1         14  
  1         4  
  1         2  
  1         16  
  1         5  
  1         1  
  1         16  
  1         5  
  1         1  
  1         14  
  1         5  
  1         2  
  1         15  
  1         4  
  1         2  
  1         14  
  1         5  
  1         1  
  1         19  
  1         4  
  1         1  
  1         15  
  1         5  
  1         2  
  1         17  
  1         4  
  1         2  
  1         17  
  1         4  
  1         1  
  1         14  
  1         4  
  1         2  
  1         14  
  1         4  
  1         1  
  1         17  
  1         5  
  1         1  
  1         17  
  1         5  
  1         1  
  1         13  
  1         7  
  1         2  
  1         49  
  1         4  
  1         1  
  1         21  
  1         4  
  1         2  
  1         25  
  1         4  
  1         1  
  1         26  
  1         4  
  1         2  
  1         14  
  1         4  
  1         2  
  1         29  
  1         5  
  1         1  
  1         14  
  1         4  
  1         2  
  1         14  
  1         5  
  1         1  
  1         13  
  1         5  
  1         1  
  1         13  
  1         5  
  1         1  
  1         14  
  1         4  
  1         2  
  1         16  
  1         4  
  1         1  
  1         14  
  1         5  
  1         1  
  1         16  
  1         9  
  1         1  
  1         15  
  1         5  
  1         1  
  1         17  
  1         5  
  1         1  
  1         15  
  1         5  
  1         0  
  1         12  
  1         4  
  1         1  
  1         12  
  1         4  
  1         1  
  1         13  
  1         4  
  1         1  
  1         13  
  1         4  
  1         1  
  1         13  
  1         4  
  1         1  
  1         18  
  1         5  
  1         1  
  1         17  
  1         5  
  1         2  
  1         18  
  1         4  
  1         2  
  1         11  
  1         4  
  1         1  
  1         12  
  1         5  
  1         1  
  1         17  
  1         4  
  1         1  
  1         17  
  1         4  
  1         1  
  1         18  
  1         5  
  1         1  
  1         17  
  1         4  
  1         1  
  1         18  
  1         4  
  1         1  
  1         17  
  1         4  
  1         1  
  1         18  
  1         5  
  1         1  
  1         18  
  1         4  
  1         2  
  1         17  
  1         4  
  1         1  
  1         17  
  1         5  
  1         1  
  1         18  
  1         7  
  1         2  
  1         27  
  1         8  
  1         2  
  1         23  
  1         6  
  1         1  
  1         16  
  1         4  
  1         1  
  1         25  
  1         4  
  1         1  
  1         17  
  1         5  
  1         1  
  1         16  
  1         5  
  1         1  
  1         23  
  1         8  
  1         1  
  1         28  
  1         5  
  1         1  
  1         15  
  1         4  
  1         1  
  1         67  
  1         4  
  1         2  
  1         18  
  1         5  
  1         1  
  1         15  
  1         4  
  1         1  
  1         71  
  1         5  
  1         1  
  1         77  
  1         6  
  1         2  
  1         61  
  1         4  
  1         1  
  1         59  
  1         5  
  1         1  
  1         60  
  1         5  
  1         1  
  1         62  
  1         5  
  1         1  
  1         62  
  1         5  
  1         1  
  1         67  
  1         6  
  1         1  
  1         100  
  1         5  
  1         1  
  1         21  
  1         5  
  1         1  
  1         23  
  1         5  
  1         1  
  1         29  
  1         4  
  1         2  
  1         38  
  1         5  
  1         1  
  1         37  
  1         5  
  1         1  
  1         30  
  1         5  
  1         2  
  1         34  
  1         8  
  1         2  
  1         107  
  1         4  
  1         1  
  1         24  
  1         5  
  1         1  
  1         51  
  1         5  
  1         1  
  1         40  
  1         5  
  1         1  
  1         60  
  1         7  
  1         1  
  1         127  
  1         5  
  1         1  
  1         21  
  1         6  
  1         1  
  1         48  
  1         5  
  1         2  
  1         43  
  1         8  
  1         2  
  1         51  
  1         8  
  1         1  
  1         154  
  1         7  
  1         2  
  1         187  
  1         7  
  1         1  
  1         158  
  1         8  
  1         1  
  1         66  
399 156 100       1046 die if $@;
400 149         572 $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.28 of Language::Expr::Compiler::perl (from Perl distribution Language-Expr), released on 2016-07-01.
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