|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Pugs::Runtime::Regex;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # documentation after __END__  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
132
 | 
 use strict;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
849
 | 
    | 
| 
6
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
142
 | 
 use warnings;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1114
 | 
    | 
| 
7
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
113
 | 
 no warnings qw(recursion);  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
990
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use Smart::Comments; #for debugging, look also at Filtered-Comments.pm  | 
| 
10
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
121
 | 
 use Data::Dumper;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1275
 | 
    | 
| 
11
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
122
 | 
 use Pugs::Runtime::Match;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
696
 | 
    | 
| 
12
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
147
 | 
 use Carp qw(croak);  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26623
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # note: alternation is first match (not longest).   | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # note: the list in @$nodes can be modified at runtime  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub alternation {  | 
| 
17
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
  
0
  
 | 
31
 | 
     my $nodes = shift;  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
19
 | 
106
 | 
  
100
  
 | 
 
 | 
  
106
  
 | 
 
 | 
291
 | 
         my @state = $_[1] ? @{$_[1]} : ( 0, undef );  | 
| 
 
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
    | 
| 
20
 | 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
315
 | 
         while ( $state[0] <= $#$nodes ) {  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "alternation $state[0] ",Dumper($nodes->[ $state[0] ]);  | 
| 
22
 | 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
449
 | 
             $nodes->[ $state[0] ]->( $_[0], $state[1], @_[2..7] );  | 
| 
23
 | 
137
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
488
 | 
             last unless defined $_[3];  # test case ???  | 
| 
24
 | 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
397
 | 
             $state[1] = $_[3]->state;  | 
| 
25
 | 
137
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3240
 | 
             $state[0]++ unless $state[1];  | 
| 
26
 | 
137
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
3414
 | 
             if ( $_[3] || $_[3]->data->{abort} ) {  | 
| 
27
 | 
100
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
419
 | 
                 $_[3]->data->{state} = $state[0] > $#$nodes   | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ? undef  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     : \@state;  | 
| 
30
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
245
 | 
                 return;  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
33
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
154
 | 
         $_[3] = failed()->(@_);  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
35
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
132
 | 
 }  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub concat {  | 
| 
38
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
  
0
  
 | 
80
 | 
     my $nodes = shift;  | 
| 
39
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
208
 | 
     $nodes = [ $nodes, @_ ] unless ref($nodes) eq 'ARRAY';  # backwards compat  | 
| 
40
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
120
 | 
     return null()      if ! @$nodes;  | 
| 
41
 | 
58
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
154
 | 
     return $nodes->[0] if @$nodes == 1;  | 
| 
42
 | 
49
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
106
 | 
     if ( @$nodes > 2 ) {  | 
| 
43
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
         return concat(  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             concat( [ $nodes->[0], $nodes->[1] ] ),  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             @$nodes[ 2 .. $#$nodes ],  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
49
 | 
101
 | 
  
100
  
 | 
 
 | 
  
101
  
 | 
 
 | 
553
 | 
         my @state = $_[1] ? @{$_[1]} : ( undef, undef );  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "enter state ",Dumper(\@state);  | 
| 
51
 | 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
140
 | 
         my $m2;  | 
| 
52
 | 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
131
 | 
         my $redo_count = 0;    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # XXX - workaround for t/regex/from_perl6_rules/capture.t test #38:  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # regex single { o | k | e };  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # # ...  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # ok(!( "bokeper" ~~ m/() ($0)/ ), 'Failed positional backref');  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
101
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
106
 | 
         do {  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
114
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
227
 | 
             my %param1 = defined $_[7] ? %{$_[7]} : ();  | 
| 
 
 | 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
253
 | 
    | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "concat 1: @{[ %param1 ]} \n";  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
424
 | 
             $nodes->[0]->( $_[0], $state[0], @_[2..7] );  | 
| 
64
 | 
114
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
403
 | 
             return if ! $_[3]   | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    || $_[3]->data->{abort};  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
286
 | 
             my $is_empty = ( $_[3]->from == $_[3]->to );  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #    && ( $param1{was_empty} )  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #    ; # fix a problem with '^'  | 
| 
70
 | 
90
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
340
 | 
             if ( $is_empty && $param1{was_empty} ) {  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #    # perl5 perlre says "the following match after a zero-length match  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #   is prohibited to have a length of zero"  | 
| 
73
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 return unless $_[3]->from == 0;  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
90
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
163
 | 
             my $param = { ( defined $_[7] ? %{$_[7]} : () ),   | 
| 
 
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
324
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                           p => $_[3]->to,  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                           was_empty => $is_empty,  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         };       | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # TODO - retry the second submatch only, until it fails  | 
| 
81
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
311
 | 
             my $next_state = $_[3]->state;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "next_state ",Dumper($next_state);  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "concat 2: "," \n";  | 
| 
84
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
332
 | 
             $nodes->[1]->( $_[0], $state[1], $_[2], $m2,   | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                            $_[4], $_[3]->to, $_[6], $param );  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               #return if $is_empty && $m2->from == $m2->to;   | 
| 
88
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
317
 | 
             $state[1] = $m2->state;  | 
| 
89
 | 
90
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
575
 | 
             $state[0] = $next_state unless $state[1];  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "concat 3: "," \n";  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "return state ",Dumper(\@state);  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } while    ! $m2   | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 && ! $m2->data->{abort}   | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 && defined $state[0]  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 && $redo_count++ < 512  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ;   | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # push capture data  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # print "Concat positional: ", Dumper( $_[3]->data->{match}, $m2->data->{match} );  | 
| 
101
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
         for ( 0 .. $#{ $m2 } ) {   | 
| 
 
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
205
 | 
    | 
| 
102
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             if ( ref $m2->[$_] eq 'ARRAY' ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # TODO - fully static count  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # push @{ $_[3]->data->{match}[$_] }, @{ $m2->[$_] };  | 
| 
105
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $_[3]->data->{match}[$_] = [  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ( ref( $_[3]->data->{match}[$_] ) eq 'ARRAY'   | 
| 
107
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                       ? @{ $_[3]->data->{match}[$_] }  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       : defined( $_[3]->data->{match}[$_] )   | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       ?    $_[3]->data->{match}[$_]   | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       :    ()   | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ),   | 
| 
112
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     @{ $m2->[$_] },  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ];  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif ( defined $m2->[$_] ) {  | 
| 
116
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $_[3]->data->{match}[$_] = $m2->[$_];  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "Concat named: ", Dumper( $_[3]->data->{named}, $m2->data->{named} );  | 
| 
120
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
123
 | 
         for ( keys %{$m2} ) {  | 
| 
 
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
194
 | 
    | 
| 
121
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             if ( ref $m2->{$_} eq 'ARRAY' ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # TODO - fully static count  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #push @{ $_[3]->data->{named}{$_} }, @{ $m2->{$_} };  | 
| 
124
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $_[3]->data->{named}{$_} = [  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ( ref( $_[3]->data->{named}{$_} ) eq 'ARRAY'  | 
| 
126
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                       ? @{ $_[3]->data->{named}{$_} }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       : defined( $_[3]->data->{named}{$_} )   | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       ?    $_[3]->data->{named}{$_}   | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                       :    ()   | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     ),  | 
| 
131
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     @{ $m2->{$_} },  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ];  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif ( defined $m2->{$_} ) {  | 
| 
135
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $_[3]->data->{named}{$_} = $m2->{$_};  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # /push capture data  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
231
 | 
         %{$_[3]->data} = (  | 
| 
 
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
217
 | 
    | 
| 
141
 | 
77
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
108
 | 
                 %{$_[3]->data},  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool    => \($m2->bool),  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to      => \($m2->to),  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 capture => $m2->data->{capture} || $_[3]->data->{capture},  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort   => $m2->data->{abort},  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 state   => ( defined $state[0] || defined $state[1]   | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              ? \@state   | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              : undef ),  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
151
 | 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
428
 | 
 }  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub try_method {   | 
| 
154
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $method = shift;  | 
| 
155
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $param_list = shift;  # XXX  | 
| 
156
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
158
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2389
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # XXX method call must be inlined, due to inheritance problems  | 
| 
158
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $sub = 'sub {  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $bool = $_[0]->'.$method.'( '.$param_list.' ) ? 1 : 0;  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \$bool,  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }';  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "sub: $sub\n";  | 
| 
170
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return eval $sub;  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub ignorecase {   | 
| 
175
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $sub = shift;  | 
| 
176
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
125
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3411
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
178
 | 
0
 | 
  
  0
  
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my %param = ( ( defined $_[7] ? %{$_[7]} : () ), ignorecase => 1 );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
179
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $sub->( @_[0..6], \%param );  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
181
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub constant {   | 
| 
184
 | 
32
 | 
 
 | 
 
 | 
  
32
  
 | 
  
0
  
 | 
111
 | 
     my $const = shift;  | 
| 
185
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     my $lconst = length( $const );  | 
| 
186
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
160
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3989
 | 
    | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
188
 | 
157
 | 
  
 50
  
 | 
 
 | 
  
157
  
 | 
 
 | 
560
 | 
         my $bool = $_[7]{ignorecase}  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ? lc( $const ) eq lc( substr( $_[0], $_[5], $lconst ) )  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             : $const eq substr( $_[0], $_[5], $lconst );  | 
| 
191
 | 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1290
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \$bool,  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \($_[5] + $lconst),  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
200
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
224
 | 
 }  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub perl5 {  | 
| 
203
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $rx;  | 
| 
204
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
136
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7762
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {   | 
| 
206
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         local $@;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
207
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $rx = eval " use charnames ':full'; qr(^($_[0]))s ";  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "regex perl5<< $_[0] >>\n";  | 
| 
209
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print "Error in perl5 regex: << $_[0] >> \n$@\n"  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if $@;  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #die "Error in perl5 regex: $_[0]"  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #    if $@;  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #use charnames ':full';  | 
| 
216
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $bool;  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         eval {  | 
| 
218
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $bool = $_[7]{ignorecase}  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ? substr( $_[0], $_[5] ) =~ m/(?i)$rx/  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 : substr( $_[0], $_[5] ) =~ m/$rx/;  | 
| 
221
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $_[3] = Pugs::Runtime::Match->new({   | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \$bool,  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \($_[5] + length $1),  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
229
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             1;  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }   | 
| 
231
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         or do {  | 
| 
232
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             die "$@ in perl5 regex: /$rx/";  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
234
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3];  | 
| 
235
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     };  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub null {  | 
| 
239
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
9057
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2897
 | 
    | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
241
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
 
 | 
150
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \1,  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
250
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
0
  
 | 
49
 | 
 };  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub failed {  | 
| 
253
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
128
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2807
 | 
    | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
255
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
58
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \0,  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 state => undef,  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
265
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
  
0
  
 | 
34
 | 
 };  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub failed_abort {  | 
| 
268
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
127
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21730
 | 
    | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
270
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \0,  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort => 1,  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
280
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 };  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub named {  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # return a named capture  | 
| 
284
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $label = shift;  | 
| 
285
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $capture_to_array = shift;    | 
| 
286
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $node = shift;  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
288
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $match;  | 
| 
289
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $node->( @_[0,1,2], $match, @_[4,5,6,7] );  | 
| 
290
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my %matches;  | 
| 
291
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $matches{ $label } = $capture_to_array ? [ $match ] : $match;  | 
| 
292
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $match->bool ),  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \( $match->from ),  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \( $match->to ),  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => \%matches,  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 capture => $match->data->{capture},  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 state => $match->state,  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
303
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
304
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 sub capture { named(@_) } # backwards compat  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub positional {  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # return a positional capture  | 
| 
308
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $num = shift;    | 
| 
309
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $capture_to_array = shift;    | 
| 
310
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $node = shift;  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
312
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $match;  | 
| 
313
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $node->( @_[0,1,2], $match, @_[4,5,6,7] );  | 
| 
314
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my @matches;  | 
| 
315
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $matches[ $num ] = $capture_to_array ? [ $match ] : $match;  | 
| 
316
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $match->bool ),  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \( $match->from ),  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \( $match->to ),  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => \@matches,  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 capture => $match->data->{capture},  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 state => $match->state,  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
327
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub capture_as_result {  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # return a capture as the result object  | 
| 
331
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $node = shift;  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub {  | 
| 
333
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $match;  | 
| 
334
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $node->( @_[0,1,2], $match, @_[4,5,6,7] );  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $match->bool ),  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \( $match->from ),  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \( $match->to ),  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 capture => (   | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     sub {  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         # print "Match: ", Dumper( $match );  | 
| 
345
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                         '' . $match   | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }   | 
| 
347
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 ),  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 state => $match->state,  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
351
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 }  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub ___abort {   | 
| 
354
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my $op = shift;  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
356
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         print "ABORTING\n";  | 
| 
357
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $op->( @_ );  | 
| 
358
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print "ABORT: [0] ",Dumper(@_);  #$_[3]->perl;  | 
| 
359
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3]->data->{abort} = 1;  | 
| 
360
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         print "ABORT: ",$_[3]->perl;  | 
| 
361
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     };  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub ___fail {   | 
| 
365
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my $op = shift;  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return abort(   | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sub {  | 
| 
368
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
             print "FAILING\n";  | 
| 
369
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $op->( @_ );  | 
| 
370
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $_[3]->data->{bool} = \0;  | 
| 
371
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             print "FAIL: ",Dumper( $_[3] );  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }   | 
| 
373
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     );  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub before {   | 
| 
377
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $op = shift;  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
379
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $match;  | 
| 
380
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $op->( @_[0,1,2], $match, @_[4,5,6,7] );  | 
| 
381
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $match->bool ),  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \( $match->from ),  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \( $match->from ),  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 state => $match->state,  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
390
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     };  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub at_start {  | 
| 
394
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
169
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3257
 | 
    | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
396
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $_[5] == 0 ),  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort => 0,  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
406
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 };  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub at_line_start {  | 
| 
409
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
274
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3973
 | 
    | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
411
 | 
0
 | 
 
 | 
  
  0
  
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $bool = $_[5] == 0  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ||  substr( $_[0], 0, $_[5] ) =~ /\n$/s;  | 
| 
413
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \$bool,  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort => 0,  | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
423
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 };  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub at_line_end {  | 
| 
426
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
124
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4000
 | 
    | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
428
 | 
0
 | 
 
 | 
  
  0
  
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $bool = $_[5] >= length( $_[0] )  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ||  substr( $_[0], $_[5] ) =~ /^\n/s;  | 
| 
430
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \$bool,  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort => 0,  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
440
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 };  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub at_end_of_string {  | 
| 
443
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
 
 | 
137
 | 
     no warnings qw( uninitialized );  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51342
 | 
    | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
445
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $_[5] == length( $_[0] ) ),  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort => 0,  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
455
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 };  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # experimental!  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub negate {   | 
| 
459
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $op = shift;  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #my $str = $_[0];  | 
| 
462
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
         my $match = $op->( @_ );  | 
| 
463
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $bool = ! $match;  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $_[3] = Pugs::Runtime::Match->new({   | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool  => \( $bool ),  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str   => \$_[0],  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from  => \(0 + $_[5]),  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to    => \(0 + $_[5]),  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 abort => 0,  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             });  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
475
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     };  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ------- higher-order ruleops  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub optional {  | 
| 
481
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
0
  
 | 
12
 | 
     my $node = shift;  | 
| 
482
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     alternation( [ $node, null() ] );  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub null_or_optional {  | 
| 
486
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     my $node = shift;  | 
| 
487
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     alternation( [ null(), $node ] );  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub greedy_star {   | 
| 
491
 | 
2
 | 
 
 | 
  
 50
  
 | 
  
2
  
 | 
  
0
  
 | 
22
 | 
     greedy_plus( $_[0], $_[1] || 0, $_[2] )   | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub non_greedy_star {   | 
| 
495
 | 
0
 | 
 
 | 
  
  0
  
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
     non_greedy_plus( $_[0], $_[1] || 0, $_[2] )   | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # XXX - needs optimization for faster backtracking, less stack usage  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # TODO - run-time ranges (iterator)  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub greedy_plus {   | 
| 
501
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
0
  
 | 
9
 | 
     my $node = shift;  | 
| 
502
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $min_count = defined( $_[0] ) ? $_[0] : 1;  | 
| 
503
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $max_count = $_[1];    | 
| 
504
 | 
5
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
18
 | 
     if (  defined $max_count   | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        && $max_count < 1e99  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        ) {  | 
| 
507
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return concat( [   | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ( $node )             x $min_count,   | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ( optional( $node ) ) x ($max_count - $min_count)   | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ] );  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # $max_count == infinity  | 
| 
513
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $alt;  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $alt = concat( [  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $node,   | 
| 
516
 | 
5
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
28
 | 
         optional( sub{ goto $alt } ),    | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
225
 | 
    | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ] );  | 
| 
518
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     return optional( $alt ) if $min_count < 1;  | 
| 
519
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     return concat( [ ( $node ) x ($min_count - 1), $alt ] );  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # XXX - needs optimization for faster backtracking, less stack usage  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # TODO - run-time ranges (iterator)  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub non_greedy_plus {   | 
| 
525
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
10
 | 
     my $node = shift;  | 
| 
526
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     my $min_count = defined( $_[0] ) ? $_[0] : 1;  | 
| 
527
 | 
6
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
24
 | 
     my $max_count = $_[1] || 1e99;  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
529
 | 
21
 | 
 
 | 
  
100
  
 | 
  
21
  
 | 
 
 | 
133
 | 
         my $state = $_[1]   | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             || { node  => concat( [ ( $node ) x $min_count ] ),   | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  count => $min_count };  | 
| 
532
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
66
 | 
         return failed()->(@_)  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if $state->{count} > $max_count;  | 
| 
534
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
166
 | 
         $state->{node}->( $_[0], undef, @_[2..7] );  | 
| 
535
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
134
 | 
         $_[3]->data->{state} =   | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             { node  => concat( [ $node, $state->{node} ] ),   | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               count => $state->{count} + 1 };  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
539
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
 }  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub range {  | 
| 
542
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
     my $node = shift;  | 
| 
543
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $min_count = shift;  | 
| 
544
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $max_count = shift;  | 
| 
545
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $greedy = not shift;  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return sub {  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
548
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
         my $continuation = $_[1]; #XXX how do optional continuations work?  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Forward declarations  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
552
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $try_getting_more;  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $default_behavior;  | 
| 
555
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $fallback_behavior;  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Loop variables  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
559
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $count = 0;  | 
| 
560
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $previous_pos = -1;  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Loop 1 - getting to min_count  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
564
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $continue_towards_min;  | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $get_minimum = sub {  | 
| 
566
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if ( $count < $min_count ) {  | 
| 
567
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $count++;  | 
| 
568
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 goto &$continue_towards_min;  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
570
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 goto &$try_getting_more;  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
572
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
573
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $continue_towards_min = concat( [ $node, $get_minimum ] );  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Loop 2 - beyond the minimum  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $try_getting_more = sub {  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             my $current_pos = $_[5];  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # (1) Stop when max_count is reached, or if pos does not move.  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
             if ( !( $count < $max_count ) ||  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  !( $previous_pos < $current_pos ) )  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             {  | 
| 
586
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 goto &$continuation;  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
588
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $count++;  | 
| 
589
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $previous_pos = $current_pos;  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # (2) Attempt the default behavior.  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # XXX - This section needs to be filled in.  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # try $default_behavior  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #  if successful, return.  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #  if abort, do whatever is needed.  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #  if fail, we need to backtrack:  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #    undo any side-effects from trying the $default_behavior,  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #    so we can do the $fallback_behavior.  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # (3) Since the default behavior failed, do the fall-back beharvior.  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             goto &$fallback_behavior;  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
605
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
606
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $get_one_and_maybe_more = concat( [ $node, $try_getting_more ] );  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Final preparations.  | 
| 
609
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
610
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if ( $greedy ) {  | 
| 
611
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $default_behavior = $get_one_and_maybe_more;  | 
| 
612
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $fallback_behavior = $continuation;  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else { # non-greedy  | 
| 
614
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $default_behavior = $continuation;  | 
| 
615
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $fallback_behavior = $get_one_and_maybe_more;  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Start.  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
620
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         goto &$get_minimum;  | 
| 
621
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub preprocess_hash {  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # TODO - move to Pugs::Runtime::Regex  | 
| 
627
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
     my ( $h, $key ) = @_;  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # returns AST depending on $h  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "preprocess_hash: ", Dumper( \@_ );  | 
| 
630
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( ref( $h->{$key} ) eq 'CODE') {  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {   | 
| 
632
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
             my ( $str, $grammar, $args ) = @_;  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "data: ", Dumper( \@_ );  | 
| 
634
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             my $ret = $h->{$key}->( @_ );   | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "ret: ", Dumper( $ret );  | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
637
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             return $ret   | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 if ref( $ret ) eq 'Pugs::Runtime::Match';  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
640
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
             Pugs::Runtime::Match->new( {   | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool => \1,   | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str =>  \$str,  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from => \( 0 + ( $args->{p} || 0 ) ),  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to =>   \( 0 + ( $args->{p} || 0 ) ),  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } ) }  | 
| 
648
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }   | 
| 
649
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( ref( $h->{$key} ) =~ /Pugs::Compiler::/ ) {  | 
| 
650
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
         return sub { $h->{$key}->match( @_ ) };  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # fail is number != 1   | 
| 
653
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( $h->{$key} =~ /^(\d+)$/ ) {  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {   | 
| 
655
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
             my ( $str, $grammar, $args ) = @_;  | 
| 
656
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
             Pugs::Runtime::Match->new( {   | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool => \0,   | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str =>  \$str,  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from => \( 0 + ( $args->{p} || 0 ) ),  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to =>   \( 0 + ( $args->{p} || 0 ) ),  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
663
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } ) } unless $1 == 1;  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return sub {   | 
| 
665
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
             my ( $str, $grammar, $args ) = @_;  | 
| 
666
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
             Pugs::Runtime::Match->new( {   | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bool => \1,   | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 str =>  \$str,  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 from => \( 0 + ( $args->{p} || 0 ) ),  | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 to =>   \( 0 + ( $args->{p} || 0 ) ),  | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 named => {},  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 match => [],  | 
| 
673
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } ) };  | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # subrule  | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "compile: ",$h->{$key}, "\n";  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # XXX - compile to Token or to Regex ? (v6.pm needs Token)  | 
| 
679
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $r = Pugs::Compiler::Token->compile( $h->{$key} );  | 
| 
680
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $h->{$key} = $r;  | 
| 
681
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     return sub { $r->match( @_ ) };  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # return sub { warn "uncompiled subrule: $h->{$key} - not implemented " };  | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # see commit #9783 for an alternate implementation  | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub hash {  | 
| 
687
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
     my %hash = %{shift()};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "HASH: @{[ %hash ]}\n";  | 
| 
689
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @keys = sort {length $b <=> length $a } keys %hash;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "hash keys [ @keys ]\n";  | 
| 
691
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     for ( @keys ) {  | 
| 
692
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $h = preprocess_hash( \%hash, $_ );  | 
| 
693
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $key = $_;  | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $_ =   | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           concat( [  | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             constant( $key ),  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             sub {   | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # print "hash param: ",Dumper(\@_);  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # TODO - add $ to $_[7]  | 
| 
700
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
               $_[3] = $h->( $_[0], $_[4], $_[7], $_[1] );  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               # print "result: ",Dumper($_[3]);  | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
703
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           ] );  | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
705
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return alternation( \@keys );  | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # not a 'rule node'  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # gets a variable from the user's pad  | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # this is used by the <$var> rule  | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_variable {  | 
| 
712
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
 
 | 
     my $name = shift;  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
714
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     local $@;  | 
| 
715
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my($idx, $pad) = 0;  | 
| 
716
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     while(eval { require PadWalker; $pad = PadWalker::peek_my($idx) }) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
717
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $idx++, next  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           unless exists $pad->{$name};  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "NAME $name $pad->{$name}\n";  | 
| 
721
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return ${ $pad->{$name} } if $name =~ /^\$/;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
722
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return $pad->{$name};  # arrayref/hashref  | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
724
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "Couldn't find '$name' in surrounding lexical scope.";  | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |