File Coverage

blib/lib/Mylisp/OptAst.pm
Criterion Covered Total %
statement 14 246 5.6
branch 0 16 0.0
condition 0 3 0.0
subroutine 5 34 14.7
pod 0 29 0.0
total 19 328 5.7


line stmt bran cond sub pod time code
1             package Mylisp::OptAst;
2              
3 1     1   21 use 5.012;
  1         4  
4 1     1   4 no warnings "experimental";
  1         2  
  1         26  
5              
6 1     1   5 use Exporter;
  1         1  
  1         60  
7             our @ISA = qw(Exporter);
8             our @EXPORT =
9             qw(opt_mylisp_ast opt_mylisp_atoms opt_mylisp_atom opt_mylisp_expr is_oper opt_mylisp_infix_op_expr opt_mylisp_oper opt_mylisp_sub opt_mylisp_package opt_mylisp_use opt_mylisp_func opt_mylisp_func_args opt_mylisp_arg opt_mylisp_for opt_mylisp_iter opt_mylisp_my opt_mylisp_ocall_expr opt_mylisp_ocall opt_mylisp_name_value opt_mylisp_array opt_mylisp_hash opt_mylisp_pair opt_mylisp_aindex opt_mylisp_arange opt_mylisp_string opt_mylisp_str opt_mylisp_lstr opt_mylisp_kstr opt_mylisp_sym);
10 1     1   5 use Spp::Builtin;
  1         1  
  1         172  
11 1     1   6 use Spp::Tools;
  1         3  
  1         1802  
