| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package JE::Parser; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.066'; |
|
4
|
|
|
|
|
|
|
|
|
5
|
101
|
|
|
101
|
|
43477
|
use strict; # :-( |
|
|
101
|
|
|
|
|
148
|
|
|
|
101
|
|
|
|
|
3897
|
|
|
6
|
101
|
|
|
101
|
|
487
|
use warnings;# :-( |
|
|
101
|
|
|
|
|
157
|
|
|
|
101
|
|
|
|
|
2827
|
|
|
7
|
101
|
|
|
101
|
|
459
|
no warnings 'utf8'; |
|
|
101
|
|
|
|
|
157
|
|
|
|
101
|
|
|
|
|
3966
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
101
|
|
|
101
|
|
493
|
use Scalar::Util 'blessed'; |
|
|
101
|
|
|
|
|
211
|
|
|
|
101
|
|
|
|
|
56785
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require JE::Code ; |
|
12
|
|
|
|
|
|
|
require JE::Number; # ~~~ Don't want to do this |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
import JE::Code 'add_line_number'; |
|
15
|
|
|
|
|
|
|
sub add_line_number; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our ($_parser, $global, @_decls, @_stms, $_vars); |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
#----------METHODS---------# |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub new { |
|
22
|
2
|
|
|
2
|
1
|
659
|
my %self = ( |
|
23
|
|
|
|
|
|
|
stm_names => [qw[ |
|
24
|
|
|
|
|
|
|
-function block empty if while with for switch try |
|
25
|
|
|
|
|
|
|
labelled var do continue break return throw expr |
|
26
|
|
|
|
|
|
|
]], |
|
27
|
|
|
|
|
|
|
stm => { |
|
28
|
|
|
|
|
|
|
-function => \&function, block => \&block, |
|
29
|
|
|
|
|
|
|
empty => \&empty, if => \&if, |
|
30
|
|
|
|
|
|
|
while => \&while, with => \&with, |
|
31
|
|
|
|
|
|
|
for => \&for, switch => \&switch, |
|
32
|
|
|
|
|
|
|
try => \&try, labelled => \&labelled, |
|
33
|
|
|
|
|
|
|
var => \&var, do => \&do, |
|
34
|
|
|
|
|
|
|
continue => \&continue, break => \&break, |
|
35
|
|
|
|
|
|
|
return => \&return, throw => \&throw, |
|
36
|
|
|
|
|
|
|
expr => \&expr_statement, |
|
37
|
|
|
|
|
|
|
}, |
|
38
|
|
|
|
|
|
|
global => pop, |
|
39
|
|
|
|
|
|
|
); |
|
40
|
2
|
|
|
|
|
15
|
return bless \%self, shift; |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub add_statement { |
|
44
|
0
|
|
|
0
|
1
|
0
|
my($self,$name,$parser) = shift; |
|
45
|
0
|
|
|
|
|
0
|
my $in_list; |
|
46
|
|
|
|
|
|
|
# no warnings 'exiting'; |
|
47
|
0
|
|
|
|
|
0
|
grep $_ eq $name && ++$in_list && goto END_GREP, |
|
48
|
0
|
|
0
|
|
|
0
|
@{$$self{stm_names}}; |
|
49
|
0
|
|
|
|
|
0
|
END_GREP: |
|
50
|
0
|
0
|
|
|
|
0
|
$in_list or unshift @{$$self{stm_names}} ,$name; |
|
51
|
0
|
|
|
|
|
0
|
$$self{stm}{$name} = $parser; |
|
52
|
0
|
|
|
|
|
0
|
return; # Don't return anything for now, because if we return some- |
|
53
|
|
|
|
|
|
|
# thing, even if it's not documented, someone might start |
|
54
|
|
|
|
|
|
|
# relying on it. |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub delete_statement { |
|
58
|
1
|
|
|
1
|
1
|
401
|
my $self = shift; |
|
59
|
1
|
|
|
|
|
4
|
for my $name (@_) { |
|
60
|
4
|
|
|
|
|
21
|
delete $$self{stm}{$name}; |
|
61
|
4
|
|
|
|
|
22
|
@{$$self{stm_names}} = |
|
|
4
|
|
|
|
|
18
|
|
|
62
|
4
|
|
|
|
|
5
|
grep $_ ne $name, @{$$self{stm_names}}; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
1
|
|
|
|
|
3
|
return $self; |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub statement_list { |
|
68
|
2
|
|
|
2
|
1
|
21
|
$_[0]{stm_names}; |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub parse { |
|
72
|
11
|
|
|
11
|
1
|
20
|
local $_parser = shift; |
|
73
|
11
|
|
|
|
|
23
|
local(@_decls, @_stms); # Doing this here and localising it saves |
|
74
|
11
|
|
|
|
|
13
|
for(@{$_parser->{stm_names}}) { # us from having to do it multiple |
|
|
11
|
|
|
|
|
35
|
|
|
75
|
143
|
50
|
|
|
|
140
|
push @{/^-/ ? \@_decls : \@_stms}, # times. |
|
|
143
|
|
|
|
|
453
|
|
|
76
|
|
|
|
|
|
|
$_parser->{stm}{$_}; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
11
|
|
|
|
|
59
|
JE::Code::parse($_parser->{global}, @_); |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub eval { |
|
83
|
4
|
|
|
4
|
1
|
21
|
shift->parse(@_)->execute |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
#----------PARSER---------# |
|
87
|
|
|
|
|
|
|
|
|
88
|
101
|
|
|
101
|
|
645
|
use Exporter 5.57 'import'; |
|
|
101
|
|
|
|
|
2983
|
|
|
|
101
|
|
|
|
|
9041
|
|
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
our @EXPORT_OK = qw/ $h $n $optional_sc $ss $s $S $id_cont |
|
91
|
|
|
|
|
|
|
str num skip ident expr expr_noin statement |
|
92
|
|
|
|
|
|
|
statements expected optional_sc/; |
|
93
|
|
|
|
|
|
|
our @EXPORT_TAGS = ( |
|
94
|
|
|
|
|
|
|
vars => [qw/ $h $n $optional_sc $ss $s $S $id_cont/], |
|
95
|
|
|
|
|
|
|
functions => [qw/ str num skip ident expr expr_noin statement |
|
96
|
|
|
|
|
|
|
statements expected optional_sc /], |
|
97
|
|
|
|
|
|
|
); |
|
98
|
|
|
|
|
|
|
|
|
99
|
101
|
|
|
101
|
|
579
|
use re 'taint'; |
|
|
101
|
|
|
|
|
150
|
|
|
|
101
|
|
|
|
|
4815
|
|
|
100
|
|
|
|
|
|
|
#use subs qw'statement statements assign assign_noin expr new'; |
|
101
|
101
|
|
|
101
|
|
517
|
use constant JECE => 'JE::Code::Expression'; |
|
|
101
|
|
|
|
|
232
|
|
|
|
101
|
|
|
|
|
6895
|
|
|
102
|
101
|
|
|
101
|
|
537
|
use constant JECS => 'JE::Code::Statement'; |
|
|
101
|
|
|
|
|
162
|
|
|
|
101
|
|
|
|
|
14935
|
|
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
require JE::String; |
|
105
|
|
|
|
|
|
|
import JE::String 'desurrogify'; |
|
106
|
|
|
|
|
|
|
import JE::String 'surrogify'; |
|
107
|
|
|
|
|
|
|
sub desurrogify($); |
|
108
|
|
|
|
|
|
|
sub surrogify($); |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# die is called with a scalar ref when the string contains what is |
|
112
|
|
|
|
|
|
|
# expected. This will be converted to a longer message afterwards, which |
|
113
|
|
|
|
|
|
|
# will read something like "Expected %s but found %s" (probably the most |
|
114
|
|
|
|
|
|
|
# common error message, which is why there is a shorthand). Using an array |
|
115
|
|
|
|
|
|
|
# ref is the easiest way to stop the 'at ..., line ...' from being appended |
|
116
|
|
|
|
|
|
|
# when there is no line break at the end already. die is called with a |
|
117
|
|
|
|
|
|
|
# double reference to a string if the string is the complete error |
|
118
|
|
|
|
|
|
|
# message. |
|
119
|
|
|
|
|
|
|
# ~~~ We may need a function for this second usage, in case we change the |
|
120
|
|
|
|
|
|
|
# \\ yet again. |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# @ret != push @ret, ... is a funny way of pushing and then checking to |
|
123
|
|
|
|
|
|
|
# see whether anything was pushed. |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub expected($) { # public |
|
127
|
21
|
|
|
21
|
0
|
205
|
die \shift |
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# public vars: |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# optional horizontal comments and whitespace |
|
134
|
|
|
|
|
|
|
our $h = qr( |
|
135
|
|
|
|
|
|
|
(?> [ \t\x0b\f\xa0\p{Zs}]* ) |
|
136
|
|
|
|
|
|
|
(?> (?>/\*[^\cm\cj\x{2028}\x{2029}]*?\*/) [ \t\x0b\f\xa0\p{Zs}]* )? |
|
137
|
1
|
|
|
1
|
|
540
|
)x; |
|
|
1
|
|
|
|
|
8
|
|
|
|
1
|
|
|
|
|
10
|
|
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# line terminators |
|
140
|
|
|
|
|
|
|
our $n = qr((?>[\cm\cj\x{2028}\x{2029}])); |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# single space char |
|
143
|
|
|
|
|
|
|
our $ss = qr((?>[\p{Zs}\s\ck\x{2028}\x{2029}])); |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# optional comments and whitespace |
|
146
|
|
|
|
|
|
|
our $s = qr((?> |
|
147
|
|
|
|
|
|
|
(?> $ss* ) |
|
148
|
|
|
|
|
|
|
(?> (?> //[^\cm\cj\x{2028}\x{2029}]* (?>$n|\z) | /\*.*?\*/ ) |
|
149
|
|
|
|
|
|
|
(?> $ss* ) |
|
150
|
|
|
|
|
|
|
) * |
|
151
|
|
|
|
|
|
|
))sx; |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# mandatory comments/whitespace |
|
154
|
|
|
|
|
|
|
our $S = qr( |
|
155
|
|
|
|
|
|
|
(?> |
|
156
|
|
|
|
|
|
|
$ss |
|
157
|
|
|
|
|
|
|
| |
|
158
|
|
|
|
|
|
|
//[^\cm\cj\x{2028}\x{2029}]* |
|
159
|
|
|
|
|
|
|
| |
|
160
|
|
|
|
|
|
|
/\*.*?\*/ |
|
161
|
|
|
|
|
|
|
) |
|
162
|
|
|
|
|
|
|
$s |
|
163
|
|
|
|
|
|
|
)xs; |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
our $id_cont = qr( |
|
166
|
|
|
|
|
|
|
(?> |
|
167
|
|
|
|
|
|
|
\\u([0-9A-Fa-f]{4}) |
|
168
|
|
|
|
|
|
|
| |
|
169
|
|
|
|
|
|
|
[\p{ID_Continue}\$_] |
|
170
|
|
|
|
|
|
|
) |
|
171
|
|
|
|
|
|
|
)x; |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# end public vars |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub str() { # public |
|
177
|
|
|
|
|
|
|
# For very long strings (>~45000), this pattern hits a perl bug (Complex regular subexpression recursion limit (32766) exceeded) |
|
178
|
|
|
|
|
|
|
#/\G (?: '((?>(?:[^'\\] | \\.)*))' |
|
179
|
|
|
|
|
|
|
# | |
|
180
|
|
|
|
|
|
|
# "((?>(?:[^"\\] | \\.)*))" )/xcgs or return; |
|
181
|
|
|
|
|
|
|
# There are two solutions: |
|
182
|
|
|
|
|
|
|
# 1) Use the unrolling technique from the Owl Book. |
|
183
|
|
|
|
|
|
|
# 2) Use shorter patterns but more code (contributed by Kevin |
|
184
|
|
|
|
|
|
|
# Cameron) |
|
185
|
|
|
|
|
|
|
# Number 1 should be faster, but it crashes under perl 5.8.8 on |
|
186
|
|
|
|
|
|
|
# Windows, and perhaps on other platforms, too. So we use #2 for |
|
187
|
|
|
|
|
|
|
# 5.8.x regardless of platform to be on the safe side. |
|
188
|
|
|
|
|
|
|
|
|
189
|
101
|
|
|
101
|
|
228300
|
use constant old_perl => $] < 5.01; # Use a constant so the |
|
|
101
|
|
|
|
|
219
|
|
|
|
101
|
|
|
|
|
31087
|
|
|
190
|
42085
|
|
|
42085
|
0
|
83859
|
my $yarn; # if-block disappears |
|
191
|
42085
|
|
|
|
|
36777
|
if(old_perl) { # at compile-time. |
|
192
|
|
|
|
|
|
|
# Use a simpler pattern (but more code) to break strings up |
|
193
|
|
|
|
|
|
|
# into extents bounded by the quote or escape |
|
194
|
|
|
|
|
|
|
my $qt = substr($_,pos($_),1); |
|
195
|
|
|
|
|
|
|
$qt =~ /['"]/ or return; # not a string literal if first |
|
196
|
|
|
|
|
|
|
pos($_)++; # char not a quote |
|
197
|
|
|
|
|
|
|
my $done = 0; |
|
198
|
|
|
|
|
|
|
while (defined(substr($_,pos($_),1))) { |
|
199
|
|
|
|
|
|
|
my ($part) = /\G([^\\$qt]*)/xcgs; |
|
200
|
|
|
|
|
|
|
defined($part) or $part = ""; |
|
201
|
|
|
|
|
|
|
$yarn .= $part; |
|
202
|
|
|
|
|
|
|
my $next = substr($_,pos($_)++,1); |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
if ($next eq "\\") { |
|
205
|
|
|
|
|
|
|
#pass on any escaped char |
|
206
|
|
|
|
|
|
|
$next = substr($_,pos($_)++,1); |
|
207
|
|
|
|
|
|
|
$yarn .= "\\$next"; |
|
208
|
|
|
|
|
|
|
} else { |
|
209
|
|
|
|
|
|
|
# handle end quote |
|
210
|
|
|
|
|
|
|
$done = 1; |
|
211
|
|
|
|
|
|
|
last; |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# error if EOF before end of string |
|
216
|
|
|
|
|
|
|
return if !$done; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
else { |
|
219
|
42085
|
100
|
|
|
|
205166
|
/\G (?: '([^'\\]*(?:\\.[^'\\]*)*)' |
|
220
|
|
|
|
|
|
|
| |
|
221
|
|
|
|
|
|
|
"([^"\\]*(?:\\.[^"\\]*)*)" )/xcgs or return; |
|
222
|
9838
|
|
|
|
|
24528
|
$yarn = $+; |
|
223
|
|
|
|
|
|
|
} |
|
224
|
|
|
|
|
|
|
# Get rid of that constant, as it’s no longer needed. |
|
225
|
101
|
|
|
101
|
|
614
|
BEGIN { no strict; delete ${__PACKAGE__.'::'}{old_perl}; } |
|
|
101
|
|
|
101
|
|
171
|
|
|
|
101
|
|
|
|
|
4640
|
|
|
|
101
|
|
|
|
|
181
|
|
|
|
101
|
|
|
|
|
2456
|
|
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# transform special chars |
|
228
|
101
|
|
|
101
|
|
546
|
no re 'taint'; # I need eval "qq-..." to work |
|
|
101
|
|
|
|
|
181
|
|
|
|
101
|
|
|
|
|
42159
|
|
|
229
|
9838
|
|
|
|
|
19780
|
$yarn =~ s/\\(?: |
|
230
|
|
|
|
|
|
|
u([0-9a-fA-F]{4}) |
|
231
|
|
|
|
|
|
|
| |
|
232
|
|
|
|
|
|
|
x([0-9a-fA-F]{2}) |
|
233
|
|
|
|
|
|
|
| |
|
234
|
|
|
|
|
|
|
(\r\n?|[\n\x{2028}\x{2029}]) |
|
235
|
|
|
|
|
|
|
| |
|
236
|
|
|
|
|
|
|
([bfnrt]) |
|
237
|
|
|
|
|
|
|
| |
|
238
|
|
|
|
|
|
|
(v) |
|
239
|
|
|
|
|
|
|
| |
|
240
|
|
|
|
|
|
|
([0-3][0-7]{0,2}|[4-7][0-7]?) # actually slightly looser |
|
241
|
|
|
|
|
|
|
| # than what ECMAScript v3 has in its |
|
242
|
|
|
|
|
|
|
(.) # addendum (it forbids \0 when followed by 8) |
|
243
|
|
|
|
|
|
|
)/ |
|
244
|
22012
|
100
|
|
|
|
175275
|
$1 ? chr(hex $1) : |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
$2 ? chr(hex $2) : |
|
246
|
|
|
|
|
|
|
$3 ? "" : # escaped line feed disappears |
|
247
|
|
|
|
|
|
|
$4 ? eval "qq-\\$4-" : |
|
248
|
|
|
|
|
|
|
$5 ? "\cK" : |
|
249
|
|
|
|
|
|
|
defined $6 ? chr oct $6 : |
|
250
|
|
|
|
|
|
|
$7 |
|
251
|
|
|
|
|
|
|
/sgex; |
|
252
|
9838
|
|
|
|
|
44389
|
"s$yarn"; |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub num() { # public |
|
256
|
32247
|
100
|
|
32247
|
0
|
369852
|
/\G (?: |
|
257
|
|
|
|
|
|
|
0[Xx] ([A-Fa-f0-9]+) |
|
258
|
|
|
|
|
|
|
| |
|
259
|
|
|
|
|
|
|
0 ([01234567]+) |
|
260
|
|
|
|
|
|
|
| |
|
261
|
|
|
|
|
|
|
(?=[0-9]|\.[0-9]) |
|
262
|
|
|
|
|
|
|
( |
|
263
|
|
|
|
|
|
|
(?:0|[1-9][0-9]*)? |
|
264
|
|
|
|
|
|
|
(?:\.[0-9]*)? |
|
265
|
|
|
|
|
|
|
(?:[Ee][+-]?[0-9]+)? |
|
266
|
|
|
|
|
|
|
) |
|
267
|
|
|
|
|
|
|
) /xcg |
|
268
|
|
|
|
|
|
|
or return; |
|
269
|
21597
|
100
|
|
|
|
131163
|
return defined $1 ? hex $1 : defined $2 ? oct $2 : $3; |
|
|
|
100
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
our $ident = qr( |
|
273
|
|
|
|
|
|
|
(?! (?: case | default ) (?!$id_cont) ) |
|
274
|
|
|
|
|
|
|
(?: |
|
275
|
|
|
|
|
|
|
\\u[0-9A-Fa-f]{4} |
|
276
|
|
|
|
|
|
|
| |
|
277
|
|
|
|
|
|
|
[\p{ID_Start}\$_] |
|
278
|
|
|
|
|
|
|
) |
|
279
|
|
|
|
|
|
|
(?> $id_cont* ) |
|
280
|
|
|
|
|
|
|
)x; |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub unescape_ident($) { |
|
283
|
23697
|
|
|
23697
|
0
|
31991
|
my $ident = shift; |
|
284
|
23697
|
|
|
|
|
31158
|
$ident =~ s/\\u([0-9a-fA-F]{4})/chr hex $1/ge; |
|
|
18
|
|
|
|
|
126
|
|
|
285
|
23697
|
|
|
|
|
64095
|
$ident = desurrogify $ident; |
|
286
|
23697
|
100
|
|
|
|
90301
|
$ident =~ /^[\p{ID_Start}\$_] |
|
287
|
|
|
|
|
|
|
[\p{ID_Continue}\$_]* |
|
288
|
|
|
|
|
|
|
\z/x |
|
289
|
|
|
|
|
|
|
or die \\"'$ident' is not a valid identifier"; |
|
290
|
23696
|
|
|
|
|
118828
|
$ident; |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# public |
|
294
|
34806
|
|
|
34806
|
0
|
168471
|
sub skip() { /\G$s/g } # skip whitespace |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
sub ident() { # public |
|
297
|
6483
|
100
|
|
6483
|
0
|
44785
|
return unless my($ident) = /\G($ident)/cgox; |
|
298
|
5553
|
|
|
|
|
76073
|
unescape_ident $ident; |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
sub params() { # Only called when we know we need it, which is why it dies |
|
302
|
|
|
|
|
|
|
# on the second line |
|
303
|
364
|
|
|
364
|
0
|
480
|
my @ret; |
|
304
|
364
|
50
|
|
|
|
1301
|
/\G\(/gc or expected "'('"; |
|
305
|
364
|
|
|
|
|
658
|
&skip; |
|
306
|
364
|
100
|
|
|
|
1853
|
if (@ret != push @ret, &ident) { # first identifier (not prec. |
|
307
|
|
|
|
|
|
|
# by comma) |
|
308
|
111
|
|
|
|
|
1540
|
while (/\G$s,$s/gc) { |
|
309
|
|
|
|
|
|
|
# if there's a comma we need another ident |
|
310
|
100
|
100
|
|
|
|
8495
|
@ret != push @ret, &ident or expected 'identifier'; |
|
311
|
|
|
|
|
|
|
} |
|
312
|
109
|
|
|
|
|
2681
|
&skip; |
|
313
|
|
|
|
|
|
|
} |
|
314
|
362
|
100
|
|
|
|
1278
|
/\G\)/gc or expected "')'"; |
|
315
|
360
|
|
|
|
|
890
|
\@ret; |
|
316
|
|
|
|
|
|
|
} |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
sub term() { |
|
319
|
61769
|
|
|
61769
|
0
|
102415
|
my $pos = pos; |
|
320
|
61769
|
|
|
|
|
52231
|
my $tmp; |
|
321
|
61769
|
100
|
100
|
|
|
439107
|
if(/\Gfunction(?!$id_cont)$s/cg) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
322
|
163
|
|
|
|
|
468
|
my @ret = (func => ident); |
|
323
|
163
|
100
|
|
|
|
4264
|
@ret == 2 and &skip; |
|
324
|
163
|
|
|
|
|
387
|
push @ret, ¶ms; |
|
325
|
163
|
|
|
|
|
330
|
&skip; |
|
326
|
163
|
50
|
|
|
|
591
|
/\G \{ /gcx or expected "'{'"; |
|
327
|
|
|
|
|
|
|
{ |
|
328
|
163
|
|
|
|
|
204
|
local $_vars = []; |
|
|
163
|
|
|
|
|
327
|
|
|
329
|
163
|
|
|
|
|
394
|
push @ret, &statements, $_vars; |
|
330
|
|
|
|
|
|
|
} |
|
331
|
163
|
50
|
|
|
|
774
|
/\G \} /gocx or expected "'}'"; |
|
332
|
|
|
|
|
|
|
|
|
333
|
163
|
|
|
|
|
1253
|
return bless [[$pos, pos], @ret], JECE; |
|
334
|
|
|
|
|
|
|
} |
|
335
|
|
|
|
|
|
|
# We don’t call the ident subroutine here, |
|
336
|
|
|
|
|
|
|
# because we need to sift out null/true/false/this. |
|
337
|
|
|
|
|
|
|
elsif(($tmp)=/\G($ident)/cgox) { |
|
338
|
20040
|
100
|
|
|
|
122225
|
$tmp=~/^(?:(?:tru|fals)e|null)\z/ &&return $global->$tmp; |
|
339
|
18271
|
100
|
|
|
|
36994
|
$tmp eq 'this' and return $tmp; |
|
340
|
18055
|
|
|
|
|
32698
|
return "i" . unescape_ident $tmp; |
|
341
|
|
|
|
|
|
|
} |
|
342
|
|
|
|
|
|
|
elsif(defined($tmp = &str) or |
|
343
|
|
|
|
|
|
|
defined($tmp = &num)) { |
|
344
|
31344
|
|
|
|
|
140153
|
return $tmp; |
|
345
|
|
|
|
|
|
|
} |
|
346
|
|
|
|
|
|
|
elsif(m-\G |
|
347
|
|
|
|
|
|
|
/ |
|
348
|
|
|
|
|
|
|
( (?:[^/*\\[] | \\. | \[ (?>(?:[^]\\] | \\.)*) \] ) |
|
349
|
|
|
|
|
|
|
(?>(?:[^/\\[] | \\. | \[ (?>(?:[^]\\] | \\.)*) \] )*) ) |
|
350
|
|
|
|
|
|
|
/ |
|
351
|
|
|
|
|
|
|
($id_cont*) |
|
352
|
|
|
|
|
|
|
-cogx ) { |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
# I have to use local *_ because |
|
355
|
|
|
|
|
|
|
# 'require JE::Object::RegExp' causes |
|
356
|
|
|
|
|
|
|
# Scalar::Util->import() to be called (import is inherited |
|
357
|
|
|
|
|
|
|
# from Exporter), and &Exporter::import does 'local $_', |
|
358
|
|
|
|
|
|
|
# which, in p5.8.8 (though not 5.9.5) causes pos() |
|
359
|
|
|
|
|
|
|
# to be reset. |
|
360
|
317
|
|
|
|
|
488
|
{ local *_; require JE::Object::RegExp; } |
|
|
317
|
|
|
|
|
755
|
|
|
|
317
|
|
|
|
|
3172
|
|
|
361
|
|
|
|
|
|
|
# ~~~ This needs to unescape the flags. |
|
362
|
317
|
|
|
|
|
1516
|
return JE::Object::RegExp->new( $global, $1, $2); |
|
363
|
|
|
|
|
|
|
} |
|
364
|
|
|
|
|
|
|
elsif(/\G\[$s/cg) { |
|
365
|
5291
|
|
|
|
|
6620
|
my $anon; |
|
366
|
|
|
|
|
|
|
my @ret; |
|
367
|
0
|
|
|
|
|
0
|
my $length; |
|
368
|
|
|
|
|
|
|
|
|
369
|
5291
|
|
|
|
|
5281
|
while () { |
|
370
|
20890
|
100
|
|
|
|
34222
|
@ret != ($length = push @ret, &assign) and &skip; |
|
371
|
20890
|
|
|
|
|
171778
|
push @ret, bless \$anon, 'comma' while /\G,$s/cg; |
|
372
|
20890
|
100
|
|
|
|
47567
|
$length == @ret and last; |
|
373
|
|
|
|
|
|
|
} |
|
374
|
|
|
|
|
|
|
|
|
375
|
5291
|
100
|
|
|
|
15656
|
/\G]/cg or expected "']'"; |
|
376
|
5287
|
|
|
|
|
49632
|
return bless [[$pos, pos], array => @ret], JECE; |
|
377
|
|
|
|
|
|
|
} |
|
378
|
|
|
|
|
|
|
elsif(/\G\{$s/cg) { |
|
379
|
552
|
|
|
|
|
6363
|
my @ret; |
|
380
|
|
|
|
|
|
|
|
|
381
|
552
|
100
|
66
|
|
|
1093
|
if($tmp = &ident or defined($tmp = &str)&&$tmp=~s/^s// or |
|
|
|
|
66
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
382
|
|
|
|
|
|
|
defined($tmp = &num)) { |
|
383
|
|
|
|
|
|
|
# first elem, not preceded by comma |
|
384
|
125
|
|
|
|
|
251
|
push @ret, $tmp; |
|
385
|
125
|
|
|
|
|
253
|
&skip; |
|
386
|
125
|
50
|
|
|
|
1678
|
/\G:$s/cggg or expected 'colon'; |
|
387
|
125
|
50
|
|
|
|
3721
|
@ret != push @ret, &assign |
|
388
|
|
|
|
|
|
|
or expected \'expression'; |
|
389
|
125
|
|
|
|
|
290
|
&skip; |
|
390
|
|
|
|
|
|
|
|
|
391
|
125
|
|
|
|
|
1009
|
while (/\G,$s/cg) { |
|
392
|
|
|
|
|
|
|
$tmp = ident |
|
393
|
|
|
|
|
|
|
or defined($tmp = &str)&&$tmp=~s/^s// or |
|
394
|
|
|
|
|
|
|
defined($tmp = &num) |
|
395
|
101
|
100
|
66
|
|
|
1731
|
or do { |
|
|
|
|
66
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
396
|
|
|
|
|
|
|
# ECMAScript 5 allows a |
|
397
|
|
|
|
|
|
|
# trailing comma |
|
398
|
1
|
50
|
|
|
|
10
|
/\G}/cg or expected |
|
399
|
|
|
|
|
|
|
"'}', identifier, or string or ". |
|
400
|
|
|
|
|
|
|
" number literal"; |
|
401
|
1
|
|
|
|
|
14
|
return bless [[$pos, pos], |
|
402
|
|
|
|
|
|
|
hash => @ret], JECE; |
|
403
|
|
|
|
|
|
|
}; |
|
404
|
|
|
|
|
|
|
|
|
405
|
100
|
|
|
|
|
230
|
push @ret, $tmp; |
|
406
|
100
|
|
|
|
|
172
|
&skip; |
|
407
|
100
|
50
|
|
|
|
755
|
/\G:$s/cggg or expected 'colon'; |
|
408
|
100
|
50
|
|
|
|
2060
|
@ret != push @ret, &assign |
|
409
|
|
|
|
|
|
|
or expected 'expression'; |
|
410
|
100
|
|
|
|
|
213
|
&skip; |
|
411
|
|
|
|
|
|
|
} |
|
412
|
|
|
|
|
|
|
} |
|
413
|
551
|
50
|
|
|
|
3598
|
/\G}/cg or expected "'}'"; |
|
414
|
551
|
|
|
|
|
5132
|
return bless [[$pos, pos], hash => @ret], JECE; |
|
415
|
|
|
|
|
|
|
} |
|
416
|
|
|
|
|
|
|
elsif (/\G\($s/cg) { |
|
417
|
812
|
50
|
|
|
|
6366
|
my $ret = &expr or expected 'expression'; |
|
418
|
812
|
|
|
|
|
1567
|
&skip; |
|
419
|
812
|
50
|
|
|
|
3268
|
/\G\)/cg or expected "')'"; |
|
420
|
812
|
|
|
|
|
3328
|
return $ret; |
|
421
|
|
|
|
|
|
|
} |
|
422
|
|
|
|
|
|
|
return |
|
423
|
3250
|
|
|
|
|
127937
|
} |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
sub subscript() { # skips leading whitespace |
|
426
|
71601
|
|
|
71601
|
0
|
97120
|
my $pos = pos; |
|
427
|
71601
|
|
|
|
|
61044
|
my $subscript; |
|
428
|
71601
|
100
|
|
|
|
790986
|
if (/\G$s\[$s/cg) { |
|
|
|
100
|
|
|
|
|
|
|
429
|
1012
|
50
|
|
|
|
1873
|
$subscript = &expr or expected 'expression'; |
|
430
|
1012
|
|
|
|
|
1811
|
&skip; |
|
431
|
1012
|
50
|
|
|
|
3161
|
/\G]/cog or expected "']'"; |
|
432
|
|
|
|
|
|
|
} |
|
433
|
|
|
|
|
|
|
elsif (/\G$s\.$s/cg) { |
|
434
|
4220
|
50
|
|
|
|
9992
|
$subscript = &ident or expected 'identifier'; |
|
435
|
|
|
|
|
|
|
} |
|
436
|
66369
|
|
|
|
|
222259
|
else { return } |
|
437
|
|
|
|
|
|
|
|
|
438
|
5232
|
|
|
|
|
32420
|
return bless [[$pos, pos], $subscript], 'JE::Code::Subscript'; |
|
439
|
|
|
|
|
|
|
} |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
sub args() { # skips leading whitespace |
|
442
|
71569
|
|
|
71569
|
0
|
86240
|
my $pos = pos; |
|
443
|
71569
|
|
|
|
|
61429
|
my @ret; |
|
444
|
71569
|
100
|
|
|
|
793666
|
/\G$s\($s/gc or return; |
|
445
|
10414
|
100
|
|
|
|
30066
|
if (@ret != push @ret, &assign) { # first expression (not prec. |
|
446
|
|
|
|
|
|
|
# by comma) |
|
447
|
9030
|
|
|
|
|
56581
|
while (/\G$s,$s/gc) { |
|
448
|
|
|
|
|
|
|
# if there's a comma we need another expression |
|
449
|
9255
|
50
|
|
|
|
28832
|
@ret != push @ret, &assign |
|
450
|
|
|
|
|
|
|
or expected 'expression'; |
|
451
|
|
|
|
|
|
|
} |
|
452
|
9030
|
|
|
|
|
20654
|
&skip; |
|
453
|
|
|
|
|
|
|
} |
|
454
|
10414
|
100
|
|
|
|
33488
|
/\G\)/gc or expected "')'"; |
|
455
|
10412
|
|
|
|
|
81711
|
return bless [[$pos, pos], @ret], 'JE::Code::Arguments'; |
|
456
|
|
|
|
|
|
|
} |
|
457
|
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
sub new_expr() { |
|
459
|
62776
|
100
|
|
62776
|
0
|
397027
|
/\G new(?!$id_cont) $s /cgx or return; |
|
460
|
1007
|
|
|
|
|
5547
|
my $ret = bless [[pos], 'new'], JECE; |
|
461
|
|
|
|
|
|
|
|
|
462
|
1007
|
|
|
|
|
1758
|
my $pos = pos; |
|
463
|
1007
|
|
33
|
|
|
2039
|
my @member_expr = &new_expr || &term |
|
464
|
|
|
|
|
|
|
|| expected "identifier, literal, 'new' or '('"; |
|
465
|
|
|
|
|
|
|
|
|
466
|
1007
|
|
|
|
|
2498
|
0 while @member_expr != push @member_expr, &subscript; |
|
467
|
|
|
|
|
|
|
|
|
468
|
1007
|
100
|
|
|
|
3311
|
push @$ret, @member_expr == 1 ? @member_expr : |
|
469
|
|
|
|
|
|
|
bless [[$pos, pos], 'member/call', @member_expr], |
|
470
|
|
|
|
|
|
|
JECE; |
|
471
|
1007
|
|
|
|
|
2065
|
push @$ret, args; |
|
472
|
1007
|
|
|
|
|
4726
|
$ret; |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub left_expr() { |
|
476
|
61769
|
|
|
61769
|
0
|
73204
|
my($pos,@ret) = pos; |
|
477
|
61769
|
100
|
100
|
|
|
90232
|
@ret != push @ret, &new_expr || &term or return; |
|
478
|
|
|
|
|
|
|
|
|
479
|
58509
|
|
|
|
|
125114
|
0 while @ret != push @ret, &subscript, &args; |
|
480
|
58507
|
100
|
|
|
|
298985
|
@ret ? @ret == 1 ? @ret : |
|
|
|
50
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
bless([[$pos, pos], 'member/call', @ret], |
|
482
|
|
|
|
|
|
|
JECE) |
|
483
|
|
|
|
|
|
|
: return; |
|
484
|
|
|
|
|
|
|
} |
|
485
|
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
sub postfix() { |
|
487
|
61769
|
|
|
61769
|
0
|
87990
|
my($pos,@ret) = pos; |
|
488
|
61769
|
100
|
|
|
|
86984
|
@ret != push @ret, &left_expr or return; |
|
489
|
58507
|
|
|
|
|
209802
|
push @ret, $1 while /\G $h ( \+\+ | -- ) /cogx; |
|
490
|
58507
|
100
|
|
|
|
198567
|
@ret == 1 ? @ret : bless [[$pos, pos], 'postfix', @ret], |
|
491
|
|
|
|
|
|
|
JECE; |
|
492
|
|
|
|
|
|
|
} |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub unary() { |
|
495
|
61769
|
|
|
61769
|
0
|
72013
|
my($pos,@ret) = pos; |
|
496
|
61769
|
|
|
|
|
533589
|
push @ret, $1 while /\G $s ( |
|
497
|
|
|
|
|
|
|
(?: delete | void | typeof )(?!$id_cont) |
|
498
|
|
|
|
|
|
|
| |
|
499
|
|
|
|
|
|
|
\+\+? | --? | ~ | ! |
|
500
|
|
|
|
|
|
|
) $s /cgx; |
|
501
|
61769
|
100
|
|
|
|
139996
|
@ret != push @ret, &postfix or ( |
|
|
|
100
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
@ret |
|
503
|
|
|
|
|
|
|
? expected "expression" |
|
504
|
|
|
|
|
|
|
: return |
|
505
|
|
|
|
|
|
|
); |
|
506
|
58507
|
100
|
|
|
|
208213
|
@ret == 1 ? @ret : bless [[$pos, pos], 'prefix', @ret], |
|
507
|
|
|
|
|
|
|
JECE; |
|
508
|
|
|
|
|
|
|
} |
|
509
|
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
sub multi() { |
|
511
|
61549
|
|
|
61549
|
0
|
71527
|
my($pos,@ret) = pos; |
|
512
|
61549
|
100
|
|
|
|
86886
|
@ret != push @ret, &unary or return; |
|
513
|
58287
|
|
|
|
|
364953
|
while(m-\G $s ( [*%](?!=) | / (?![*/=]) ) $s -cgx) { |
|
514
|
220
|
|
|
|
|
811
|
push @ret, $1; |
|
515
|
220
|
50
|
|
|
|
361
|
@ret == push @ret, &unary and expected 'expression'; |
|
516
|
|
|
|
|
|
|
} |
|
517
|
58287
|
100
|
|
|
|
224534
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
518
|
|
|
|
|
|
|
JECE; |
|
519
|
|
|
|
|
|
|
} |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
sub add() { |
|
522
|
60271
|
|
|
60271
|
0
|
70430
|
my($pos,@ret) = pos; |
|
523
|
60271
|
100
|
|
|
|
83382
|
@ret != push @ret, &multi or return; |
|
524
|
57009
|
|
|
|
|
305741
|
while(/\G $s ( \+(?![+=]) | -(?![-=]) ) $s /cgx) { |
|
525
|
1278
|
|
|
|
|
4712
|
push @ret, $1; |
|
526
|
1278
|
50
|
|
|
|
2203
|
@ret == push @ret, &multi and expected 'expression' |
|
527
|
|
|
|
|
|
|
} |
|
528
|
57009
|
100
|
|
|
|
209897
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
529
|
|
|
|
|
|
|
JECE; |
|
530
|
|
|
|
|
|
|
} |
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
sub bitshift() { |
|
533
|
60115
|
|
|
60115
|
0
|
68824
|
my($pos,@ret) = pos; |
|
534
|
60115
|
100
|
|
|
|
84283
|
@ret == push @ret, &add and return; |
|
535
|
56853
|
|
|
|
|
296570
|
while(/\G $s (>>> | >>(?!>) | <<)(?!=) $s /cgx) { |
|
536
|
156
|
|
|
|
|
984
|
push @ret, $1; |
|
537
|
156
|
50
|
|
|
|
278
|
@ret == push @ret, &add and expected 'expression'; |
|
538
|
|
|
|
|
|
|
} |
|
539
|
56853
|
100
|
|
|
|
214716
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
540
|
|
|
|
|
|
|
JECE; |
|
541
|
|
|
|
|
|
|
} |
|
542
|
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
sub rel() { |
|
544
|
58581
|
|
|
58581
|
0
|
70689
|
my($pos,@ret) = pos; |
|
545
|
58581
|
100
|
|
|
|
83967
|
@ret == push @ret, &bitshift and return; |
|
546
|
55332
|
|
|
|
|
332686
|
while(/\G $s ( ([<>])(?!\2|=) | [<>]= | |
|
547
|
|
|
|
|
|
|
in(?:stanceof)?(?!$id_cont) ) $s /cgx) { |
|
548
|
957
|
|
|
|
|
3481
|
push @ret, $1; |
|
549
|
957
|
50
|
|
|
|
1855
|
@ret== push @ret, &bitshift and expected 'expression'; |
|
550
|
|
|
|
|
|
|
} |
|
551
|
55332
|
100
|
|
|
|
228735
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
552
|
|
|
|
|
|
|
JECE; |
|
553
|
|
|
|
|
|
|
} |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
sub rel_noin() { |
|
556
|
565
|
|
|
565
|
0
|
853
|
my($pos,@ret) = pos; |
|
557
|
565
|
100
|
|
|
|
915
|
@ret == push @ret, &bitshift and return; |
|
558
|
552
|
|
|
|
|
4564
|
while(/\G $s ( ([<>])(?!\2|=) | [<>]= | instanceof(?!$id_cont) ) |
|
559
|
|
|
|
|
|
|
$s /cgx) { |
|
560
|
12
|
|
|
|
|
587
|
push @ret, $1; |
|
561
|
12
|
50
|
|
|
|
26
|
@ret == push @ret, &bitshift and expected 'expression'; |
|
562
|
|
|
|
|
|
|
} |
|
563
|
552
|
100
|
|
|
|
11357
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
564
|
|
|
|
|
|
|
JECE; |
|
565
|
|
|
|
|
|
|
} |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub equal() { |
|
568
|
55814
|
|
|
55814
|
0
|
65532
|
my($pos,@ret) = pos; |
|
569
|
55814
|
100
|
|
|
|
80981
|
@ret == push @ret, &rel and return; |
|
570
|
52565
|
|
|
|
|
619861
|
while(/\G $s ([!=]==?) $s /cgx) { |
|
571
|
2767
|
|
|
|
|
8658
|
push @ret, $1; |
|
572
|
2767
|
50
|
|
|
|
4808
|
@ret == push @ret, &rel and expected 'expression'; |
|
573
|
|
|
|
|
|
|
} |
|
574
|
52565
|
100
|
|
|
|
208298
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
575
|
|
|
|
|
|
|
JECE; |
|
576
|
|
|
|
|
|
|
} |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
sub equal_noin() { |
|
579
|
555
|
|
|
555
|
0
|
833
|
my($pos,@ret) = pos; |
|
580
|
555
|
100
|
|
|
|
1030
|
@ret == push @ret, &rel_noin and return; |
|
581
|
542
|
|
|
|
|
4157
|
while(/\G $s ([!=]==?) $s /cgx) { |
|
582
|
10
|
|
|
|
|
16
|
push @ret, $1; |
|
583
|
10
|
50
|
|
|
|
16
|
@ret == push @ret, &rel_noin and expected 'expression'; |
|
584
|
|
|
|
|
|
|
} |
|
585
|
542
|
100
|
|
|
|
9482
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
586
|
|
|
|
|
|
|
JECE; |
|
587
|
|
|
|
|
|
|
} |
|
588
|
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
sub bit_and() { |
|
590
|
55762
|
|
|
55762
|
0
|
63884
|
my($pos,@ret) = pos; |
|
591
|
55762
|
100
|
|
|
|
78273
|
@ret == push @ret, &equal and return; |
|
592
|
52513
|
|
|
|
|
1257807
|
while(/\G $s &(?![&=]) $s /cgx) { |
|
593
|
52
|
50
|
|
|
|
779
|
@ret == push @ret, '&', &equal and expected 'expression'; |
|
594
|
|
|
|
|
|
|
} |
|
595
|
52513
|
100
|
|
|
|
203692
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
596
|
|
|
|
|
|
|
JECE; |
|
597
|
|
|
|
|
|
|
} |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
sub bit_and_noin() { |
|
600
|
553
|
|
|
553
|
0
|
770
|
my($pos,@ret) = pos; |
|
601
|
553
|
100
|
|
|
|
1018
|
@ret == push @ret, &equal_noin and return; |
|
602
|
540
|
|
|
|
|
9447
|
while(/\G $s &(?![&=]) $s /cgx) { |
|
603
|
2
|
50
|
|
|
|
4
|
@ret == push @ret, '&', &equal_noin |
|
604
|
|
|
|
|
|
|
and expected 'expression'; |
|
605
|
|
|
|
|
|
|
} |
|
606
|
540
|
100
|
|
|
|
9053
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
607
|
|
|
|
|
|
|
JECE; |
|
608
|
|
|
|
|
|
|
} |
|
609
|
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
sub bit_or() { |
|
611
|
55709
|
|
|
55709
|
0
|
64358
|
my($pos,@ret) = pos; |
|
612
|
55709
|
100
|
|
|
|
77033
|
@ret == push @ret, &bit_and and return; |
|
613
|
52460
|
|
|
|
|
1247559
|
while(/\G $s \|(?![|=]) $s /cgx) { |
|
614
|
53
|
50
|
|
|
|
541
|
@ret == push @ret, '|', &bit_and and expected 'expression'; |
|
615
|
|
|
|
|
|
|
} |
|
616
|
52460
|
100
|
|
|
|
203536
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
617
|
|
|
|
|
|
|
JECE; |
|
618
|
|
|
|
|
|
|
} |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
sub bit_or_noin() { |
|
621
|
551
|
|
|
551
|
0
|
856
|
my($pos,@ret) = pos; |
|
622
|
551
|
100
|
|
|
|
1235
|
@ret == push @ret, &bit_and_noin and return; |
|
623
|
538
|
|
|
|
|
9560
|
while(/\G $s \|(?![|=]) $s /cgx) { |
|
624
|
2
|
50
|
|
|
|
8
|
@ret == push @ret, '|', &bit_and_noin |
|
625
|
|
|
|
|
|
|
and expected 'expression'; |
|
626
|
|
|
|
|
|
|
} |
|
627
|
538
|
100
|
|
|
|
9536
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
628
|
|
|
|
|
|
|
JECE; |
|
629
|
|
|
|
|
|
|
} |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
sub bit_xor() { |
|
632
|
55657
|
|
|
55657
|
0
|
63649
|
my($pos,@ret) = pos; |
|
633
|
55657
|
100
|
|
|
|
80194
|
@ret == push @ret, &bit_or and return; |
|
634
|
52408
|
|
|
|
|
1175297
|
while(/\G $s \^(?!=) $s /cgx) { |
|
635
|
52
|
50
|
|
|
|
400
|
@ret == push @ret, '^', &bit_or and expected 'expression'; |
|
636
|
|
|
|
|
|
|
} |
|
637
|
52408
|
100
|
|
|
|
214011
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
638
|
|
|
|
|
|
|
JECE; |
|
639
|
|
|
|
|
|
|
} |
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
sub bit_xor_noin() { |
|
642
|
549
|
|
|
549
|
0
|
780
|
my($pos,@ret) = pos; |
|
643
|
549
|
100
|
|
|
|
1067
|
@ret == push @ret, &bit_or_noin and return; |
|
644
|
536
|
|
|
|
|
9527
|
while(/\G $s \^(?!=) $s /cgx) { |
|
645
|
2
|
50
|
|
|
|
5
|
@ret == push @ret, '^', &bit_or_noin |
|
646
|
|
|
|
|
|
|
and expected 'expression'; |
|
647
|
|
|
|
|
|
|
} |
|
648
|
536
|
100
|
|
|
|
9428
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
649
|
|
|
|
|
|
|
JECE; |
|
650
|
|
|
|
|
|
|
} |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
sub and_expr() { # If I just call it 'and', then I have to write |
|
653
|
|
|
|
|
|
|
# CORE::and for the operator! (Far too cumbersome.) |
|
654
|
55180
|
|
|
55180
|
0
|
64983
|
my($pos,@ret) = pos; |
|
655
|
55180
|
100
|
|
|
|
81937
|
@ret == push @ret, &bit_xor and return; |
|
656
|
51931
|
|
|
|
|
884036
|
while(/\G $s && $s /cgx) { |
|
657
|
477
|
50
|
|
|
|
1634
|
@ret == push @ret, '&&', &bit_xor |
|
658
|
|
|
|
|
|
|
and expected 'expression'; |
|
659
|
|
|
|
|
|
|
} |
|
660
|
51931
|
100
|
|
|
|
201793
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
661
|
|
|
|
|
|
|
JECE; |
|
662
|
|
|
|
|
|
|
} |
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
sub and_noin() { |
|
665
|
547
|
|
|
547
|
0
|
834
|
my($pos,@ret) = pos; |
|
666
|
547
|
100
|
|
|
|
907
|
@ret == push @ret, &bit_xor_noin and return; |
|
667
|
534
|
|
|
|
|
6340
|
while(/\G $s && $s /cgx) { |
|
668
|
2
|
50
|
|
|
|
4
|
@ret == push @ret, '&&', &bit_xor_noin |
|
669
|
|
|
|
|
|
|
and expected 'expression'; |
|
670
|
|
|
|
|
|
|
} |
|
671
|
534
|
100
|
|
|
|
9342
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
672
|
|
|
|
|
|
|
JECE; |
|
673
|
|
|
|
|
|
|
} |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
sub or_expr() { |
|
676
|
55100
|
|
|
55100
|
0
|
68212
|
my($pos,@ret) = pos; |
|
677
|
55100
|
100
|
|
|
|
77481
|
@ret == push @ret, &and_expr and return; |
|
678
|
51851
|
|
|
|
|
859495
|
while(/\G $s \|\| $s /cgx) { |
|
679
|
80
|
50
|
|
|
|
176
|
@ret == push @ret, '||', &and_expr |
|
680
|
|
|
|
|
|
|
and expected 'expression'; |
|
681
|
|
|
|
|
|
|
} |
|
682
|
51851
|
100
|
|
|
|
210603
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
683
|
|
|
|
|
|
|
JECE; |
|
684
|
|
|
|
|
|
|
} |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
sub or_noin() { |
|
687
|
545
|
|
|
545
|
0
|
1107
|
my($pos,@ret) = pos; |
|
688
|
545
|
100
|
|
|
|
1000
|
@ret == push @ret, &and_noin and return; |
|
689
|
532
|
|
|
|
|
6181
|
while(/\G $s \|\| $s /cgx) { |
|
690
|
2
|
50
|
|
|
|
5
|
@ret == push @ret, '||', &and_noin |
|
691
|
|
|
|
|
|
|
and expected 'expression'; |
|
692
|
|
|
|
|
|
|
} |
|
693
|
532
|
100
|
|
|
|
10788
|
@ret == 1 ? @ret : bless [[$pos, pos], 'lassoc', @ret], |
|
694
|
|
|
|
|
|
|
JECE; |
|
695
|
|
|
|
|
|
|
} |
|
696
|
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
sub assign() { |
|
698
|
53482
|
|
|
53482
|
0
|
119218
|
my($pos,@ret) = pos; |
|
699
|
53482
|
100
|
|
|
|
79249
|
@ret == push @ret, &or_expr and return; |
|
700
|
50234
|
|
|
|
|
652209
|
while(m@\G $s ((?>(?: [-*/%+&^|] | << | >>>? )?)=) $s @cgx) { |
|
701
|
1618
|
|
|
|
|
11459
|
push @ret, $1; |
|
702
|
1618
|
50
|
|
|
|
3161
|
@ret == push @ret, &or_expr and expected 'expression'; |
|
703
|
|
|
|
|
|
|
} |
|
704
|
50233
|
100
|
|
|
|
1386090
|
if(/\G$s\?$s/cg) { |
|
705
|
48
|
50
|
|
|
|
127
|
@ret == push @ret, &assign and expected 'expression'; |
|
706
|
48
|
|
|
|
|
111
|
&skip; |
|
707
|
48
|
50
|
|
|
|
790
|
/\G:$s/cg or expected "colon"; |
|
708
|
48
|
50
|
|
|
|
1678
|
@ret == push @ret, &assign and expected 'expression'; |
|
709
|
|
|
|
|
|
|
} |
|
710
|
50233
|
100
|
|
|
|
311579
|
@ret == 1 ? @ret : bless [[$pos, pos], 'assign', @ret], |
|
711
|
|
|
|
|
|
|
JECE; |
|
712
|
|
|
|
|
|
|
} |
|
713
|
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
sub assign_noin() { |
|
715
|
321
|
|
|
321
|
0
|
2962
|
my($pos,@ret) = pos; |
|
716
|
321
|
100
|
|
|
|
726
|
@ret == push @ret, &or_noin and return; |
|
717
|
308
|
|
|
|
|
3245
|
while(m~\G $s ((?>(?: [-*/%+&^|] | << | >>>? )?)=) $s ~cgx) { |
|
718
|
224
|
|
|
|
|
3974
|
push @ret, $1; |
|
719
|
224
|
50
|
|
|
|
404
|
@ret == push @ret, &or_noin and expected 'expression'; |
|
720
|
|
|
|
|
|
|
} |
|
721
|
308
|
100
|
|
|
|
6853
|
if(/\G$s\?$s/cg) { |
|
722
|
6
|
50
|
|
|
|
14
|
@ret == push @ret, &assign and expected 'expression'; |
|
723
|
6
|
|
|
|
|
10
|
&skip; |
|
724
|
6
|
50
|
|
|
|
61
|
/\G:$s/cg or expected "colon"; |
|
725
|
6
|
50
|
|
|
|
237
|
@ret == push @ret, &assign_noin and expected 'expression'; |
|
726
|
|
|
|
|
|
|
} |
|
727
|
308
|
100
|
|
|
|
9836
|
@ret == 1 ? @ret : bless [[$pos, pos], 'assign', @ret], |
|
728
|
|
|
|
|
|
|
JECE; |
|
729
|
|
|
|
|
|
|
} |
|
730
|
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
sub expr() { # public |
|
732
|
11988
|
|
|
11988
|
0
|
47907
|
my $ret = bless [[pos], 'expr'], JECE; |
|
733
|
11988
|
100
|
|
|
|
23417
|
@$ret == push @$ret, &assign and return; |
|
734
|
10292
|
|
|
|
|
63002
|
while(/\G$s,$s/cg) { |
|
735
|
304
|
50
|
|
|
|
1490
|
@$ret == push @$ret,& assign and expected 'expression'; |
|
736
|
|
|
|
|
|
|
} |
|
737
|
10292
|
|
|
|
|
39552
|
push @{$$ret[0]},pos; |
|
|
10292
|
|
|
|
|
25099
|
|
|
738
|
10292
|
|
|
|
|
32790
|
$ret; |
|
739
|
|
|
|
|
|
|
} |
|
740
|
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
sub expr_noin() { # public |
|
742
|
237
|
|
|
237
|
0
|
5089
|
my $ret = bless [[pos], 'expr'], JECE; |
|
743
|
237
|
100
|
|
|
|
639
|
@$ret == push @$ret, &assign_noin and return; |
|
744
|
224
|
|
|
|
|
2252
|
while(/\G$s,$s/cg) { |
|
745
|
22
|
50
|
|
|
|
42
|
@$ret == push @$ret, &assign_noin |
|
746
|
|
|
|
|
|
|
and expected 'expression'; |
|
747
|
|
|
|
|
|
|
} |
|
748
|
224
|
|
|
|
|
6764
|
push @{$$ret[0]},pos; |
|
|
224
|
|
|
|
|
590
|
|
|
749
|
224
|
|
|
|
|
788
|
$ret; |
|
750
|
|
|
|
|
|
|
} |
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
sub vardecl() { # vardecl is only called when we *know* we need it, so it |
|
753
|
|
|
|
|
|
|
# will die when it can't get the first identifier, instead |
|
754
|
|
|
|
|
|
|
# of returning undef |
|
755
|
385
|
|
|
385
|
0
|
518
|
my @ret; |
|
756
|
385
|
50
|
|
|
|
841
|
@ret == push @ret, &ident and expected 'identifier'; |
|
757
|
385
|
100
|
33
|
|
|
5154
|
/\G$s=$s/cg and |
|
758
|
|
|
|
|
|
|
(@ret != push @ret, &assign or expected 'expression'); |
|
759
|
385
|
|
|
|
|
4084
|
push @$_vars, $ret[0]; |
|
760
|
385
|
|
|
|
|
4781
|
\@ret; |
|
761
|
|
|
|
|
|
|
} |
|
762
|
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
sub vardecl_noin() { |
|
764
|
118
|
|
|
118
|
0
|
145
|
my @ret; |
|
765
|
118
|
50
|
|
|
|
297
|
@ret == push @ret, &ident and expected 'identifier'; |
|
766
|
118
|
100
|
33
|
|
|
1538
|
/\G$s=$s/cg and |
|
767
|
|
|
|
|
|
|
(@ret != push @ret, &assign_noin or expected 'expression'); |
|
768
|
118
|
|
|
|
|
3224
|
push @$_vars, $ret[0]; |
|
769
|
118
|
|
|
|
|
366
|
\@ret; |
|
770
|
|
|
|
|
|
|
} |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
sub finish_for_sc_sc() { # returns the last two expressions of a for (;;) |
|
773
|
|
|
|
|
|
|
# loop header |
|
774
|
301
|
|
|
301
|
0
|
593
|
my @ret; |
|
775
|
|
|
|
|
|
|
my $msg; |
|
776
|
301
|
100
|
|
|
|
662
|
if(@ret != push @ret, expr) { |
|
777
|
260
|
|
|
|
|
403
|
$msg = ''; |
|
778
|
260
|
|
|
|
|
537
|
&skip |
|
779
|
|
|
|
|
|
|
} else { |
|
780
|
41
|
|
|
|
|
81
|
push @ret, 'empty'; |
|
781
|
41
|
|
|
|
|
69
|
$msg = 'expression or ' |
|
782
|
|
|
|
|
|
|
} |
|
783
|
301
|
50
|
|
|
|
2172
|
/\G;$s/cg or expected "${msg}semicolon"; |
|
784
|
301
|
100
|
|
|
|
3918
|
if(@ret != push @ret, expr) { |
|
785
|
194
|
|
|
|
|
338
|
$msg = ''; |
|
786
|
194
|
|
|
|
|
531
|
&skip |
|
787
|
|
|
|
|
|
|
} else { |
|
788
|
107
|
|
|
|
|
183
|
push @ret, 'empty'; |
|
789
|
107
|
|
|
|
|
163
|
$msg = 'expression or ' |
|
790
|
|
|
|
|
|
|
} |
|
791
|
301
|
50
|
|
|
|
2326
|
/\G\)$s/cg or expected "${msg}')'"; |
|
792
|
|
|
|
|
|
|
|
|
793
|
301
|
|
|
|
|
4328
|
@ret; |
|
794
|
|
|
|
|
|
|
} |
|
795
|
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
# ----------- Statement types ------------ # |
|
797
|
|
|
|
|
|
|
# (used by custom parsers) |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
our $optional_sc = # public |
|
800
|
|
|
|
|
|
|
qr-\G (?: |
|
801
|
|
|
|
|
|
|
$s (?: \z | ; $s | (?=\}) ) |
|
802
|
|
|
|
|
|
|
| |
|
803
|
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
# optional horizontal whitespace |
|
805
|
|
|
|
|
|
|
# then a line terminator or a comment containing one |
|
806
|
|
|
|
|
|
|
# then optional trailing whitespace |
|
807
|
|
|
|
|
|
|
$h |
|
808
|
|
|
|
|
|
|
(?: $n | //[^\cm\cj\x{2028}\x{2029}]* $n | |
|
809
|
|
|
|
|
|
|
/\* [^*\cm\cj\x{2028}\x{2029}]* |
|
810
|
|
|
|
|
|
|
(?: \*(?!/) [^*\cm\cj\x{2028}\x{2029}] )* |
|
811
|
|
|
|
|
|
|
$n |
|
812
|
|
|
|
|
|
|
(?s:.)*? |
|
813
|
|
|
|
|
|
|
\*/ |
|
814
|
|
|
|
|
|
|
) |
|
815
|
|
|
|
|
|
|
$s |
|
816
|
|
|
|
|
|
|
)-x; |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
sub optional_sc() { |
|
819
|
9
|
100
|
|
9
|
0
|
84
|
/$optional_sc/gc or expected "semicolon, '}' or end of line"; |
|
820
|
|
|
|
|
|
|
} |
|
821
|
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
sub block() { |
|
823
|
16
|
50
|
|
16
|
0
|
102
|
/\G\{/gc or return; |
|
824
|
0
|
|
|
|
|
0
|
my $ret = [[pos()-1], 'statements']; |
|
825
|
0
|
|
|
|
|
0
|
&skip; |
|
826
|
0
|
|
|
|
|
0
|
while() { # 'last' does not work when 'while' is a |
|
827
|
|
|
|
|
|
|
# statement modifier |
|
828
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &statement and last; |
|
829
|
|
|
|
|
|
|
} |
|
830
|
0
|
0
|
|
|
|
0
|
expected "'}'" unless /\G\}$s/gc; |
|
831
|
|
|
|
|
|
|
|
|
832
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
833
|
|
|
|
|
|
|
|
|
834
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
835
|
|
|
|
|
|
|
} |
|
836
|
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
sub empty() { |
|
838
|
16
|
|
|
16
|
0
|
28
|
my $pos = pos; |
|
839
|
16
|
50
|
|
|
|
142
|
/\G;$s/cg or return; |
|
840
|
0
|
|
|
|
|
0
|
bless [[$pos,pos], 'empty'], JECS; |
|
841
|
|
|
|
|
|
|
} |
|
842
|
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
sub function() { |
|
844
|
7070
|
|
|
7070
|
0
|
10845
|
my $pos = pos; |
|
845
|
7070
|
100
|
|
|
|
47781
|
/\Gfunction$S/cg or return; |
|
846
|
132
|
|
|
|
|
6595
|
my $ret = [[$pos], 'function']; |
|
847
|
132
|
50
|
|
|
|
429
|
@$ret == push @$ret, &ident |
|
848
|
|
|
|
|
|
|
and expected "identifier"; |
|
849
|
132
|
|
|
|
|
324
|
&skip; |
|
850
|
132
|
|
|
|
|
5395
|
push @$ret, ¶ms; |
|
851
|
132
|
|
|
|
|
270
|
&skip; |
|
852
|
132
|
50
|
|
|
|
481
|
/\G \{ /gcx or expected "'{'"; |
|
853
|
|
|
|
|
|
|
{ |
|
854
|
132
|
|
|
|
|
169
|
local $_vars = []; |
|
|
132
|
|
|
|
|
241
|
|
|
855
|
132
|
|
|
|
|
319
|
push @$ret, &statements, $_vars; |
|
856
|
|
|
|
|
|
|
} |
|
857
|
132
|
50
|
|
|
|
1910
|
/\G \}$s /gcx or expected "'}'"; |
|
858
|
|
|
|
|
|
|
|
|
859
|
132
|
|
|
|
|
7352
|
push @{$$ret[0]},pos; |
|
|
132
|
|
|
|
|
380
|
|
|
860
|
|
|
|
|
|
|
|
|
861
|
132
|
|
|
|
|
291
|
push @$_vars, $ret; |
|
862
|
|
|
|
|
|
|
|
|
863
|
132
|
|
|
|
|
849
|
bless $ret, JECS; |
|
864
|
|
|
|
|
|
|
} |
|
865
|
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
sub if() { |
|
867
|
16
|
|
|
16
|
0
|
26
|
my $pos = pos; |
|
868
|
16
|
50
|
|
|
|
128
|
/\Gif$s\($s/cg or return; |
|
869
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'if']; |
|
870
|
|
|
|
|
|
|
|
|
871
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
872
|
|
|
|
|
|
|
and expected 'expression'; |
|
873
|
0
|
|
|
|
|
0
|
&skip; |
|
874
|
0
|
0
|
|
|
|
0
|
/\G\)$s/gc or expected "')'"; |
|
875
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &statement |
|
876
|
|
|
|
|
|
|
or expected 'statement'; |
|
877
|
0
|
0
|
|
|
|
0
|
if (/\Gelse(?!$id_cont)$s/cg) { |
|
878
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &statement |
|
879
|
|
|
|
|
|
|
and expected 'statement'; |
|
880
|
|
|
|
|
|
|
} |
|
881
|
|
|
|
|
|
|
|
|
882
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
883
|
|
|
|
|
|
|
|
|
884
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
885
|
|
|
|
|
|
|
} |
|
886
|
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
sub while() { |
|
888
|
0
|
|
|
0
|
0
|
0
|
my $pos = pos; |
|
889
|
0
|
0
|
|
|
|
0
|
/\Gwhile$s\($s/cg or return; |
|
890
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'while']; |
|
891
|
|
|
|
|
|
|
|
|
892
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
893
|
|
|
|
|
|
|
and expected 'expression'; |
|
894
|
0
|
|
|
|
|
0
|
&skip; |
|
895
|
0
|
0
|
|
|
|
0
|
/\G\)$s/gc or expected "')'"; |
|
896
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &statement |
|
897
|
|
|
|
|
|
|
or expected 'statement'; |
|
898
|
|
|
|
|
|
|
|
|
899
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
900
|
|
|
|
|
|
|
|
|
901
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
902
|
|
|
|
|
|
|
} |
|
903
|
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
sub for() { |
|
905
|
0
|
|
|
0
|
1
|
0
|
my $pos = pos; |
|
906
|
0
|
0
|
|
|
|
0
|
/\Gfor$s\($s/cg or return; |
|
907
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'for']; |
|
908
|
|
|
|
|
|
|
|
|
909
|
0
|
0
|
|
|
|
0
|
if (/\G var$S/cgx) { |
|
|
|
0
|
|
|
|
|
|
|
910
|
0
|
|
|
|
|
0
|
push @$ret, my $var = bless |
|
911
|
|
|
|
|
|
|
[[pos() - length $1], 'var'], |
|
912
|
|
|
|
|
|
|
'JE::Code::Statement'; |
|
913
|
|
|
|
|
|
|
|
|
914
|
0
|
|
|
|
|
0
|
push @$var, &vardecl_noin; |
|
915
|
0
|
|
|
|
|
0
|
&skip; |
|
916
|
0
|
0
|
|
|
|
0
|
if (/\G([;,])$s/gc) { |
|
917
|
|
|
|
|
|
|
# if there's a comma or sc then |
|
918
|
|
|
|
|
|
|
# this is a for(;;) loop |
|
919
|
0
|
0
|
|
|
|
0
|
if ($1 eq ',') { |
|
920
|
|
|
|
|
|
|
# finish getting the var |
|
921
|
|
|
|
|
|
|
# decl list |
|
922
|
0
|
|
|
|
|
0
|
do{ |
|
923
|
0
|
0
|
|
|
|
0
|
@$var == |
|
924
|
|
|
|
|
|
|
push @$var, &vardecl |
|
925
|
|
|
|
|
|
|
and expected |
|
926
|
|
|
|
|
|
|
'identifier' |
|
927
|
|
|
|
|
|
|
} while (/\G$s,$s/gc); |
|
928
|
0
|
|
|
|
|
0
|
&skip; |
|
929
|
0
|
0
|
|
|
|
0
|
/\G;$s/cg |
|
930
|
|
|
|
|
|
|
or expected 'semicolon'; |
|
931
|
|
|
|
|
|
|
} |
|
932
|
0
|
|
|
|
|
0
|
push @$ret, &finish_for_sc_sc; |
|
933
|
|
|
|
|
|
|
} |
|
934
|
|
|
|
|
|
|
else { |
|
935
|
0
|
0
|
|
|
|
0
|
/\Gin$s/cg or expected |
|
936
|
|
|
|
|
|
|
"'in', comma or semicolon"; |
|
937
|
0
|
|
|
|
|
0
|
push @$ret, 'in'; |
|
938
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
939
|
|
|
|
|
|
|
and expected 'expresssion'; |
|
940
|
0
|
|
|
|
|
0
|
&skip; |
|
941
|
0
|
0
|
|
|
|
0
|
/\G\)$s/cg or expected "')'"; |
|
942
|
|
|
|
|
|
|
} |
|
943
|
|
|
|
|
|
|
} |
|
944
|
|
|
|
|
|
|
elsif(@$ret != push @$ret, &expr_noin) { |
|
945
|
0
|
|
|
|
|
0
|
&skip; |
|
946
|
0
|
0
|
|
|
|
0
|
if (/\G;$s/gc) { |
|
947
|
|
|
|
|
|
|
# if there's a semicolon then |
|
948
|
|
|
|
|
|
|
# this is a for(;;) loop |
|
949
|
0
|
|
|
|
|
0
|
push @$ret, &finish_for_sc_sc; |
|
950
|
|
|
|
|
|
|
} |
|
951
|
|
|
|
|
|
|
else { |
|
952
|
0
|
0
|
|
|
|
0
|
/\Gin$s/cg or expected |
|
953
|
|
|
|
|
|
|
"'in' or semicolon"; |
|
954
|
0
|
|
|
|
|
0
|
push @$ret, 'in'; |
|
955
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
956
|
|
|
|
|
|
|
and expected 'expresssion'; |
|
957
|
0
|
|
|
|
|
0
|
&skip; |
|
958
|
0
|
0
|
|
|
|
0
|
/\G\)$s/cg or expected "')'"; |
|
959
|
|
|
|
|
|
|
} |
|
960
|
|
|
|
|
|
|
} |
|
961
|
|
|
|
|
|
|
else { |
|
962
|
0
|
|
|
|
|
0
|
push @$ret, 'empty'; |
|
963
|
0
|
0
|
|
|
|
0
|
/\G;$s/cg |
|
964
|
|
|
|
|
|
|
or expected 'expression or semicolon'; |
|
965
|
0
|
|
|
|
|
0
|
push @$ret, &finish_for_sc_sc; |
|
966
|
|
|
|
|
|
|
} |
|
967
|
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
# body of the for loop |
|
969
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &statement |
|
970
|
|
|
|
|
|
|
or expected 'statement'; |
|
971
|
|
|
|
|
|
|
|
|
972
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
973
|
|
|
|
|
|
|
|
|
974
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
975
|
|
|
|
|
|
|
} |
|
976
|
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
sub with() { # almost identical to while |
|
978
|
16
|
|
|
16
|
0
|
27
|
my $pos = pos; |
|
979
|
16
|
50
|
|
|
|
125
|
/\Gwith$s\($s/cg or return; |
|
980
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'with']; |
|
981
|
|
|
|
|
|
|
|
|
982
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
983
|
|
|
|
|
|
|
and expected 'expression'; |
|
984
|
0
|
|
|
|
|
0
|
&skip; |
|
985
|
0
|
0
|
|
|
|
0
|
/\G\)$s/gc or expected "')'"; |
|
986
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &statement |
|
987
|
|
|
|
|
|
|
or expected 'statement'; |
|
988
|
|
|
|
|
|
|
|
|
989
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
990
|
|
|
|
|
|
|
|
|
991
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
992
|
|
|
|
|
|
|
} |
|
993
|
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
sub switch() { |
|
995
|
16
|
|
|
16
|
0
|
26
|
my $pos = pos; |
|
996
|
16
|
50
|
|
|
|
130
|
/\Gswitch$s\($s/cg or return; |
|
997
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'switch']; |
|
998
|
|
|
|
|
|
|
|
|
999
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
1000
|
|
|
|
|
|
|
and expected 'expression'; |
|
1001
|
0
|
|
|
|
|
0
|
&skip; |
|
1002
|
0
|
0
|
|
|
|
0
|
/\G\)$s/gc or expected "')'"; |
|
1003
|
0
|
0
|
|
|
|
0
|
/\G\{$s/gc or expected "'{'"; |
|
1004
|
|
|
|
|
|
|
|
|
1005
|
0
|
|
|
|
|
0
|
while (/\G case(?!$id_cont) $s/cgx) { |
|
1006
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
1007
|
|
|
|
|
|
|
and expected 'expression'; |
|
1008
|
0
|
|
|
|
|
0
|
&skip; |
|
1009
|
0
|
0
|
|
|
|
0
|
/\G:$s/cg or expected 'colon'; |
|
1010
|
0
|
|
|
|
|
0
|
push @$ret, &statements; |
|
1011
|
|
|
|
|
|
|
} |
|
1012
|
0
|
|
|
|
|
0
|
my $default=0; |
|
1013
|
0
|
0
|
|
|
|
0
|
if (/\G default(?!$id_cont) $s/cgx) { |
|
1014
|
0
|
0
|
|
|
|
0
|
/\G : $s /cgx or expected 'colon'; |
|
1015
|
0
|
|
|
|
|
0
|
push @$ret, default => &statements; |
|
1016
|
0
|
|
|
|
|
0
|
++$default; |
|
1017
|
|
|
|
|
|
|
} |
|
1018
|
0
|
|
|
|
|
0
|
while (/\G case(?!$id_cont) $s/cgx) { |
|
1019
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr |
|
1020
|
|
|
|
|
|
|
and expected 'expression'; |
|
1021
|
0
|
|
|
|
|
0
|
&skip; |
|
1022
|
0
|
0
|
|
|
|
0
|
/\G:$s/cg or expected 'colon'; |
|
1023
|
0
|
|
|
|
|
0
|
push @$ret, &statements; |
|
1024
|
|
|
|
|
|
|
} |
|
1025
|
0
|
0
|
|
|
|
0
|
/\G \} $s /cgx or expected ( |
|
|
|
0
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
$default |
|
1027
|
|
|
|
|
|
|
? "'}' or 'case'" |
|
1028
|
|
|
|
|
|
|
: "'}', 'case' or 'default'" |
|
1029
|
|
|
|
|
|
|
); |
|
1030
|
|
|
|
|
|
|
|
|
1031
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1032
|
|
|
|
|
|
|
|
|
1033
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1034
|
|
|
|
|
|
|
} |
|
1035
|
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
sub try() { |
|
1037
|
16
|
|
|
16
|
0
|
21
|
my $pos = pos; |
|
1038
|
16
|
50
|
|
|
|
125
|
/\Gtry$s\{$s/cg or return; |
|
1039
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'try', &statements]; |
|
1040
|
|
|
|
|
|
|
|
|
1041
|
0
|
0
|
|
|
|
0
|
/\G \} $s /cgx or expected "'}'"; |
|
1042
|
|
|
|
|
|
|
|
|
1043
|
0
|
|
|
|
|
0
|
$pos = pos; |
|
1044
|
|
|
|
|
|
|
|
|
1045
|
0
|
0
|
|
|
|
0
|
if(/\Gcatch$s/cg) { |
|
1046
|
0
|
0
|
|
|
|
0
|
/\G \( $s /cgx or expected "'('"; |
|
1047
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &ident |
|
1048
|
|
|
|
|
|
|
and expected 'identifier'; |
|
1049
|
0
|
|
|
|
|
0
|
&skip; |
|
1050
|
0
|
0
|
|
|
|
0
|
/\G \) $s /cgx or expected "')'"; |
|
1051
|
|
|
|
|
|
|
|
|
1052
|
0
|
0
|
|
|
|
0
|
/\G \{ $s /cgx or expected "'{'"; |
|
1053
|
0
|
|
|
|
|
0
|
push @$ret, &statements; |
|
1054
|
0
|
0
|
|
|
|
0
|
/\G \} $s /cgx or expected "'}'"; |
|
1055
|
|
|
|
|
|
|
} |
|
1056
|
0
|
0
|
|
|
|
0
|
if(/\Gfinally$s/cg) { |
|
1057
|
0
|
0
|
|
|
|
0
|
/\G \{ $s /cgx or expected "'{'"; |
|
1058
|
0
|
|
|
|
|
0
|
push @$ret, &statements; |
|
1059
|
0
|
0
|
|
|
|
0
|
/\G \} $s /cgx or expected "'}'"; |
|
1060
|
|
|
|
|
|
|
} |
|
1061
|
|
|
|
|
|
|
|
|
1062
|
0
|
0
|
|
|
|
0
|
pos eq $pos and expected "'catch' or 'finally'"; |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1065
|
|
|
|
|
|
|
|
|
1066
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1067
|
|
|
|
|
|
|
} |
|
1068
|
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
sub labelled() { |
|
1070
|
16
|
|
|
16
|
0
|
23
|
my $pos = pos; |
|
1071
|
16
|
50
|
|
|
|
160
|
/\G ($ident) $s : $s/cgx or return; |
|
1072
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'labelled', unescape_ident $1]; |
|
1073
|
|
|
|
|
|
|
|
|
1074
|
0
|
|
|
|
|
0
|
while (/\G($ident)$s:$s/cg) { |
|
1075
|
0
|
|
|
|
|
0
|
push @$ret, unescape_ident $1; |
|
1076
|
|
|
|
|
|
|
} |
|
1077
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &statement |
|
1078
|
|
|
|
|
|
|
or expected 'statement'; |
|
1079
|
|
|
|
|
|
|
|
|
1080
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1081
|
|
|
|
|
|
|
|
|
1082
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1083
|
|
|
|
|
|
|
} |
|
1084
|
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
sub var() { |
|
1086
|
16
|
|
|
16
|
0
|
25
|
my $pos = pos; |
|
1087
|
16
|
50
|
|
|
|
124
|
/\G var $S/cgx or return; |
|
1088
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'var']; |
|
1089
|
|
|
|
|
|
|
|
|
1090
|
0
|
|
|
|
|
0
|
do{ |
|
1091
|
0
|
|
|
|
|
0
|
push @$ret, &vardecl; |
|
1092
|
|
|
|
|
|
|
} while(/\G$s,$s/gc); |
|
1093
|
|
|
|
|
|
|
|
|
1094
|
0
|
|
|
|
|
0
|
optional_sc; |
|
1095
|
|
|
|
|
|
|
|
|
1096
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1097
|
|
|
|
|
|
|
|
|
1098
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1099
|
|
|
|
|
|
|
} |
|
1100
|
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
sub do() { |
|
1102
|
0
|
|
|
0
|
0
|
0
|
my $pos = pos; |
|
1103
|
0
|
0
|
|
|
|
0
|
/\G do(?!$id_cont)$s/cgx or return; |
|
1104
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'do']; |
|
1105
|
|
|
|
|
|
|
|
|
1106
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &statement |
|
1107
|
|
|
|
|
|
|
or expected 'statement'; |
|
1108
|
0
|
0
|
|
|
|
0
|
/\Gwhile$s/cg or expected "'while'"; |
|
1109
|
0
|
0
|
|
|
|
0
|
/\G\($s/cg or expected "'('"; |
|
1110
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &expr |
|
1111
|
|
|
|
|
|
|
or expected 'expression'; |
|
1112
|
0
|
|
|
|
|
0
|
&skip; |
|
1113
|
0
|
0
|
|
|
|
0
|
/\G\)/cog or expected "')'"; |
|
1114
|
|
|
|
|
|
|
|
|
1115
|
0
|
|
|
|
|
0
|
optional_sc; |
|
1116
|
|
|
|
|
|
|
|
|
1117
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1118
|
|
|
|
|
|
|
|
|
1119
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1120
|
|
|
|
|
|
|
} |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
sub continue() { |
|
1123
|
16
|
|
|
16
|
0
|
27
|
my $pos = pos; |
|
1124
|
16
|
50
|
|
|
|
81
|
/\G continue(?!$id_cont)/cogx or return; |
|
1125
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'continue']; |
|
1126
|
|
|
|
|
|
|
|
|
1127
|
0
|
0
|
|
|
|
0
|
/\G$h($ident)/cog |
|
1128
|
|
|
|
|
|
|
and push @$ret, unescape_ident $1; |
|
1129
|
|
|
|
|
|
|
|
|
1130
|
0
|
|
|
|
|
0
|
optional_sc; |
|
1131
|
|
|
|
|
|
|
|
|
1132
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1133
|
|
|
|
|
|
|
|
|
1134
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1135
|
|
|
|
|
|
|
} |
|
1136
|
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
sub break() { # almost identical to continue |
|
1138
|
16
|
|
|
16
|
0
|
29
|
my $pos = pos; |
|
1139
|
16
|
50
|
|
|
|
79
|
/\G break(?!$id_cont)/cogx or return; |
|
1140
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'break']; |
|
1141
|
|
|
|
|
|
|
|
|
1142
|
0
|
0
|
|
|
|
0
|
/\G$h($ident)/cog |
|
1143
|
|
|
|
|
|
|
and push @$ret, unescape_ident $1; |
|
1144
|
|
|
|
|
|
|
|
|
1145
|
0
|
|
|
|
|
0
|
optional_sc; |
|
1146
|
|
|
|
|
|
|
|
|
1147
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1148
|
|
|
|
|
|
|
|
|
1149
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1150
|
|
|
|
|
|
|
} |
|
1151
|
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
sub return() { |
|
1153
|
16
|
|
|
16
|
0
|
19
|
my $pos = pos; |
|
1154
|
16
|
50
|
|
|
|
81
|
/\G return(?!$id_cont)/cogx or return; |
|
1155
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'return']; |
|
1156
|
|
|
|
|
|
|
|
|
1157
|
0
|
|
|
|
|
0
|
$pos = pos; |
|
1158
|
0
|
|
|
|
|
0
|
/\G$h/g; # skip horz ws |
|
1159
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr and pos = $pos; |
|
1160
|
|
|
|
|
|
|
# reverse to before the white space if |
|
1161
|
|
|
|
|
|
|
# there is no expr |
|
1162
|
|
|
|
|
|
|
|
|
1163
|
0
|
|
|
|
|
0
|
optional_sc; |
|
1164
|
|
|
|
|
|
|
|
|
1165
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1166
|
|
|
|
|
|
|
|
|
1167
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1168
|
|
|
|
|
|
|
} |
|
1169
|
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
sub throw() { |
|
1171
|
16
|
|
|
16
|
0
|
22
|
my $pos = pos; |
|
1172
|
16
|
50
|
|
|
|
72
|
/\G throw(?!$id_cont)/cogx |
|
1173
|
|
|
|
|
|
|
or return; |
|
1174
|
0
|
|
|
|
|
0
|
my $ret = [[$pos], 'throw']; |
|
1175
|
|
|
|
|
|
|
|
|
1176
|
0
|
|
|
|
|
0
|
/\G$h/g; # skip horz ws |
|
1177
|
0
|
0
|
|
|
|
0
|
@$ret == push @$ret, &expr and expected 'expression'; |
|
1178
|
|
|
|
|
|
|
|
|
1179
|
0
|
|
|
|
|
0
|
optional_sc; |
|
1180
|
|
|
|
|
|
|
|
|
1181
|
0
|
|
|
|
|
0
|
push @{$$ret[0]},pos; |
|
|
0
|
|
|
|
|
0
|
|
|
1182
|
|
|
|
|
|
|
|
|
1183
|
0
|
|
|
|
|
0
|
bless $ret, JECS; |
|
1184
|
|
|
|
|
|
|
} |
|
1185
|
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
sub expr_statement() { |
|
1187
|
16
|
100
|
|
16
|
0
|
34
|
my $ret = &expr or return; |
|
1188
|
9
|
|
|
|
|
23
|
optional_sc; # the only difference in behaviour between |
|
1189
|
|
|
|
|
|
|
# this and &expr |
|
1190
|
5
|
|
|
|
|
21
|
$ret; |
|
1191
|
|
|
|
|
|
|
} |
|
1192
|
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
# -------- end of statement types----------# |
|
1196
|
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
# This takes care of trailing white space. |
|
1198
|
|
|
|
|
|
|
sub statement_default() { |
|
1199
|
10955
|
|
|
10955
|
0
|
24087
|
my $ret = [[pos]]; |
|
1200
|
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
# Statements that do not have an optional semicolon |
|
1202
|
10955
|
100
|
|
|
|
128548
|
if (/\G (?: |
|
1203
|
|
|
|
|
|
|
( \{ | ; ) |
|
1204
|
|
|
|
|
|
|
| |
|
1205
|
|
|
|
|
|
|
(function)$S |
|
1206
|
|
|
|
|
|
|
| |
|
1207
|
|
|
|
|
|
|
( if | w(?:hile|ith) | for | switch ) $s \( $s |
|
1208
|
|
|
|
|
|
|
| |
|
1209
|
|
|
|
|
|
|
( try $s \{ $s ) |
|
1210
|
|
|
|
|
|
|
| |
|
1211
|
|
|
|
|
|
|
($ident) $s : $s |
|
1212
|
|
|
|
|
|
|
) /xgc) { |
|
1213
|
101
|
|
|
101
|
|
812958
|
no warnings 'uninitialized'; |
|
|
101
|
|
|
|
|
247
|
|
|
|
101
|
|
|
|
|
231201
|
|
|
1214
|
1222
|
100
|
|
|
|
28208
|
if($1 eq '{') { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1215
|
166
|
|
|
|
|
374
|
push @$ret, 'statements'; |
|
1216
|
166
|
|
|
|
|
345
|
&skip; |
|
1217
|
166
|
|
|
|
|
586
|
while() { # 'last' does not work when 'while' is a |
|
1218
|
|
|
|
|
|
|
# statement modifier |
|
1219
|
509
|
100
|
|
|
|
1278
|
@$ret == push @$ret, |
|
1220
|
|
|
|
|
|
|
&statement_default and last; |
|
1221
|
|
|
|
|
|
|
} |
|
1222
|
|
|
|
|
|
|
|
|
1223
|
165
|
50
|
|
|
|
2346
|
expected "'}'" unless /\G\}$s/gc; |
|
1224
|
|
|
|
|
|
|
} |
|
1225
|
|
|
|
|
|
|
elsif($1 eq ';') { |
|
1226
|
156
|
|
|
|
|
306
|
push @$ret, 'empty'; |
|
1227
|
156
|
|
|
|
|
307
|
&skip; |
|
1228
|
|
|
|
|
|
|
} |
|
1229
|
|
|
|
|
|
|
elsif($2) { |
|
1230
|
34
|
|
|
|
|
51
|
push @$ret, 'function'; |
|
1231
|
34
|
50
|
|
|
|
74
|
@$ret == push @$ret, &ident |
|
1232
|
|
|
|
|
|
|
and expected "identifier"; |
|
1233
|
34
|
|
|
|
|
57
|
&skip; |
|
1234
|
34
|
|
|
|
|
51
|
push @$ret, ¶ms; |
|
1235
|
34
|
|
|
|
|
52
|
&skip; |
|
1236
|
34
|
50
|
|
|
|
94
|
/\G \{ /gcx or expected "'{'"; |
|
1237
|
|
|
|
|
|
|
{ |
|
1238
|
34
|
|
|
|
|
34
|
local $_vars = []; |
|
|
34
|
|
|
|
|
53
|
|
|
1239
|
34
|
|
|
|
|
67
|
push @$ret, &statements, $_vars; |
|
1240
|
|
|
|
|
|
|
} |
|
1241
|
34
|
50
|
|
|
|
287
|
/\G \}$s /gcx or expected "'}'"; |
|
1242
|
34
|
|
|
|
|
653
|
push @$_vars, $ret; |
|
1243
|
|
|
|
|
|
|
} |
|
1244
|
|
|
|
|
|
|
elsif($3 eq 'if') { |
|
1245
|
84
|
|
|
|
|
203
|
push @$ret, 'if'; |
|
1246
|
84
|
50
|
|
|
|
202
|
@$ret == push @$ret, &expr |
|
1247
|
|
|
|
|
|
|
and expected 'expression'; |
|
1248
|
84
|
|
|
|
|
192
|
&skip; |
|
1249
|
84
|
50
|
|
|
|
1096
|
/\G\)$s/gc or expected "')'"; |
|
1250
|
84
|
50
|
|
|
|
2579
|
@$ret != push @$ret, &statement_default |
|
1251
|
|
|
|
|
|
|
or expected 'statement'; |
|
1252
|
84
|
100
|
|
|
|
886
|
if (/\Gelse(?!$id_cont)$s/cg) { |
|
1253
|
29
|
50
|
|
|
|
806
|
@$ret == push @$ret, |
|
1254
|
|
|
|
|
|
|
&statement_default |
|
1255
|
|
|
|
|
|
|
and expected 'statement'; |
|
1256
|
|
|
|
|
|
|
} |
|
1257
|
|
|
|
|
|
|
} |
|
1258
|
|
|
|
|
|
|
elsif($3 eq 'while') { |
|
1259
|
22
|
|
|
|
|
50
|
push @$ret, 'while'; |
|
1260
|
22
|
50
|
|
|
|
51
|
@$ret == push @$ret, &expr |
|
1261
|
|
|
|
|
|
|
and expected 'expression'; |
|
1262
|
22
|
|
|
|
|
46
|
&skip; |
|
1263
|
22
|
50
|
|
|
|
425
|
/\G\)$s/gc or expected "')'"; |
|
1264
|
22
|
50
|
|
|
|
927
|
@$ret != push @$ret, &statement_default |
|
1265
|
|
|
|
|
|
|
or expected 'statement'; |
|
1266
|
|
|
|
|
|
|
} |
|
1267
|
|
|
|
|
|
|
elsif($3 eq 'for') { |
|
1268
|
355
|
|
|
|
|
853
|
push @$ret, 'for'; |
|
1269
|
355
|
100
|
|
|
|
3230
|
if (/\G var$S/cgx) { |
|
|
|
100
|
|
|
|
|
|
|
1270
|
118
|
|
|
|
|
4682
|
push @$ret, my $var = bless |
|
1271
|
|
|
|
|
|
|
[[pos() - length $1], 'var'], |
|
1272
|
|
|
|
|
|
|
'JE::Code::Statement'; |
|
1273
|
|
|
|
|
|
|
|
|
1274
|
118
|
|
|
|
|
305
|
push @$var, &vardecl_noin; |
|
1275
|
118
|
|
|
|
|
272
|
&skip; |
|
1276
|
118
|
100
|
|
|
|
1198
|
if (/\G([;,])$s/gc) { |
|
1277
|
|
|
|
|
|
|
# if there's a comma or sc then |
|
1278
|
|
|
|
|
|
|
# this is a for(;;) loop |
|
1279
|
85
|
100
|
|
|
|
1738
|
if ($1 eq ',') { |
|
1280
|
|
|
|
|
|
|
# finish getting the var |
|
1281
|
|
|
|
|
|
|
# decl list |
|
1282
|
34
|
|
|
|
|
44
|
do{ |
|
1283
|
34
|
50
|
|
|
|
84
|
@$var == |
|
1284
|
|
|
|
|
|
|
push @$var, &vardecl |
|
1285
|
|
|
|
|
|
|
and expected |
|
1286
|
|
|
|
|
|
|
'identifier' |
|
1287
|
|
|
|
|
|
|
} while (/\G$s,$s/gc); |
|
1288
|
34
|
|
|
|
|
1002
|
&skip; |
|
1289
|
34
|
50
|
|
|
|
271
|
/\G;$s/cg |
|
1290
|
|
|
|
|
|
|
or expected 'semicolon'; |
|
1291
|
|
|
|
|
|
|
} |
|
1292
|
85
|
|
|
|
|
594
|
push @$ret, &finish_for_sc_sc; |
|
1293
|
|
|
|
|
|
|
} |
|
1294
|
|
|
|
|
|
|
else { |
|
1295
|
33
|
50
|
|
|
|
1466
|
/\Gin$s/cg or expected |
|
1296
|
|
|
|
|
|
|
"'in', comma or semicolon"; |
|
1297
|
33
|
|
|
|
|
1675
|
push @$ret, 'in'; |
|
1298
|
33
|
50
|
|
|
|
89
|
@$ret == push @$ret, &expr |
|
1299
|
|
|
|
|
|
|
and expected 'expresssion'; |
|
1300
|
33
|
|
|
|
|
124
|
&skip; |
|
1301
|
33
|
50
|
|
|
|
487
|
/\G\)$s/cg or expected "')'"; |
|
1302
|
|
|
|
|
|
|
} |
|
1303
|
|
|
|
|
|
|
} |
|
1304
|
|
|
|
|
|
|
elsif(@$ret != push @$ret, &expr_noin) { |
|
1305
|
224
|
|
|
|
|
424
|
&skip; |
|
1306
|
224
|
100
|
|
|
|
2547
|
if (/\G;$s/gc) { |
|
1307
|
|
|
|
|
|
|
# if there's a semicolon then |
|
1308
|
|
|
|
|
|
|
# this is a for(;;) loop |
|
1309
|
203
|
|
|
|
|
2483
|
push @$ret, &finish_for_sc_sc; |
|
1310
|
|
|
|
|
|
|
} |
|
1311
|
|
|
|
|
|
|
else { |
|
1312
|
21
|
50
|
|
|
|
1709
|
/\Gin$s/cg or expected |
|
1313
|
|
|
|
|
|
|
"'in' or semicolon"; |
|
1314
|
21
|
|
|
|
|
1739
|
push @$ret, 'in'; |
|
1315
|
21
|
50
|
|
|
|
65
|
@$ret == push @$ret, &expr |
|
1316
|
|
|
|
|
|
|
and expected 'expresssion'; |
|
1317
|
21
|
|
|
|
|
57
|
&skip; |
|
1318
|
21
|
50
|
|
|
|
301
|
/\G\)$s/cg or expected "')'"; |
|
1319
|
|
|
|
|
|
|
} |
|
1320
|
|
|
|
|
|
|
} |
|
1321
|
|
|
|
|
|
|
else { |
|
1322
|
13
|
|
|
|
|
30
|
push @$ret, 'empty'; |
|
1323
|
13
|
50
|
|
|
|
129
|
/\G;$s/cg |
|
1324
|
|
|
|
|
|
|
or expected 'expression or semicolon'; |
|
1325
|
13
|
|
|
|
|
214
|
push @$ret, &finish_for_sc_sc; |
|
1326
|
|
|
|
|
|
|
} |
|
1327
|
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
# body of the for loop |
|
1329
|
355
|
50
|
|
|
|
4498
|
@$ret != push @$ret, &statement_default |
|
1330
|
|
|
|
|
|
|
or expected 'statement'; |
|
1331
|
|
|
|
|
|
|
} |
|
1332
|
|
|
|
|
|
|
elsif($3 eq 'with') { |
|
1333
|
18
|
|
|
|
|
42
|
push @$ret, 'with'; |
|
1334
|
18
|
50
|
|
|
|
48
|
@$ret == push @$ret, &expr |
|
1335
|
|
|
|
|
|
|
and expected 'expression'; |
|
1336
|
18
|
|
|
|
|
39
|
&skip; |
|
1337
|
18
|
50
|
|
|
|
461
|
/\G\)$s/gc or expected "')'"; |
|
1338
|
18
|
50
|
|
|
|
1200
|
@$ret != push @$ret, &statement_default |
|
1339
|
|
|
|
|
|
|
or expected 'statement'; |
|
1340
|
|
|
|
|
|
|
} |
|
1341
|
|
|
|
|
|
|
elsif($3 eq 'switch') { |
|
1342
|
33
|
|
|
|
|
70
|
push @$ret, 'switch'; |
|
1343
|
33
|
50
|
|
|
|
69
|
@$ret == push @$ret, &expr |
|
1344
|
|
|
|
|
|
|
and expected 'expression'; |
|
1345
|
33
|
|
|
|
|
59
|
&skip; |
|
1346
|
33
|
50
|
|
|
|
469
|
/\G\)$s/gc or expected "')'"; |
|
1347
|
33
|
50
|
|
|
|
777
|
/\G\{$s/gc or expected "'{'"; |
|
1348
|
|
|
|
|
|
|
|
|
1349
|
33
|
|
|
|
|
630
|
while (/\G case(?!$id_cont) $s/cgx) { |
|
1350
|
31
|
50
|
|
|
|
361
|
@$ret == push @$ret, &expr |
|
1351
|
|
|
|
|
|
|
and expected 'expression'; |
|
1352
|
31
|
|
|
|
|
52
|
&skip; |
|
1353
|
31
|
50
|
|
|
|
193
|
/\G:$s/cg or expected 'colon'; |
|
1354
|
31
|
|
|
|
|
537
|
push @$ret, &statements; |
|
1355
|
|
|
|
|
|
|
} |
|
1356
|
33
|
|
|
|
|
447
|
my $default=0; |
|
1357
|
33
|
100
|
|
|
|
236
|
if (/\G default(?!$id_cont) $s/cgx) { |
|
1358
|
20
|
50
|
|
|
|
461
|
/\G : $s /cgx or expected 'colon'; |
|
1359
|
20
|
|
|
|
|
592
|
push @$ret, default => &statements; |
|
1360
|
20
|
|
|
|
|
31
|
++$default; |
|
1361
|
|
|
|
|
|
|
} |
|
1362
|
33
|
|
|
|
|
637
|
while (/\G case(?!$id_cont) $s/cgx) { |
|
1363
|
19
|
50
|
|
|
|
352
|
@$ret == push @$ret, &expr |
|
1364
|
|
|
|
|
|
|
and expected 'expression'; |
|
1365
|
19
|
|
|
|
|
35
|
&skip; |
|
1366
|
19
|
50
|
|
|
|
172
|
/\G:$s/cg or expected 'colon'; |
|
1367
|
19
|
|
|
|
|
604
|
push @$ret, &statements; |
|
1368
|
|
|
|
|
|
|
} |
|
1369
|
33
|
0
|
|
|
|
674
|
/\G \} $s /cgx or expected ( |
|
|
|
50
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
$default |
|
1371
|
|
|
|
|
|
|
? "'}' or 'case'" |
|
1372
|
|
|
|
|
|
|
: "'}', 'case' or 'default'" |
|
1373
|
|
|
|
|
|
|
); |
|
1374
|
|
|
|
|
|
|
} |
|
1375
|
|
|
|
|
|
|
elsif($4) { # try |
|
1376
|
316
|
|
|
|
|
973
|
push @$ret, 'try', &statements; |
|
1377
|
316
|
50
|
|
|
|
3846
|
/\G \} $s /cgx or expected "'}'"; |
|
1378
|
|
|
|
|
|
|
|
|
1379
|
316
|
|
|
|
|
7739
|
my $pos = pos; |
|
1380
|
|
|
|
|
|
|
|
|
1381
|
316
|
100
|
|
|
|
2467
|
if(/\Gcatch$s/cg) { |
|
1382
|
314
|
50
|
|
|
|
8358
|
/\G \( $s /cgx or expected "'('"; |
|
1383
|
314
|
50
|
|
|
|
7023
|
@$ret == push @$ret, &ident |
|
1384
|
|
|
|
|
|
|
and expected 'identifier'; |
|
1385
|
314
|
|
|
|
|
727
|
&skip; |
|
1386
|
314
|
50
|
|
|
|
3152
|
/\G \) $s /cgx or expected "')'"; |
|
1387
|
|
|
|
|
|
|
|
|
1388
|
314
|
50
|
|
|
|
8426
|
/\G \{ $s /cgx or expected "'{'"; |
|
1389
|
314
|
|
|
|
|
6594
|
push @$ret, &statements; |
|
1390
|
314
|
50
|
|
|
|
3575
|
/\G \} $s /cgx or expected "'}'"; |
|
1391
|
|
|
|
|
|
|
} |
|
1392
|
316
|
100
|
|
|
|
8866
|
if(/\Gfinally$s/cg) { |
|
1393
|
7
|
50
|
|
|
|
289
|
/\G \{ $s /cgx or expected "'{'"; |
|
1394
|
7
|
|
|
|
|
598
|
push @$ret, &statements; |
|
1395
|
7
|
50
|
|
|
|
84
|
/\G \} $s /cgx or expected "'}'"; |
|
1396
|
|
|
|
|
|
|
} |
|
1397
|
|
|
|
|
|
|
|
|
1398
|
316
|
50
|
|
|
|
7789
|
pos eq $pos and expected "'catch' or 'finally'"; |
|
1399
|
|
|
|
|
|
|
} |
|
1400
|
|
|
|
|
|
|
else { # labelled statement |
|
1401
|
38
|
|
|
|
|
109
|
push @$ret, 'labelled', unescape_ident $5; |
|
1402
|
38
|
|
|
|
|
641
|
while (/\G($ident)$s:$s/cg) { |
|
1403
|
21
|
|
|
|
|
1554
|
push @$ret, unescape_ident $1; |
|
1404
|
|
|
|
|
|
|
} |
|
1405
|
38
|
50
|
|
|
|
3187
|
@$ret != push @$ret, &statement_default |
|
1406
|
|
|
|
|
|
|
or expected 'statement'; |
|
1407
|
|
|
|
|
|
|
} |
|
1408
|
|
|
|
|
|
|
} |
|
1409
|
|
|
|
|
|
|
# Statements that do have an optional semicolon |
|
1410
|
|
|
|
|
|
|
else { |
|
1411
|
9733
|
100
|
|
|
|
255732
|
if (/\G var$S/xcg) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1412
|
339
|
|
|
|
|
5379
|
push @$ret, 'var'; |
|
1413
|
|
|
|
|
|
|
|
|
1414
|
339
|
|
|
|
|
475
|
do{ |
|
1415
|
351
|
|
|
|
|
1550
|
push @$ret, &vardecl; |
|
1416
|
|
|
|
|
|
|
} while(/\G$s,$s/gc); |
|
1417
|
|
|
|
|
|
|
} |
|
1418
|
|
|
|
|
|
|
elsif(/\Gdo(?!$id_cont)$s/cg) { |
|
1419
|
25
|
|
|
|
|
364
|
push @$ret, 'do'; |
|
1420
|
25
|
50
|
|
|
|
85
|
@$ret != push @$ret, &statement_default |
|
1421
|
|
|
|
|
|
|
or expected 'statement'; |
|
1422
|
25
|
50
|
|
|
|
267
|
/\Gwhile$s/cg or expected "'while'"; |
|
1423
|
25
|
50
|
|
|
|
934
|
/\G\($s/cg or expected "'('"; |
|
1424
|
25
|
50
|
|
|
|
707
|
@$ret != push @$ret, &expr |
|
1425
|
|
|
|
|
|
|
or expected 'expression'; |
|
1426
|
25
|
|
|
|
|
57
|
&skip; |
|
1427
|
25
|
50
|
|
|
|
334
|
/\G\)/cog or expected "')'"; |
|
1428
|
|
|
|
|
|
|
} |
|
1429
|
|
|
|
|
|
|
elsif(/\G(continue|break)(?!$id_cont)/cog) { |
|
1430
|
109
|
|
|
|
|
1760
|
push @$ret, $1; |
|
1431
|
109
|
100
|
|
|
|
880
|
/\G$h($ident)/cog |
|
1432
|
|
|
|
|
|
|
and push @$ret, unescape_ident $1; |
|
1433
|
|
|
|
|
|
|
} |
|
1434
|
|
|
|
|
|
|
elsif(/\Greturn(?!$id_cont)/cog) { |
|
1435
|
135
|
|
|
|
|
1301
|
push @$ret, 'return'; |
|
1436
|
135
|
|
|
|
|
261
|
my $pos = pos; |
|
1437
|
135
|
|
|
|
|
1485
|
/\G$h/g; # skip horz ws |
|
1438
|
135
|
100
|
|
|
|
5858
|
@$ret == push @$ret, &expr and pos = $pos; |
|
1439
|
|
|
|
|
|
|
# reverse to before the white space if |
|
1440
|
|
|
|
|
|
|
# there is no expr |
|
1441
|
|
|
|
|
|
|
} |
|
1442
|
|
|
|
|
|
|
elsif(/\Gthrow(?!$id_cont)/cog) { |
|
1443
|
23
|
|
|
|
|
59
|
push @$ret, 'throw'; |
|
1444
|
23
|
|
|
|
|
314
|
/\G$h/g; # skip horz ws |
|
1445
|
23
|
100
|
|
|
|
1434
|
@$ret == push @$ret, &expr |
|
1446
|
|
|
|
|
|
|
and expected 'expression'; |
|
1447
|
|
|
|
|
|
|
} |
|
1448
|
|
|
|
|
|
|
else { # expression statement |
|
1449
|
9102
|
100
|
|
|
|
87691
|
$ret = &expr or return; |
|
1450
|
|
|
|
|
|
|
} |
|
1451
|
|
|
|
|
|
|
|
|
1452
|
|
|
|
|
|
|
# Check for optional semicolon |
|
1453
|
8195
|
100
|
|
|
|
104295
|
m-$optional_sc-cgx |
|
1454
|
|
|
|
|
|
|
or expected "semicolon, '}' or end of line"; |
|
1455
|
|
|
|
|
|
|
} |
|
1456
|
9413
|
100
|
|
|
|
20670
|
push @{$$ret[0]},pos unless @{$$ret[0]} == 2; # an expr will |
|
|
1851
|
|
|
|
|
4094
|
|
|
|
9413
|
|
|
|
|
23664
|
|
|
1457
|
|
|
|
|
|
|
# already have this |
|
1458
|
|
|
|
|
|
|
|
|
1459
|
9413
|
100
|
|
|
|
26732
|
ref $ret eq 'ARRAY' and bless $ret, 'JE::Code::Statement'; |
|
1460
|
|
|
|
|
|
|
|
|
1461
|
9413
|
|
|
|
|
32727
|
return $ret; |
|
1462
|
|
|
|
|
|
|
} |
|
1463
|
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
sub statement() { # public |
|
1465
|
16
|
|
|
16
|
0
|
24
|
my $ret; |
|
1466
|
16
|
|
|
|
|
30
|
for my $sub(@_stms) { |
|
1467
|
208
|
100
|
|
|
|
4912
|
defined($ret = &$sub) |
|
1468
|
|
|
|
|
|
|
and last; |
|
1469
|
|
|
|
|
|
|
} |
|
1470
|
10
|
100
|
|
|
|
51
|
defined $ret ? $ret : () |
|
1471
|
|
|
|
|
|
|
} |
|
1472
|
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
# This takes care of leading white space. |
|
1474
|
|
|
|
|
|
|
sub statements() { |
|
1475
|
1036
|
|
|
1036
|
0
|
4937
|
my $ret = bless [[pos], 'statements'], 'JE::Code::Statement'; |
|
1476
|
1036
|
|
|
|
|
9019
|
/\G$s/g; # skip initial whitespace |
|
1477
|
1036
|
|
|
|
|
9985
|
while () { # 'last' does not work when 'while' is a |
|
1478
|
|
|
|
|
|
|
# statement modifier |
|
1479
|
2937
|
50
|
|
|
|
8830
|
@$ret != push @$ret, |
|
|
|
100
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
$_parser ? &statement : &statement_default |
|
1481
|
|
|
|
|
|
|
or last; |
|
1482
|
|
|
|
|
|
|
} |
|
1483
|
1036
|
|
|
|
|
1972
|
push @{$$ret[0]},pos; |
|
|
1036
|
|
|
|
|
2812
|
|
|
1484
|
1036
|
|
|
|
|
3187
|
return $ret; |
|
1485
|
|
|
|
|
|
|
} |
|
1486
|
|
|
|
|
|
|
|
|
1487
|
|
|
|
|
|
|
sub program() { # like statements(), but it allows function declarations |
|
1488
|
|
|
|
|
|
|
# as well |
|
1489
|
351
|
|
|
351
|
0
|
2001
|
my $ret = bless [[pos], 'statements'], 'JE::Code::Statement'; |
|
1490
|
351
|
|
|
|
|
6673
|
/\G$s/g; # skip initial whitespace |
|
1491
|
351
|
100
|
|
|
|
24841
|
if($_parser) { |
|
1492
|
11
|
|
|
|
|
14
|
while () { |
|
1493
|
|
|
|
|
|
|
DECL: { |
|
1494
|
16
|
|
|
|
|
18
|
for my $sub(@_decls) { |
|
|
16
|
|
|
|
|
65
|
|
|
1495
|
0
|
0
|
|
|
|
0
|
@$ret != push @$ret, &$sub |
|
1496
|
|
|
|
|
|
|
and redo DECL; |
|
1497
|
|
|
|
|
|
|
} |
|
1498
|
|
|
|
|
|
|
} |
|
1499
|
16
|
100
|
|
|
|
48
|
@$ret != push @$ret, &statement or last; |
|
1500
|
|
|
|
|
|
|
} |
|
1501
|
|
|
|
|
|
|
} |
|
1502
|
|
|
|
|
|
|
else { |
|
1503
|
340
|
|
|
|
|
578
|
while () { |
|
1504
|
6938
|
|
|
|
|
7416
|
while() { |
|
1505
|
7070
|
100
|
|
|
|
16015
|
@$ret == push @$ret, &function and last; |
|
1506
|
|
|
|
|
|
|
} |
|
1507
|
6938
|
100
|
|
|
|
29774
|
@$ret != push @$ret, &statement_default or last; |
|
1508
|
|
|
|
|
|
|
} |
|
1509
|
|
|
|
|
|
|
} |
|
1510
|
330
|
|
|
|
|
801
|
push @{$$ret[0]},pos; |
|
|
330
|
|
|
|
|
991
|
|
|
1511
|
330
|
|
|
|
|
952
|
return $ret; |
|
1512
|
|
|
|
|
|
|
} |
|
1513
|
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
|
|
1515
|
|
|
|
|
|
|
# ~~~ The second arg to add_line_number is a bit ridiculous. I may change |
|
1516
|
|
|
|
|
|
|
# add_line_number's parameter list, perhaps so it accepts either a |
|
1517
|
|
|
|
|
|
|
# code object, or (src,file,line) if $_[1] isn'ta JE::Code. I don't |
|
1518
|
|
|
|
|
|
|
# know.... |
|
1519
|
|
|
|
|
|
|
sub _parse($$$;$$) { # Returns just the parse tree, not a JE::Code object. |
|
1520
|
|
|
|
|
|
|
# Actually, it returns the source followed by the |
|
1521
|
|
|
|
|
|
|
# parse tree in list context, or just the parse tree |
|
1522
|
|
|
|
|
|
|
# in scalar context. |
|
1523
|
386
|
|
|
386
|
|
792
|
my ($rule, $src, $my_global, $file, $line) = @_; |
|
1524
|
386
|
|
|
|
|
992
|
local our($_source, $_file, $_line) =($src,$file,$line); |
|
1525
|
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
# Note: We *hafta* stringify the $src, because it could be an |
|
1527
|
|
|
|
|
|
|
# object with overloading (e.g., JE::String) and we |
|
1528
|
|
|
|
|
|
|
# need to rely on its pos(), which simply cannot be |
|
1529
|
|
|
|
|
|
|
# done with an object. Furthermore, perl5.8.5 is |
|
1530
|
|
|
|
|
|
|
# a bit buggy and sometimes mangles the contents |
|
1531
|
|
|
|
|
|
|
# of $1 when one does $obj =~ /(...)/. |
|
1532
|
386
|
100
|
100
|
|
|
5082
|
$src = defined blessed $src && $src->isa("JE::String") |
|
1533
|
|
|
|
|
|
|
? $src->value16 |
|
1534
|
|
|
|
|
|
|
: surrogify("$src"); |
|
1535
|
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
# remove unicode format chrs |
|
1537
|
386
|
|
|
|
|
58172
|
$src =~ s/\p{Cf}//g; |
|
1538
|
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
# In HTML mode, modify the whitespace regexps to remove HTML com- |
|
1540
|
|
|
|
|
|
|
# ment delimiters and following junk up to the end of the line. |
|
1541
|
386
|
100
|
|
|
|
1445
|
$my_global->html_mode and |
|
1542
|
|
|
|
|
|
|
local $s = qr((?> |
|
1543
|
|
|
|
|
|
|
(?> [ \t\x0b\f\xa0\p{Zs}]* ) |
|
1544
|
|
|
|
|
|
|
(?> (?> |
|
1545
|
|
|
|
|
|
|
$n |
|
1546
|
|
|
|
|
|
|
(?>(?: |
|
1547
|
|
|
|
|
|
|
(?>[ \t\x0b\f\xa0\p{Zs}]*) --> |
|
1548
|
|
|
|
|
|
|
(?>[^\cm\cj\x{2028}\x{2029}]*)(?>$n|\z) |
|
1549
|
|
|
|
|
|
|
)?) |
|
1550
|
|
|
|
|
|
|
| |
|
1551
|
|
|
|
|
|
|
^ |
|
1552
|
|
|
|
|
|
|
(?>[ \t\x0b\f\xa0\p{Zs}]*) --> |
|
1553
|
|
|
|
|
|
|
(?>[^\cm\cj\x{2028}\x{2029}]*)(?>$n|\z) |
|
1554
|
|
|
|
|
|
|
| |
|
1555
|
|
|
|
|
|
|
(?>//| |