Commit | Line | Data |
9ee33178 |
1 | package Data::Query::ExprBuilder; |
2 | |
3 | use strictures 1; |
b616bc41 |
4 | use Scalar::Util (); |
12e6eab8 |
5 | use Data::Query::ExprHelpers qw(perl_scalar_value perl_operator); |
b616bc41 |
6 | |
0431b46a |
7 | sub _perl_binop { |
8 | return perl_operator( |
9 | shift, |
10 | map { |
11 | (Scalar::Util::blessed($_) |
12 | && $_->isa('Data::Query::ExprBuilder')) |
13 | ? $_->{expr} |
14 | : perl_scalar_value($_) |
15 | # we're called with ($left, $right, 0) or ($right, $left, 1) |
16 | } $_[2] ? @_[1,0] : @_[0,1] |
17 | ); |
18 | } |
19 | |
b616bc41 |
20 | use overload ( |
c3633a0e |
21 | # unary operators |
22 | (map { |
23 | my $op = $_; |
24 | $op => sub { |
25 | Data::Query::ExprBuilder->new({ |
12e6eab8 |
26 | expr => perl_operator($op => $_[0]->{expr}) |
c3633a0e |
27 | }); |
28 | } |
29 | } qw(! neg)), |
7e599929 |
30 | # binary operators |
b616bc41 |
31 | (map { |
7e599929 |
32 | my ($overload, $as) = ref($_) ? @$_ : ($_, $_); |
33 | $overload => sub { |
b616bc41 |
34 | Data::Query::ExprBuilder->new({ |
0431b46a |
35 | expr => _perl_binop($as, @_), |
b616bc41 |
36 | }); |
37 | } |
7e599929 |
38 | } |
b01a3688 |
39 | qw(+ - * / % ** << >> . < > lt le gt ge ), |
7e599929 |
40 | |
41 | # since 'and' and 'or' aren't operators we borrow the bitwise ops |
42 | [ '&' => 'and' ], [ '|' => 'or' ], |
43 | ), |
b01a3688 |
44 | |
45 | # equality operators (need undef maping) |
46 | (map { |
0431b46a |
47 | my $op = $_; |
48 | $op => sub { |
b01a3688 |
49 | Data::Query::ExprBuilder->new({ |
50 | expr => grep(!defined, @_[0,1]) |
0431b46a |
51 | ? (map { $op =~ /==|eq/ ? perl_operator(not => $_) : $_ } |
b01a3688 |
52 | perl_operator(defined => map { defined($_) ? $_->{expr} : () } @_[0,1])) |
0431b46a |
53 | : _perl_binop($op, @_), |
b01a3688 |
54 | }); |
55 | } |
56 | } |
57 | qw(== != eq ne) |
58 | |
59 | ), |
7e599929 |
60 | # unsupported |
9e0200bc |
61 | (map { |
62 | my $op = $_; |
63 | $op => sub { die "Can't use operator $op on a ".ref($_[0]) } |
7e599929 |
64 | } qw(<=> cmp x ^ ~) |
9e0200bc |
65 | ), |
8e97944c |
66 | fallback => 1, |
b616bc41 |
67 | ); |
9ee33178 |
68 | |
69 | sub new { |
70 | bless({ %{$_[1]} }, (ref($_[0])||$_[0])); |
71 | } |
72 | |
73 | 1; |