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; |