| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Mildew::AST::Helpers; |
|
2
|
|
|
|
|
|
|
BEGIN { |
|
3
|
1
|
|
|
1
|
|
729
|
$Mildew::AST::Helpers::VERSION = '0.05'; |
|
4
|
|
|
|
|
|
|
} |
|
5
|
1
|
|
|
1
|
|
6
|
use Exporter 'import'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
54
|
|
|
6
|
|
|
|
|
|
|
our @EXPORT = qw(string reg integer call FETCH lookup capturize let fcall name_components empty_sig routine code move_CONTROL XXX trailing_return varname lookupf curlies named_and_positional dump lookup_package YYY wrap_in_block); |
|
7
|
1
|
|
|
1
|
|
4
|
use Carp 'confess'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
63
|
|
|
8
|
1
|
|
|
1
|
|
4006
|
use Term::ANSIColor qw(:constants); |
|
|
1
|
|
|
|
|
11287
|
|
|
|
1
|
|
|
|
|
920
|
|
|
9
|
1
|
|
|
1
|
|
1860
|
use PadWalker qw(peek_my); |
|
|
1
|
|
|
|
|
4850
|
|
|
|
1
|
|
|
|
|
97
|
|
|
10
|
1
|
|
|
1
|
|
1605
|
use YAML::XS qw(Dump); |
|
|
1
|
|
|
|
|
23408
|
|
|
|
1
|
|
|
|
|
82
|
|
|
11
|
1
|
|
|
1
|
|
2545
|
use utf8; |
|
|
1
|
|
|
|
|
11
|
|
|
|
1
|
|
|
|
|
7
|
|
|
12
|
1
|
|
|
1
|
|
43
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
45
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub YYY { |
|
15
|
1
|
|
|
1
|
|
6
|
use YAML::XS; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
891
|
|
|
16
|
|
|
|
|
|
|
# Mildew::prune($_[0]); |
|
17
|
0
|
|
|
0
|
0
|
|
die Dump($_[0]); |
|
18
|
|
|
|
|
|
|
} |
|
19
|
|
|
|
|
|
|
sub string($) { |
|
20
|
0
|
|
|
0
|
0
|
|
Mildew::AST::StringConstant->new(value=>$_[0]); |
|
21
|
|
|
|
|
|
|
} |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub reg($) { |
|
24
|
0
|
|
|
0
|
0
|
|
Mildew::AST::Reg->new(name=>$_[0]); |
|
25
|
|
|
|
|
|
|
} |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub integer($) { |
|
28
|
0
|
|
|
0
|
0
|
|
Mildew::AST::IntegerConstant->new(value=>$_[0]); |
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub call { |
|
33
|
0
|
|
0
|
0
|
0
|
|
Mildew::AST::Call->new(identifier=>string($_[0]),capture=>Mildew::AST::Capture->new(invocant => $_[1],positional => $_[2]//[],named => $_[3]//[])); |
|
|
|
|
0
|
|
|
|
|
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub FETCH { |
|
37
|
0
|
|
|
0
|
|
|
my $arg = shift; |
|
38
|
0
|
|
|
|
|
|
call FETCH => $arg |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub lookup { |
|
42
|
0
|
|
|
0
|
0
|
|
my $thing = shift; |
|
43
|
0
|
|
|
|
|
|
call lookup => reg '$scope',[string $thing]; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
sub lookupf { |
|
46
|
0
|
|
|
0
|
0
|
|
FETCH(lookup(@_)); |
|
47
|
|
|
|
|
|
|
} |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub curlies { |
|
50
|
0
|
|
|
0
|
0
|
|
my $thing = shift; |
|
51
|
0
|
|
|
|
|
|
call 'postcircumfix:{ }' => reg '$scope',[string $thing]; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub fcall { |
|
55
|
0
|
|
|
0
|
0
|
|
my $func = shift; |
|
56
|
0
|
0
|
|
|
|
|
unless (ref $func) { |
|
57
|
0
|
|
|
|
|
|
$func = FETCH(lookup($func)); |
|
58
|
|
|
|
|
|
|
} |
|
59
|
0
|
|
|
|
|
|
call 'postcircumfix:( )' => $func, [capturize(@_)]; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
sub capturize { |
|
62
|
0
|
|
|
0
|
0
|
|
my ($pos,$named) = @_; |
|
63
|
0
|
|
0
|
|
|
|
Mildew::AST::Call->new( |
|
|
|
|
0
|
|
|
|
|
|
64
|
|
|
|
|
|
|
identifier => string "new", |
|
65
|
|
|
|
|
|
|
capture => Mildew::AST::Capture->new( |
|
66
|
|
|
|
|
|
|
invocant => FETCH(lookup("capture")), |
|
67
|
|
|
|
|
|
|
positional => $pos // [], |
|
68
|
|
|
|
|
|
|
named => $named // [] |
|
69
|
|
|
|
|
|
|
) |
|
70
|
|
|
|
|
|
|
) |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub let { |
|
74
|
0
|
|
|
0
|
0
|
|
my ($value,$block) = @_; |
|
75
|
0
|
|
|
|
|
|
my $adhoc_sig = $Mildew::adhoc_sig; |
|
76
|
0
|
|
|
0
|
|
|
Mildew::AST::Let->new(value=>$value,block=>sub { local $Mildew::adhoc_sig = $adhoc_sig;$block->(@_)}); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub empty_sig { |
|
80
|
0
|
|
|
0
|
0
|
|
Mildew::AST::Call->new |
|
81
|
|
|
|
|
|
|
( identifier => string 'new', |
|
82
|
|
|
|
|
|
|
capture => Mildew::AST::Capture->new |
|
83
|
|
|
|
|
|
|
( invocant => FETCH(lookup('AdhocSignature')), |
|
84
|
|
|
|
|
|
|
positional => [], |
|
85
|
|
|
|
|
|
|
named => |
|
86
|
|
|
|
|
|
|
[ string 'BIND' => Mildew::AST::Block->new |
|
87
|
|
|
|
|
|
|
( regs => [qw(interpreter scope capture)], |
|
88
|
|
|
|
|
|
|
stmts => trailing_return([]))])); |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub block_sig { |
|
92
|
0
|
|
|
0
|
0
|
|
Mildew::AST::Call->new |
|
93
|
|
|
|
|
|
|
( identifier => string 'new', |
|
94
|
|
|
|
|
|
|
capture => Mildew::AST::Capture->new |
|
95
|
|
|
|
|
|
|
( invocant => FETCH(lookup('AdhocSignature')), |
|
96
|
|
|
|
|
|
|
positional => [], |
|
97
|
|
|
|
|
|
|
named => |
|
98
|
|
|
|
|
|
|
[ string 'BIND' => Mildew::AST::Block->new |
|
99
|
|
|
|
|
|
|
( regs => [qw(interpreter scope capture)], |
|
100
|
|
|
|
|
|
|
stmts => trailing_return([ |
|
101
|
|
|
|
|
|
|
call BIND => curlies('$_'),[call positional => reg '$capture',[integer 0]] |
|
102
|
|
|
|
|
|
|
]))])); |
|
103
|
|
|
|
|
|
|
} |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub routine { |
|
106
|
0
|
|
|
0
|
0
|
|
my ($mold, $sig) = @_; |
|
107
|
1
|
|
|
1
|
|
8
|
use YAML::XS; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
555
|
|
|
108
|
0
|
|
|
|
|
|
my $realcode = $mold->emit_m0ld; |
|
109
|
0
|
|
|
|
|
|
unshift @{$realcode->stmts}, |
|
|
0
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
call(STORE => call('postcircumfix:{ }' => reg '$scope', [ string '&?ROUTINE' ]), [ call(continuation => reg '$interpreter') ]), |
|
111
|
|
|
|
|
|
|
call(STORE => call('postcircumfix:{ }' => reg '$scope', [ string '&?BLOCK' ]), [ call(continuation => reg '$interpreter') ]), |
|
112
|
|
|
|
|
|
|
call(set_control => call(continuation => reg '$interpreter'), |
|
113
|
|
|
|
|
|
|
[ |
|
114
|
|
|
|
|
|
|
call new => FETCH(lookup('Code')),[], |
|
115
|
|
|
|
|
|
|
[ |
|
116
|
|
|
|
|
|
|
string 'signature' => block_sig(), |
|
117
|
|
|
|
|
|
|
string 'outer' => reg '$scope', |
|
118
|
|
|
|
|
|
|
string 'mold' => |
|
119
|
|
|
|
|
|
|
Mildew::AST::Block->new |
|
120
|
|
|
|
|
|
|
( regs => ['interpreter','scope'], |
|
121
|
|
|
|
|
|
|
stmts => |
|
122
|
|
|
|
|
|
|
[ call( "setr" => |
|
123
|
|
|
|
|
|
|
( call "back" => (call "continuation" => reg '$interpreter' )), |
|
124
|
|
|
|
|
|
|
[ call( handle_return => |
|
125
|
|
|
|
|
|
|
call('new' => FETCH(lookup('ControlExceptionReturn'))), |
|
126
|
|
|
|
|
|
|
[ FETCH(lookup('$_')),FETCH(lookup('&?ROUTINE')) ] )]), |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
call( "goto" => reg '$interpreter', |
|
129
|
|
|
|
|
|
|
[ call("back" => call("continuation" => reg '$interpreter'))])])]]); |
|
130
|
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
|
call new => FETCH(lookup('Code')),[], |
|
132
|
|
|
|
|
|
|
[ string 'mold' => $realcode, |
|
133
|
|
|
|
|
|
|
string 'outer' => reg '$scope', |
|
134
|
|
|
|
|
|
|
string 'signature' => $sig ]; |
|
135
|
|
|
|
|
|
|
} |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub code { |
|
138
|
0
|
|
|
0
|
0
|
|
my ($mold,$sig) = @_; |
|
139
|
0
|
|
|
|
|
|
my $realcode = $mold->emit_m0ld; |
|
140
|
0
|
|
|
|
|
|
unshift @{$realcode->stmts}, |
|
|
0
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
call(STORE=> call('postcircumfix:{ }' => reg '$scope', [ string '&?BLOCK' ]), [ call(continuation => reg '$interpreter') ]); |
|
142
|
|
|
|
|
|
|
|
|
143
|
1
|
|
|
1
|
|
7
|
use YAML::XS; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
144
|
|
|
144
|
0
|
0
|
|
|
|
|
call new => FETCH(lookup('Code')),[], |
|
145
|
|
|
|
|
|
|
[ string 'mold' => $realcode, |
|
146
|
|
|
|
|
|
|
string 'outer' => reg '$scope', |
|
147
|
|
|
|
|
|
|
string 'signature' => ($sig ? $sig : empty_sig )]; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub move_CONTROL { |
|
151
|
0
|
|
|
0
|
0
|
|
my $statementlist = shift; |
|
152
|
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
|
my @statementlist; |
|
154
|
1
|
|
|
1
|
|
17
|
use v5.10; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
1059
|
|
|
155
|
0
|
|
|
|
|
|
for (@{$statementlist}) { |
|
|
0
|
|
|
|
|
|
|
|
156
|
0
|
|
|
|
|
|
my $sc = $_->{statement_control}; |
|
157
|
0
|
0
|
0
|
|
|
|
if (defined $sc && ($sc->isa('VAST::statement_control__S_CATCH') || $sc->isa('VAST::statement_control__S_CONTROL'))) { |
|
|
|
|
0
|
|
|
|
|
|
158
|
0
|
|
|
|
|
|
unshift @statementlist,$_; |
|
159
|
|
|
|
|
|
|
} else { |
|
160
|
0
|
|
|
|
|
|
push @statementlist,$_; |
|
161
|
|
|
|
|
|
|
} |
|
162
|
|
|
|
|
|
|
} |
|
163
|
0
|
|
|
|
|
|
return @statementlist; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub XXX { |
|
167
|
0
|
|
|
0
|
0
|
|
my $where = ''; |
|
168
|
0
|
|
|
|
|
|
my $m = peek_my(1)->{'$m'}; |
|
169
|
0
|
0
|
0
|
|
|
|
if ($m && ref ${$m}) { |
|
|
0
|
|
|
|
|
|
|
|
170
|
0
|
0
|
|
|
|
|
my $back = ${$m}->{POS} > 200 ? 200 : ${$m}->{POS}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
171
|
0
|
|
|
|
|
|
my ($before,) = substr($::ORIG,${$m}->{POS}-$back,$back) =~ /( (?:.*\n)? (?:.*\n)? .* \n? )$/x; |
|
|
0
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
|
my ($after,) = substr($::ORIG,${$m}->{POS}) =~ /^(.* (?:\n.*)? (?:\n.*)? \n?)/x; |
|
|
0
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
|
$where = GREEN.$before.RED.$after.RESET; |
|
174
|
0
|
|
|
|
|
|
shift; |
|
175
|
|
|
|
|
|
|
} |
|
176
|
0
|
|
|
|
|
|
confess "unimplemented: \n".$where.(join ' ',@_); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub trailing_return { |
|
180
|
0
|
|
|
0
|
0
|
|
my ($stmts,) = @_; |
|
181
|
0
|
|
|
|
|
|
my @stmts = (@{$stmts}); |
|
|
0
|
|
|
|
|
|
|
|
182
|
0
|
0
|
|
|
|
|
$stmts[-1] = call(setr => call(back=>call(continuation => reg '$interpreter')),[$stmts[-1]]) if $stmts[-1]; |
|
183
|
0
|
|
|
|
|
|
[@stmts,call(goto => reg '$interpreter',[call back=>call(continuation => reg '$interpreter')])]; |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub varname { |
|
187
|
0
|
|
|
0
|
0
|
|
my $var = shift; |
|
188
|
0
|
|
0
|
|
|
|
($var->{sigil}{TEXT} || '') . $var->{desigilname}{longname}{name}{identifier}{TEXT}; |
|
189
|
|
|
|
|
|
|
} |
|
190
|
|
|
|
|
|
|
sub name_components { |
|
191
|
0
|
|
|
0
|
0
|
|
my $m = shift; |
|
192
|
0
|
0
|
|
|
|
|
if ($m->{sublongname}) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
193
|
0
|
|
|
|
|
|
$m->{sublongname}->components; |
|
194
|
|
|
|
|
|
|
} elsif ($m->{morename}) { |
|
195
|
0
|
|
|
|
|
|
($m->{identifier}{TEXT},map {$_->{TEXT}} @{$m->{morename}[0]{identifier}}); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
} elsif ($m->{desigilname}) { |
|
197
|
0
|
|
|
|
|
|
$m->{desigilname}{longname}->components; |
|
198
|
|
|
|
|
|
|
} else { |
|
199
|
0
|
|
|
|
|
|
XXX; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub named_and_positional { |
|
204
|
0
|
|
|
0
|
0
|
|
[grep { ref $_ ne 'Mildew::AST::Pair' } @_],[map { $_->key, $_->value } grep { ref eq 'Mildew::AST::Pair' } @_] |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub lookup_package { |
|
209
|
0
|
|
|
0
|
0
|
|
my $package = lookup(shift(@_).'::'); |
|
210
|
0
|
|
|
|
|
|
for my $part (@_) { |
|
211
|
0
|
|
|
|
|
|
$package = call('postcircumfix:{ }'=>FETCH($package),[string($part.'::')]); |
|
212
|
|
|
|
|
|
|
} |
|
213
|
0
|
|
|
|
|
|
$package; |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub wrap_in_block { |
|
217
|
0
|
|
|
0
|
0
|
|
my ($ast,$scope) = @_; |
|
218
|
0
|
|
0
|
|
|
|
Mildew::AST::Block->new(regs=>['interpreter','scope'],stmts=>trailing_return([fcall(call(new => FETCH(lookup('Code')),[],[string 'outer'=>($scope // reg '$scope'),string 'signature'=>empty_sig(),string 'mold' => $ast]))])); |
|
219
|
|
|
|
|
|
|
} |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
1; |