12              
13             sub opt_mylisp_ast {
14 0     0 0   my $ast = shift;
15 0 0         if (is_atom($ast)) { return cons(opt_mylisp_atom($ast)) }
  0            
16 0           return opt_mylisp_atoms($ast);
17             }
18              
19             sub opt_mylisp_atoms {
20 0     0 0   my $atoms = shift;
21             return estr(
22 0           [map { opt_mylisp_atom($_) } @{ atoms($atoms) }]);
  0            
  0            
23             }
24              
25             sub opt_mylisp_atom {
26 0     0 0   my $atom = shift;
27 0           my ($name, $rest) = match($atom);
28 0           given ($name) {
29 0           when ('Expr') { return opt_mylisp_expr($rest) }
  0            
30 0           when ('Ocall') { return opt_mylisp_ocall($rest) }
  0            
31 0           when ('Array') { return opt_mylisp_array($rest) }
  0            
32 0           when ('Hash') { return opt_mylisp_hash($rest) }
  0            
33 0           when ('Pair') { return opt_mylisp_pair($rest) }
  0            
34 0           when ('Aindex') { return opt_mylisp_aindex($rest) }
  0            
35 0           when ('Arange') { return opt_mylisp_arange($rest) }
  0            
36 0           when ('String') { return opt_mylisp_string($rest) }
  0            
37 0           when ('Str') { return opt_mylisp_str($rest) }
  0            
38 0           when ('Lstr') { return opt_mylisp_lstr($rest) }
  0            
39 0           when ('Kstr') { return opt_mylisp_kstr($rest) }
  0            
40 0           when ('Sub') { return opt_mylisp_sym($rest) }
  0            
41 0           when ('Chars') { return eunshift('Str', $rest) }
  0            
42 0           when ('Var') { return opt_mylisp_sym($rest) }
  0            
43 0           when ('Scalar') { return opt_mylisp_sym($rest) }
  0            
44 0           when ('Oper') { return opt_mylisp_sym($rest) }
  0            
45 0           when ('Char') { return $atom }
  0            
46 0           when ('Ns') { return $atom }
  0            
47 0           when ('Arg') { return $atom }
  0            
48 0           when ('Int') { return $atom }
  0            
49 0           default { error("unknown atom |$name| to opt!") }
  0            
50             }
51             }
52              
53             sub opt_mylisp_expr {
54 0     0 0   my $value = shift;
55 0           my ($expr, $pos) = flat($value);
56 0 0 0       if (elen($expr) == 3 && is_oper(value($expr))) {
57 0           return opt_mylisp_infix_op_expr($expr, $pos);
58             }
59 0           my ($first, $args) = match($expr);
60 0           my ($type, $name) = flat($first);
61 0           given ($type) {
62 0           when ('Sub') {
63 0           return opt_mylisp_sub($name, $args, $pos)
64             }
65 0           when ('Oper') {
66 0           return opt_mylisp_oper($name, $args, $pos)
67             }
68 0           when ('Ocall') {
69 0           return opt_mylisp_ocall_expr($name, $args, $pos)
70             }
71 0           default {
72 0           my $atoms = opt_mylisp_atoms($expr);
73 0           return cons('Array', $atoms)
74             }
75             }
76             }
77              
78             sub is_oper {
79 0     0 0   my $atom = shift;
80 0 0         if (is_atom($atom)) {
81 0           my ($name, $value) = flat($atom);
82 0 0         if ($name eq 'Oper') { return 1 }
  0            
83 0 0         if ($value ~~ ['x', 'eq', 'le', 'ne', 'in']) {
84 0           return 1;
85             }
86             }
87 0           return 0;
88             }
89              
90             sub opt_mylisp_infix_op_expr {
91 0     0 0   my ($expr, $pos) = @_;
92 0           my $atoms = atoms($expr);
93 0           my $name = value($atoms->[1]);
94 0           my $args = cons($atoms->[0], $atoms->[2]);
95 0           $args = opt_mylisp_atoms($args);
96 0           given ($name) {
97 0           when ('>>') { return cons('eunshift', $args, $pos) }
  0            
98 0           when ('<<') { return cons('epush', $args, $pos) }
  0            
99 0           when ('><') { return cons('eappend', $args, $pos) }
  0            
100 0           default { return cons($name, $args, $pos) }
  0            
101             }
102             }
103              
104             sub opt_mylisp_oper {
105 0     0 0   my ($name, $args, $pos) = @_;
106 0           my $atoms = opt_mylisp_atoms($args);
107 0           return cons($name, $atoms, $pos);
108             }
109              
110             sub opt_mylisp_sub {
111 0     0 0   my ($name, $args, $pos) = @_;
112 0           given ($name) {
113 0           when ('package') {
114 0           return opt_mylisp_package($args, $pos)
115             }
116 0           when ('use') { return opt_mylisp_use($args, $pos) }
  0            
117 0           when ('func') { return opt_mylisp_func($args, $pos) }
  0            
118 0           when ('for') { return opt_mylisp_for($args, $pos) }
  0            
119 0           when ('my') { return opt_mylisp_my($args, $pos) }
  0            
120 0           default {
121 0           return cons($name, opt_mylisp_atoms($args), $pos)
122             }
123             }
124             }
125              
126             sub opt_mylisp_package {
127 0     0 0   my ($args, $pos) = @_;
128 0           my $ns = value(name($args));
129 0           return cons('package', $ns, $pos);
130             }
131              
132             sub opt_mylisp_use {
133 0     0 0   my ($args, $pos) = @_;
134 0           my $atoms = opt_mylisp_atoms($args);
135 0           my $ns = value(name($atoms));
136 0           return cons('use', $ns, $pos);
137             }
138              
139             sub opt_mylisp_func {
140 0     0 0   my ($args, $pos) = @_;
141 0           my $atoms = opt_mylisp_atoms($args);
142 0           my ($name_args, $exprs) = match($atoms);
143 0           my $return = name($exprs);
144 0 0         if (not(is_atom_name($return, '->'))) {
145 0           my $line = value(offline($return));
146 0           say "line: $line func less return expr!";
147             }
148 0           my $opt_args = opt_mylisp_func_args($name_args);
149 0           my $func_exprs = eunshift($opt_args, $exprs);
150 0           return cons('func', $func_exprs, $pos);
151             }
152              
153             sub opt_mylisp_func_args {
154 0     0 0   my $expr = shift;
155 0           my ($call, $args) = flat($expr);
156             my $opt_args =
157 0           [map { opt_mylisp_arg($_) } @{ atoms($args) }];
  0            
  0            
158 0           my $pos = offline($expr);
159 0           return cons($call, $opt_args, $pos);
160             }
161              
162             sub opt_mylisp_arg {
163 0     0 0   my $arg = shift;
164 0 0         if (is_atom_name($arg, 'Arg')) {
165 0           my $arg_name = value($arg);
166 0           my $names = [split ':', $arg_name];
167 0           my $name = $names->[0];
168 0           my $type = $names->[1];
169 0           my $pos = offline($arg);
170 0           return cons($name, $type, $pos);
171             }
172 0           my $line = value(offline($arg));
173 0           say "line: $line func arg less type info!";
174             }
175              
176             sub opt_mylisp_for {
177 0     0 0   my ($args, $pos) = @_;
178 0           my $atoms = opt_mylisp_atoms($args);
179 0           my ($iter_expr, $rest) = match($atoms);
180 0           my $iter_atom = opt_mylisp_iter($iter_expr);
181 0           my $exprs = eunshift($iter_atom, $rest);
182 0           return cons('for', $exprs, $pos);
183             }
184              
185             sub opt_mylisp_iter {
186 0     0 0   my $expr = shift;
187 0           my ($in, $args) = flat($expr);
188 0           my ($loop_sym, $iter_atom) = flat($args);
189 0           my $loop = value($loop_sym);
190 0           my $pos = offline($expr);
191 0           return cons($loop, $iter_atom, $pos);
192             }
193              
194             sub opt_mylisp_my {
195 0     0 0   my ($args, $pos) = @_;
196 0           my $atoms = opt_mylisp_atoms($args);
197 0           my $sym = name($atoms);
198 0 0         if (is_sym($sym)) { return cons('my', $atoms, $pos) }
  0            
199 0           return cons('our', $atoms, $pos);
200             }
201              
202             sub opt_mylisp_ocall_expr {
203 0     0 0   my ($ocall, $args, $pos) = @_;
204 0           my ($sym, $call) = flat($ocall);
205 0           my $name = value($call);
206 0           my $opt_args = opt_mylisp_atoms(eunshift($sym, $args));
207 0           return cons($name, $opt_args, $pos);
208             }
209              
210             sub opt_mylisp_ocall {
211 0     0 0   my $value = shift;
212 0           my ($args, $pos) = flat($value);
213 0           my $opt_args = opt_mylisp_atoms($args);
214 0           my ($sym, $call) = flat($opt_args);
215 0           my $name = value($call);
216 0           return cons($name, cons($sym), $pos);
217             }
218              
219             sub opt_mylisp_name_value {
220 0     0 0   my ($name, $value) = @_;
221 0           my ($args, $pos) = flat($value);
222 0           my $atoms = opt_mylisp_atoms($args);
223 0           return cons($name, $atoms, $pos);
224             }
225              
226             sub opt_mylisp_array {
227 0     0 0   my $value = shift;
228 0           return opt_mylisp_name_value('Array', $value);
229             }
230              
231             sub opt_mylisp_hash {
232 0     0 0   my $value = shift;
233 0           return opt_mylisp_name_value('Hash', $value);
234             }
235              
236             sub opt_mylisp_pair {
237 0     0 0   my $value = shift;
238 0           return opt_mylisp_name_value('Pair', $value);
239             }
240              
241             sub opt_mylisp_aindex {
242 0     0 0   my $value = shift;
243 0           return opt_mylisp_name_value('Aindex', $value);
244             }
245              
246             sub opt_mylisp_arange {
247 0     0 0   my $value = shift;
248 0           return opt_mylisp_name_value('subarray', $value);
249             }
250              
251             sub opt_mylisp_string {
252 0     0 0   my $value = shift;
253 0           return opt_mylisp_name_value('String', $value);
254             }
255              
256             sub opt_mylisp_str {
257 0     0 0   my $value = shift;
258 0           my ($str, $pos) = flat($value);
259 0           $str = substr($str, 1, -1);
260 0           return cons('Str', $str, $pos);
261             }
262              
263             sub opt_mylisp_lstr {
264 0     0 0   my $value = shift;
265 0           my ($lstr, $pos) = flat($value);
266 0           my $str = substr($lstr, 3, -3);
267 0           return cons('Lstr', $str, $pos);
268             }
269              
270             sub opt_mylisp_kstr {
271 0     0 0   my $value = shift;
272 0           my ($kstr, $pos) = flat($value);
273 0           my $str = substr($kstr, 1);
274 0           return cons('Str', $str, $pos);
275             }
276              
277             sub opt_mylisp_sym {
278 0     0 0   my $value = shift;
279 0           my ($name, $pos) = flat($value);
280 0           given ($name) {
281 0           when ('false') { return cons('Bool', $name, $pos) }
  0            
282 0           when ('true') { return cons('Bool', $name, $pos) }
  0            
283 0           when ('Null') { return cons('Type', $name, $pos) }
  0            
284 0           when ('Str') { return cons('Type', $name, $pos) }
  0            
285 0           when ('Int') { return cons('Type', $name, $pos) }
  0            
286 0           when ('Hash') { return cons('Type', $name, $pos) }
  0            
287 0           when ('Bool') { return cons('Type', $name, $pos) }
  0            
288 0           when ('Array') { return cons('Type', $name, $pos) }
  0            
289 0           when ('Stack') { return cons('Type', $name, $pos) }
  0            
290 0           when ('Iarray') { return cons('Type', $name, $pos) }
  0            
291 0           when ('Stable') { return cons('Type', $name, $pos) }
  0            
292 0           when ('Cursor') { return cons('Type', $name, $pos) }
  0            
293 0           when ('Lint') { return cons('Type', $name, $pos) }
  0            
294 0           when ('Parser') { return cons('Type', $name, $pos) }
  0            
295 0           default { return cons('Sym', $name, $pos) }
  0            
296             }
297             }
298             1;