File Coverage

blib/lib/Mylisp/OptAst.pm
Criterion Covered Total %
statement 14 247 5.6
branch 0 20 0.0
condition 0 3 0.0
subroutine 5 35 14.2
pod 0 30 0.0
total 19 335 5.6


line stmt bran cond sub pod time code
1             package Mylisp::OptAst;
2              
3 1     1   13 use 5.012;
  1         2  
4 1     1   4 no warnings 'experimental';
  1         2  
  1         23  
5              
6 1     1   4 use Exporter;
  1         1  
  1         63  
7             our @ISA = qw(Exporter);
8             our @EXPORT =
9             qw(opt_my_ast opt_my_atoms opt_my_atom opt_my_expr is_oper opt_my_infix_op_expr opt_my_oper opt_my_sub opt_my_package opt_my_use opt_my_func opt_my_func_args opt_my_arg opt_my_for opt_my_iter opt_my_my opt_my_ocall_expr opt_my_ocall opt_my_name_value opt_my_array opt_my_hash opt_my_pair opt_my_aindex opt_my_arange opt_my_string opt_my_str opt_my_lstr opt_my_kstr opt_my_chars opt_my_sym);
10              
11 1     1   5 use Spp::Builtin;
  1         2  
  1         208  
12 1     1   7 use Spp::Tools;
  1         2  
  1         1727  
13              
14             sub opt_my_ast {
15 0     0 0   my $ast = shift;
16 0 0         if (is_atom($ast)) { return cons(opt_my_atom($ast)) }
  0            
17 0           return opt_my_atoms($ast);
18             }
19              
20             sub opt_my_atoms {
21 0     0 0   my $atoms = shift;
22 0           return estr([map { opt_my_atom($_) } @{ atoms($atoms) }]);
  0            
  0            
23             }
24              
25             sub opt_my_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_my_expr($rest) }
  0            
30 0           when ('Ocall') { return opt_my_ocall($rest) }
  0            
31 0           when ('Array') { return opt_my_array($rest) }
  0            
32 0           when ('Hash') { return opt_my_hash($rest) }
  0            
33 0           when ('Pair') { return opt_my_pair($rest) }
  0            
34 0           when ('Aindex') { return opt_my_aindex($rest) }
  0            
35 0           when ('Arange') { return opt_my_arange($rest) }
  0            
36 0           when ('String') { return opt_my_string($rest) }
  0            
37 0           when ('Str') { return opt_my_str($rest) }
  0            
38 0           when ('Lstr') { return opt_my_lstr($rest) }
  0            
39 0           when ('Kstr') { return opt_my_kstr($rest) }
  0            
40 0           when ('Chars') { return opt_my_chars($rest) }
  0            
41 0           when ('Sub') { return opt_my_sym($rest) }
  0            
42 0           when ('Var') { return opt_my_sym($rest) }
  0            
43 0           when ('Scalar') { return opt_my_sym($rest) }
  0            
