Factor out binop construction
[dbsrgits/Data-Query.git] / lib / Data / Query / ExprBuilder.pm
CommitLineData
9ee33178 1package Data::Query::ExprBuilder;
2
3use strictures 1;
b616bc41 4use Scalar::Util ();
12e6eab8 5use Data::Query::ExprHelpers qw(perl_scalar_value perl_operator);
b616bc41 6
0431b46a 7sub _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 20use 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
69sub new {
70 bless({ %{$_[1]} }, (ref($_[0])||$_[0]));
71}
72
731;