File Coverage

blib/lib/PERLANCAR/Parse/Arithmetic/NoHash.pm
Criterion Covered Total %
statement 27 27 100.0
branch 3 6 50.0
condition n/a
subroutine 5 5 100.0
pod 1 1 100.0
total 36 39 92.3


line stmt bran cond sub pod time code
1             package PERLANCAR::Parse::Arithmetic::NoHash;
2              
3             our $DATE = '2016-06-18'; # DATE
4             our $VERSION = '0.003'; # VERSION
5              
6 1     1   456 use 5.010001;
  1         2  
7 1     1   2 use strict;
  1         2  
  1         13  
8 1     1   2 use warnings;
  1         1  
  1         28  
9              
10             my ($match_top,
11             $match_add, $match_op_add,
12             $match_mult, $match_op_mult,
13             $match_pow,
14             );
15              
16 1     1   3 use Exporter qw(import);
  1         1  
  1         344  
17             our @EXPORT_OK = qw(parse_arithmetic);
18              
19             sub parse_arithmetic {
20             state $RE =
21             qr{
22             (?&TOP)
23             (?{
24 3         27 $match_top = $^R;
25             })
26              
27             (?(DEFINE)
28              
29             (?
30             ^\s* (?&EXPR) \s*$
31             )
32              
33             (?
34             (?&MULT_EXPR)
35             (?{
36 4         9 $match_add = $^R
37             })
38             (?: \s* ([+-])
39             (?{
40 2         22 $match_op_add = $^N;
41             })
42             \s* (?&MULT_EXPR)
43             (?{
44 2 50       10 $match_add = $match_op_add eq '+' ? $match_add + $^R : $match_add - $^R;
45             })
46             )*
47             )
48              
49             (?
50             (?&POW_EXPR)
51             (?{
52 6         12 $match_mult = $^R;
53             })
54             (?: \s* ([*/])
55             (?{
56 2         14 $match_op_mult = $^N;
57             }) \s*
58             (?&POW_EXPR)
59             (?{
60 2 50       11 $match_mult = $match_op_mult eq '*' ? $match_mult * $^R : $match_mult / $^R;
61             })
62             )*
63             )
64              
65             (?
66             (?&TERM)
67             (?{
68 8         21 $match_pow = [$^R];
69             })
70             (?: \s* \*\* \s* (?&TERM)
71             (?{
72 2         9 unshift @$match_pow, $^R;
73             })
74             )*
75             (?{
76             # because ** is right-to-left, we collect first then
77             # apply from right to left
78 8         15 my $res = $match_pow->[0];
79 8         9 for (1..$#{$match_pow}) {
  8         18  
80 2         4 $res = $match_pow->[$_] ** $res;
81             }
82             $res;
83             })
84             )
85              
86             (?
87             \( \s* (?&EXPR)
88             (?{
89             $^R;
90             })
91             \s* \)
92             | (?&LITERAL)
93             (?{
94             $^R;
95             })
96             )
97              
98             (?
99             (-?(?:\d+|\d*\.\d+))
100             (?{
101             $^N;
102             })
103             )
104             )
105 3     3 1 20 }x;
106 3 50       31 $_[0] =~ $RE or return undef;
107 3         12 $match_top;
108             }
109              
110             1;
111             # ABSTRACT: Parse arithmetic expmatchsion
112              
113             __END__