File Coverage

blib/lib/Mildew/AST/Helpers.pm
Criterion Covered Total %
statement 34 117 29.0
branch 0 18 0.0
condition 0 22 0.0
subroutine 12 37 32.4
pod 0 23 0.0
total 46 217 21.2


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;