| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package List::Gen::Perl6; |
|
2
|
1
|
|
|
1
|
|
543
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
37
|
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
36
|
|
|
4
|
1
|
|
|
1
|
|
6
|
use lib '../../'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
9
|
|
|
5
|
1
|
|
|
1
|
|
131
|
use List::Gen (); |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
17
|
|
|
6
|
1
|
|
|
1
|
|
917
|
use Filter::Simple; |
|
|
1
|
|
|
|
|
26035
|
|
|
|
1
|
|
|
|
|
9
|
|
|
7
|
1
|
|
|
1
|
|
57
|
use Carp (); |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
40
|
|
|
8
|
|
|
|
|
|
|
BEGIN { |
|
9
|
1
|
|
|
1
|
|
7
|
FILTER_ONLY all => \&_filter_hyper, |
|
10
|
|
|
|
|
|
|
code_no_comments => \&_filter_rest; |
|
11
|
|
|
|
|
|
|
} |
|
12
|
|
|
|
|
|
|
my ($ops) = map qr/(?:[Rr]?(?:$_))/, join '|', map quotemeta, ',', qw ( |
|
13
|
|
|
|
|
|
|
- + / * ** x % . & | ^ < > << >> <=> cmp lt gt eq ne le ge == != <= >= |
|
14
|
|
|
|
|
|
|
); |
|
15
|
|
|
|
|
|
|
sub _filter_hyper { |
|
16
|
1
|
|
|
1
|
|
920
|
s/ ((?:<<|>>)~?) ($ops) (<<|>>) /$1'$2'$3/gx; |
|
17
|
|
|
|
|
|
|
} |
|
18
|
|
|
|
|
|
|
sub _filter_rest { |
|
19
|
1
|
|
|
1
|
|
260871
|
s{ |
|
20
|
|
|
|
|
|
|
(?
|
|
21
|
|
|
|
|
|
|
\[ (\.\.|\\)? ($ops) \] |
|
22
|
|
|
|
|
|
|
(?= \s* (?! -> | \b(?:$ops)\b(?!>) | [;\)\]\}\>] ) ) |
|
23
|
|
|
|
|
|
|
}{ |
|
24
|
10
|
|
100
|
|
|
44
|
my $t = $1 || ''; |
|
25
|
10
|
100
|
|
|
|
21
|
$t = '..' if $t eq '\\'; |
|
26
|
10
|
|
|
|
|
66
|
"List::Gen::Perl6::_reduceWith '$t$2', " |
|
27
|
|
|
|
|
|
|
}egx; |
|
28
|
1
|
|
|
|
|
70
|
s{ |
|
29
|
|
|
|
|
|
|
(?
|
|
30
|
|
|
|
|
|
|
\[ (\.\.|\\)? ($ops) \] |
|
31
|
|
|
|
|
|
|
(?!>) |
|
32
|
|
|
|
|
|
|
}{ |
|
33
|
4
|
|
100
|
|
|
19
|
my $t = $1 || ''; |
|
34
|
4
|
100
|
|
|
|
12
|
$t = '..' if $t eq '\\'; |
|
35
|
4
|
|
|
|
|
29
|
"List::Gen::Perl6::_reduction('$t$2')" |
|
36
|
|
|
|
|
|
|
}gxe; |
|
37
|
1
|
|
|
|
|
71
|
s{ |
|
38
|
|
|
|
|
|
|
(?
|
|
39
|
|
|
|
|
|
|
}{ |
|
40
|
6
|
100
|
66
|
|
|
31
|
my $rev = $1||$2 ? '~' : ''; |
|
41
|
6
|
100
|
|
|
|
38
|
$3 ? "|$rev'$3'|" : '|' |
|
42
|
|
|
|
|
|
|
}gxe; |
|
43
|
1
|
|
|
|
|
81
|
s{ |
|
44
|
|
|
|
|
|
|
(?
|
|
45
|
|
|
|
|
|
|
}{ |
|
46
|
5
|
100
|
66
|
|
|
25
|
my $rev = $1||$2 ? '~' : ''; |
|
47
|
5
|
100
|
|
|
|
35
|
$3 ? "x$rev'$3'x" : 'x' |
|
48
|
|
|
|
|
|
|
}gxe; |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my %cache; |
|
52
|
|
|
|
|
|
|
sub _reduction { |
|
53
|
14
|
|
|
14
|
|
193
|
my $str = "[@_]"; |
|
54
|
14
|
|
100
|
|
|
17
|
{return $cache{$str} || next} |
|
|
14
|
|
|
|
|
56
|
|
|
55
|
8
|
|
|
|
|
10
|
local $@; |
|
56
|
8
|
|
|
|
|
12
|
my $ret = eval {&List::Gen::glob($str)}; |
|
|
8
|
|
|
|
|
25
|
|
|
57
|
8
|
50
|
|
|
|
41
|
ref $ret eq 'CODE' or Carp::croak("not a generator glob: $str\n$@\n"); |
|
58
|
8
|
|
|
|
|
39
|
$cache{$str} = $ret; |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
sub _reduceWith { |
|
61
|
10
|
|
|
10
|
|
284
|
goto &{_reduction shift} |
|
|
10
|
|
|
|
|
22
|
|
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
sub filter { |
|
64
|
0
|
|
|
0
|
0
|
|
my $str = shift; |
|
65
|
0
|
|
|
|
|
|
for ($str) { |
|
66
|
0
|
|
|
|
|
|
_filter_hyper; |
|
67
|
0
|
|
|
|
|
|
_filter_rest; |
|
68
|
|
|
|
|
|
|
} |
|
69
|
0
|
|
|
|
|
|
return $str; |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head1 NAME |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
List::Gen::Perl6 - perl6 meta operators in perl5 |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
many of the features found in L borrow ideas from perl6. however, |
|
79
|
|
|
|
|
|
|
since the syntax of perl5 and perl6 differ, some of the constructs in perl5 are |
|
80
|
|
|
|
|
|
|
longer/messier than in perl6. C< List::Gen::Perl6 > is a source filter that |
|
81
|
|
|
|
|
|
|
makes some of C's features more syntactic. |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
the new syntactic constructs are: |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
zip: generator Z generator |
|
86
|
|
|
|
|
|
|
zipwith: generator Z+ generator |
|
87
|
|
|
|
|
|
|
cross: generator X generator |
|
88
|
|
|
|
|
|
|
crosswith: generator X+ generator |
|
89
|
|
|
|
|
|
|
hyper: generator <<+>> generator |
|
90
|
|
|
|
|
|
|
hyper: generator >>+<< generator |
|
91
|
|
|
|
|
|
|
hyper: generator >>+>> generator |
|
92
|
|
|
|
|
|
|
hyper: generator <<+<< generator |
|
93
|
|
|
|
|
|
|
reduce: [+] list |
|
94
|
|
|
|
|
|
|
triangular reduction: [\+] list |
|
95
|
|
|
|
|
|
|
or [..+] list |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
in the above, C< + > can be any perl binary operator. |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
here is a table showing the correspondence between the source filter constructs, |
|
100
|
|
|
|
|
|
|
the native overloaded ops, and the operation expanded into methods and functions. |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
List::Gen::Perl6 List::Gen List::Gen expanded |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
<1..3> Z <4..6> ~~ <1..3> | <4..6> ~~ <1..3>->zip(<4..6>) |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
<1..3> Z. <4..6> ~~ <1..3> |'.'| <4..6> ~~ <1..3>->zip('.' => <4..6>) |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
<1..3> X <4..6> ~~ <1..3> x <4..6> ~~ <1..3>->cross(<4..6>) |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
<1..3> X. <4..6> ~~ <1..3> x'.'x <4..6> ~~ <1..3>->cross('.' => <4..6>) |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
<1..3> <<+>> <4..6> ~~ <1..3> <<'+'>> <4..6> ~~ <1..3>->hyper('<<+>>', <4..6>) |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
[+] 1..10 ~~ <[+] 1..10> ~~ reduce {$_[0] + $_[1]} 1 .. 10 |
|
115
|
|
|
|
|
|
|
[+]->(1..10) ~~ <[+]>->(1..10) ~~ same as above |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
[\+] 1..10 ~~ <[..+] 1..10> ~~ scan {$_[0] + $_[1]} 1 .. 10 |
|
118
|
|
|
|
|
|
|
[\+]->(1..10) ~~ <[..+]>->(1..10) ~~ same as above |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
except for normal reductions C< [+] >, all of the new constructs return a |
|
121
|
|
|
|
|
|
|
generator. |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
you can flip the arguments to an operator with C< R > or C< r > and in some |
|
124
|
|
|
|
|
|
|
cases C< ~ > |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
ZR. Zr. Z~. |
|
127
|
|
|
|
|
|
|
XR. Xr. X~. |
|
128
|
|
|
|
|
|
|
<> <> <<~.>> |
|
129
|
|
|
|
|
|
|
[R.] [r.] n/a |
|
130
|
|
|
|
|
|
|
[\R.] [\r.] n/a |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
when used without a following argument, reductions and triangular reductions |
|
133
|
|
|
|
|
|
|
will return a code reference that will perform the reduction on its arguments. |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
my $sum = [+]; |
|
136
|
|
|
|
|
|
|
say $sum->(1..10); # 55 |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
reductions can take a list of scalars, or a single generator as their argument. |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
only the left hand side of the zip, cross, and hyper operators needs to be a |
|
141
|
|
|
|
|
|
|
generator. zip and cross will upgrade their rhs to a generator if it is an array. |
|
142
|
|
|
|
|
|
|
hyper will upgrade it's rhs to a generator if it is an array or a scalar. |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
the source filter is limited in scope, and should not harm other parts of the code, |
|
145
|
|
|
|
|
|
|
however, source filters are notoriously difficult to fully test, so take that |
|
146
|
|
|
|
|
|
|
with a grain of salt. due to limitations of L, hyper operators |
|
147
|
|
|
|
|
|
|
will be filtered in both code and strings. all other filters should skip strings. |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
this code is not really intended for serious work, ymmv. |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head1 AUTHOR |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Eric Strom, C<< >> |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=head1 BUGS |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
report any bugs / feature requests to C, or through |
|
158
|
|
|
|
|
|
|
the web interface at L. |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
comments / feedback / patches are also welcome. |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
copyright 2009-2011 Eric Strom. |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
this program is free software; you can redistribute it and/or modify it under |
|
167
|
|
|
|
|
|
|
the terms of either: the GNU General Public License as published by the Free |
|
168
|
|
|
|
|
|
|
Software Foundation; or the Artistic License. |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
see http://dev.perl.org/licenses/ for more information. |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=cut |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
1 |