44 0           when ('Oper') { return opt_my_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_my_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_my_infix_op_expr($expr, $pos);
58             }
59 0           my ($action, $args) = match($expr);
60 0           my ($type, $name) = flat($action);
61 0           given ($type) {
62 0           when ('Sub') { return opt_my_sub($name, $args, $pos) }
  0            
63 0           when ('Oper') { return opt_my_oper($name, $args, $pos) }
  0            
64 0           when ('Ocall') {
65 0           return opt_my_ocall_expr($name, $args, $pos)
66             }
67 0           default {
68 0           my $atoms = opt_my_atoms($expr);
69 0           return cons('Array', $atoms)
70             }
71             }
72             }
73              
74             sub is_oper {
75 0     0 0   my $atom = shift;
76 0 0         if (is_atom($atom)) {
77 0           my ($name, $value) = flat($atom);
78 0 0         if ($name eq 'Oper') { return 1 }
  0            
79 0 0         if ($value ~~ ['x', 'eq', 'le', 'ne', 'in']) {
80 0           return 1;
81             }
82             }
83 0           return 0;
84             }
85              
86             sub opt_my_infix_op_expr {
87 0     0 0   my ($expr, $pos) = @_;
88 0           my $atoms = atoms($expr);
89 0           my $name = value($atoms->[1]);
90 0           my $args = cons($atoms->[0], $atoms->[2]);
91 0           $args = opt_my_atoms($args);
92 0           given ($name) {
93 0           when ('>>') { return cons('eunshift', $args, $pos) }
  0            
94 0           when ('<<') { return cons('epush', $args, $pos) }
  0            
95 0           when ('><') { return cons('eappend', $args, $pos) }
  0            
96 0           default { return cons($name, $args, $pos) }
  0            
97             }
98             }
99              
100             sub opt_my_oper {
101 0     0 0   my ($name, $args, $pos) = @_;
102 0           my $atoms = opt_my_atoms($args);
103 0           return cons($name, $atoms, $pos);
104             }
105              
106             sub opt_my_sub {
107 0     0 0   my ($name, $args, $pos) = @_;
108 0           given ($name) {
109 0           when ('package') { return opt_my_package($args, $pos) }
  0            
110 0           when ('use') { return opt_my_use($args, $pos) }
  0            
111 0           when ('func') { return opt_my_func($args, $pos) }
  0            
112 0           when ('for') { return opt_my_for($args, $pos) }
  0            
113 0           when ('my') { return opt_my_my($args, $pos) }
  0            
114 0           default {
115 0           return cons($name, opt_my_atoms($args), $pos)
116             }
117             }
118             }
119              
120             sub opt_my_package {
121 0     0 0   my ($args, $pos) = @_;
122 0           my $ns = value(name($args));
123 0           return cons('package', $ns, $pos);
124             }
125              
126             sub opt_my_use {
127 0     0 0   my ($args, $pos) = @_;
128 0           my $atoms = opt_my_atoms($args);
129 0           my $ns = value(name($atoms));
130 0           return cons('use', $ns, $pos);
131             }
132              
133             sub opt_my_func {
134 0     0 0   my ($args, $pos) = @_;
135 0           my $atoms = opt_my_atoms($args);
136 0           my ($name_args, $exprs) = match($atoms);
137 0           my $return = name($exprs);
138 0 0         if (not(is_return($return))) {
139 0           my $expr = cons('->', cons(cons('Type', 'Str')));
140 0           $exprs = eunshift($expr, $exprs);
141             }
142 0           my $opt_args = opt_my_func_args($name_args);
143 0           my $func_exprs = eunshift($opt_args, $exprs);
144 0           return cons('func', $func_exprs, $pos);
145             }
146              
147             sub opt_my_func_args {
148 0     0 0   my $expr = shift;
149 0           my ($call, $args) = flat($expr);
150 0           my $opt_args = [map { opt_my_arg($_) } @{ atoms($args) }];
  0            
  0            
151 0           my $pos = offline($expr);
152 0           return cons($call, estr($opt_args), $pos);
153             }
154              
155             sub opt_my_arg {
156 0     0 0   my $arg = shift;
157 0           my ($name, $value) = flat($arg);
158 0           my $pos = offline($arg);
159 0           my $line = value(offline($arg));
160 0 0         if ($name eq 'Arg') {
161 0           my $names = [split ':', $value];
162 0           my $arg_name = $names->[0];
163 0           my $type = $names->[1];
164 0 0         if (is_type($type)) {
165 0           return cons($arg_name, $type, $pos);
166             }
167 0           else { say "line: $line unknown type |$type|" }
168             }
169 0 0         if ($name eq 'Sym') { return cons($value, 'Str', $pos) }
  0            
170 0           say "line: $line |$name| as func arg!";
171             }
172              
173             sub opt_my_for {
174 0     0 0   my ($args, $pos) = @_;
175 0           my $atoms = opt_my_atoms($args);
176 0           my ($iter_expr, $rest) = match($atoms);
177 0           my $iter_atom = opt_my_iter($iter_expr);
178 0           my $exprs = eunshift($iter_atom, $rest);
179 0           return cons('for', $exprs, $pos);
180             }
181              
182             sub opt_my_iter {
183 0     0 0   my $expr = shift;
184 0           my ($in, $args) = flat($expr);
185 0           my ($loop_sym, $iter_atom) = flat($args);
186 0           my $loop = value($loop_sym);
187 0           my $pos = offline($expr);
188 0           return cons($loop, $iter_atom, $pos);
189             }
190              
191             sub opt_my_my {
192 0     0 0   my ($args, $pos) = @_;
193 0           my $atoms = opt_my_atoms($args);
194 0           my $sym = name($atoms);
195 0 0         if (is_sym($sym)) { return cons('my', $atoms, $pos) }
  0            
196 0           return cons('our', $atoms, $pos);
197             }
198              
199             sub opt_my_ocall_expr {
200 0     0 0   my ($ocall, $args, $pos) = @_;
201 0           my ($sym, $call) = flat($ocall);
202 0           my $name = value($call);
203 0           my $opt_args = opt_my_atoms(eunshift($sym, $args));
204 0           return cons($name, $opt_args, $pos);
205             }
206              
207             sub opt_my_ocall {
208 0     0 0   my $value = shift;
209 0           my ($args, $pos) = flat($value);
210 0           my $opt_args = opt_my_atoms($args);
211 0           my ($sym, $call) = flat($opt_args);
212 0           my $name = value($call);
213 0           return cons($name, cons($sym), $pos);
214             }
215              
216             sub opt_my_name_value {
217 0     0 0   my ($name, $value) = @_;
218 0           my ($args, $pos) = flat($value);
219 0           my $atoms = opt_my_atoms($args);
220 0           return cons($name, $atoms, $pos);
221             }
222              
223             sub opt_my_array {
224 0     0 0   my $value = shift;
225 0           return opt_my_name_value('Array', $value);
226             }
227              
228             sub opt_my_hash {
229 0     0 0   my $value = shift;
230 0           return opt_my_name_value('Hash', $value);
231             }
232              
233             sub opt_my_pair {
234 0     0 0   my $value = shift;
235 0           return opt_my_name_value('Pair', $value);
236             }
237              
238             sub opt_my_aindex {
239 0     0 0   my $value = shift;
240 0           return opt_my_name_value('Aindex', $value);
241             }
242              
243             sub opt_my_arange {
244 0     0 0   my $value = shift;
245 0           return opt_my_name_value('subarray', $value);
246             }
247              
248             sub opt_my_string {
249 0     0 0   my $value = shift;
250 0           return opt_my_name_value('String', $value);
251             }
252              
253             sub opt_my_str {
254 0     0 0   my $value = shift;
255 0           my ($str, $pos) = flat($value);
256 0           $str = substr($str, 1, -1);
257 0           return cons('Str', $str, $pos);
258             }
259              
260             sub opt_my_lstr {
261 0     0 0   my $value = shift;
262 0           my ($lstr, $pos) = flat($value);
263 0           my $str = substr($lstr, 3, -3);
264 0           return cons('Lstr', $str, $pos);
265             }
266              
267             sub opt_my_kstr {
268 0     0 0   my $value = shift;
269 0           my ($kstr, $pos) = flat($value);
270 0           my $str = substr($kstr, 1);
271 0           return cons('Str', $str, $pos);
272             }
273              
274             sub opt_my_chars {
275 0     0 0   my $rest = shift;
276 0           my ($str, $pos) = flat($rest);
277 0           return cons('Str', $str, $pos);
278             }
279              
280             sub opt_my_sym {
281 0     0 0   my $value = shift;
282 0           my ($name, $pos) = flat($value);
283 0           given ($name) {
284 0           when ('false') { return cons('Bool', $name, $pos) }
  0            
285 0           when ('true') { return cons('Bool', $name, $pos) }
  0            
286 0           when ('Str') { return cons('Type', $name, $pos) }
  0            
287 0           when ('Int') { return cons('Type', $name, $pos) }
  0            
288 0           when ('Hash') { return cons('Type', $name, $pos) }
  0            
289 0           when ('Bool') { return cons('Type', $name, $pos) }
  0            
290 0           when ('Array') { return cons('Type', $name, $pos) }
  0            
291 0           when ('Ints') { return cons('Type', $name, $pos) }
  0            
292 0           when ('Table') { return cons('Type', $name, $pos) }
  0            
293 0           when ('Cursor') { return cons('Type', $name, $pos) }
  0            
294 0           when ('Lint') { return cons('Type', $name, $pos) }
  0            
295 0           default { return cons('Sym', $name, $pos) }
  0            
296             }
297             }
298             1;