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