File Coverage

blib/lib/Mylisp/ToGo.pm
Criterion Covered Total %
statement 14 380 3.6
branch 0 26 0.0
condition n/a
subroutine 5 44 11.3
pod 0 39 0.0
total 19 489 3.8


line stmt bran cond sub pod time code
1             package Mylisp::ToGo;
2              
3 1     1   14 use 5.012;
  1         2  
4 1     1   5 no warnings "experimental";
  1         3  
  1         26  
5              
6 1     1   5 use Exporter;
  1         1  
  1         68  
7             our @ISA = qw(Exporter);
8             our @EXPORT =
9             qw(ast_to_go atoms_to_go join_go_exprs atoms_to_gos atom_to_go not_to_go oper_to_go call_to_go my_to_go const_to_go our_to_go slist_to_go array_to_go package_to_go use_to_go ns_to_go func_to_go name_args_to_go arg_to_go return_expr_to_go for_to_go iter_to_go while_to_go if_to_go elif_to_go else_to_go cond_expr_to_go given_to_go when_to_go then_to_go aindex_to_go lstr_to_go str_to_go string_to_go return_to_go name_to_go sym_to_go type_to_go type_declare_to_go);
10 1     1   11 use Spp::Builtin;
  1         3  
  1         163  
11 1     1   6 use Spp::Tools;
  1         1  
  1         2299  
12 0     0 0   sub ast_to_go { my $ast = shift; return atoms_to_go($ast) }
  0            
13              
14             sub atoms_to_go {
15 0     0 0   my $atoms = shift;
16 0           my $strs = [map { atom_to_go($_) } @{ atoms($atoms) }];
  0            
  0            
17 0           return join_go_exprs($strs);
18             }
19              
20             sub join_go_exprs {
21 0     0 0   my $exprs = shift;
22 0           my $strs = [];
23 0           my $count = 0;
24 0           for my $expr (@{$exprs}) {
  0            
25 0           $count++;
26 0 0         if ($count == 1) { push @{$strs}, $expr; }
  0            
  0            
27             else {
28 0 0         if (not(start_with($expr, 'else'))) {
29 0           push @{$strs}, ';';
  0            
30             }
31 0           push @{$strs}, $expr;
  0            
32             }
33             }
34 0           return join '', @{$strs};
  0            
35             }
36              
37             sub atoms_to_gos {
38 0     0 0   my $atoms = shift;
39 0           return estr([map { atom_to_go($_) } @{ atoms($atoms) }]);
  0            
  0            
40             }
41              
42             sub atom_to_go {
43 0     0 0   my $atom = shift;
44 0           my ($name, $args) = flat($atom);
45 0           given ($name) {
46 0           when ('package') { return package_to_go($args) }
  0            
47 0           when ('use') { return use_to_go($args) }
  0            
48 0           when ('func') { return func_to_go($args) }
  0            
49 0           when ('given') { return given_to_go($args) }
  0            
50 0           when ('for') { return for_to_go($args) }
  0            
51 0           when ('while') { return while_to_go($args) }
  0            
52 0           when ('if') { return if_to_go($args) }
  0            
53 0           when ('elif') { return elif_to_go($args) }
  0            
54 0           when ('else') { return else_to_go($args) }
  0            
55 0           when ('given') { return given_to_go($args) }
  0            
56 0           when ('when') { return when_to_go($args) }
  0            
57 0           when ('then') { return then_to_go($args) }
  0            
58 0           when ('return') { return return_to_go($args) }
  0            
59 0           when ('my') { return my_to_go($args) }
  0            
60 0           when ('our') { return our_to_go($args) }
  0            
61 0           when ('const') { return const_to_go($args) }
  0            
62 0           when ('not') { return not_to_go($args) }
  0            
63 0           when ('Aindex') { return aindex_to_go($args) }
  0            
64 0           when ('Sym') { return sym_to_go($args) }
  0            
65 0           when ('Lstr') { return lstr_to_go($args) }
  0            
66 0           when ('Str') { return str_to_go($args) }
  0            
67 0           when ('String') { return string_to_go($args) }
  0            
68 0           when ('Array') { return array_to_go($args) }
  0            
69 0           when ('Type') { return type_to_go($args) }
  0            
70 0           when ('Int') { return $args }
  0            
71 0           when ('Bool') { return $args }
  0            
72 0           when ('end') { return ' ' }
  0            
73 0           default {
74 0           my $strs = atoms_to_gos($args);
75 0           return oper_to_go($name, $strs)
76             }
77             }
78             }
79              
80             sub not_to_go {
81 0     0 0   my $args = shift;
82 0           my $str = atoms_to_go($args);
83 0           return "!$str";
84             }
85              
86             sub oper_to_go {
87 0     0 0   my ($name, $strs) = @_;
88 0           given ($name) {
89 0           when ('gt') { return ejoin($strs, '>') }
  0            
90 0           when ('ge') { return ejoin($strs, '>=') }
  0            
91 0           when ('lt') { return ejoin($strs, '<') }
  0            
92 0           when ('eq') { return ejoin($strs, '==') }
  0            
93 0           when ('le') { return ejoin($strs, '<=') }
  0            
94 0           when ('ne') { return ejoin($strs, '!=') }
  0            
95 0           when ('add') { return ejoin($strs, '+') }
  0            
96 0           when ('=') { return ejoin($strs, '=') }
  0            
97 0           when ('+') { return ejoin($strs, '+') }
  0            
98 0           when ('-') { return ejoin($strs, '-') }
  0            
99 0           when ('==') { return ejoin($strs, '==') }
  0            
100 0           when ('>=') { return ejoin($strs, '>=') }
  0            
101 0           when ('!=') { return ejoin($strs, '!=') }
  0            
102 0           when ('>') { return ejoin($strs, '>') }
  0            
103 0           when ('<') { return ejoin($strs, '<') }
  0            
104 0           when ('<=') { return ejoin($strs, '<=') }
  0            
105 0           when ('&&') { return ejoin($strs, '&&') }
  0            
106 0           when ('||') { return ejoin($strs, '||') }
  0            
107 0           default { return call_to_go($name, $strs) }
  0            
108             }
109             }
110              
111             sub call_to_go {
112 0     0 0   my ($name, $strs) = @_;
113 0           my $args_str = ejoin($strs, ',');
114 0           given ($name) {
115 0           when ('~~') { return call_to_go('is-in', $strs) }
  0            
116 0           when ('>>') { return call_to_go('eunshift', $strs) }
  0            
117 0           when ('<<') { return call_to_go('epush', $strs) }
  0            
118 0           when ('><') { return call_to_go('eappend', $strs) }
  0            
119 0           when ('length') { return call_to_go('len', $strs) }
  0            
120 0           when ('exitif') { return "if $args_str { Exit() }" }
  0            
121 0           when ('nextif') { return "if $args_str { continue }" }
  0            
122 0           default {
123 0           $name = sym_to_go($name);
124 0           return "$name($args_str)"
125             }
126             }
127             }
128              
129             sub my_to_go {
130 0     0 0   my $args = shift;
131 0           my $strs = atoms_to_gos($args);
132 0           my ($sym, $value) = flat($strs);
133 0           return "$sym := $value";
134             }
135              
136             sub const_to_go {
137 0     0 0   my $args = shift;
138 0           my $strs = atoms_to_gos($args);
139 0           my ($sym, $value) = flat($strs);
140 0           return "const $sym = $value";
141             }
142              
143             sub our_to_go {
144 0     0 0   my $args = shift;
145 0           my ($slist, $value) = flat($args);
146 0           my $slist_str = slist_to_go(value($slist));
147 0           my $value_str = atom_to_go($value);
148 0           return "$slist_str := $value_str";
149             }
150              
151             sub slist_to_go {
152 0     0 0   my $syms = shift;
153 0           my $names = atoms_to_gos($syms);
154 0           return ejoin($names, ',');
155             }
156              
157             sub array_to_go {
158 0     0 0   my $args = shift;
159 0           my $strs = atoms_to_gos($args);
160 0           my $str = ejoin($strs, ',');
161 0           return "Array{$str}";
162             }
163              
164             sub package_to_go {
165 0     0 0   my $ns = shift;
166 0           my $name = ns_to_go($ns);
167 0           return "package $name";
168             }
169              
170             sub use_to_go {
171 0     0 0   my $ns = shift;
172 0           my $names = [split '::', $ns];
173 0           my $name = join '/', @{$names};
  0            
174 0           return "import . \"$name\"";
175             }
176              
177             sub ns_to_go {
178 0     0 0   my $ns = shift;
179 0           return tail([split '::', $ns]);
180             }
181              
182             sub func_to_go {
183 0     0 0   my $args = shift;
184 0           my ($name_args, $rest) = match($args);
185 0           my ($return, $exprs) = match($rest);
186 0           my $args_str = name_args_to_go($name_args);
187 0           my $return_str = return_expr_to_go($return);
188 0           my $exprs_str = atoms_to_go($exprs);
189 0 0         if ($return_str eq 'Null') {
190 0           return "func $args_str { $exprs_str }";
191             }
192 0           return "func $args_str $return_str { $exprs_str }";
193             }
194              
195             sub name_args_to_go {
196 0     0 0   my $name_args = shift;
197 0           my ($name, $args) = flat($name_args);
198             my $args_str = join ',',
199 0           @{ [map { arg_to_go($_) } @{ atoms($args) }] };
  0            
  0            
  0            
200 0           $name = sym_to_go($name);
201 0           return "$name($args_str)";
202             }
203              
204             sub arg_to_go {
205 0     0 0   my $arg = shift;
206 0           my ($name, $type) = flat($arg);
207 0           my $name_str = name_to_go($name);
208 0           return "$name_str $type";
209             }
210              
211             sub return_expr_to_go {
212 0     0 0   my $expr = shift;
213 0           my $args = value($expr);
214 0           my $types = [map { value($_) } @{ atoms($args) }];
  0            
  0            
215 0           my $go_types = [map { type_declare_to_go($_) } @{$types}];
  0            
  0            
216 0           my $str = join ',', @{$go_types};
  0            
217 0 0         if (len($types) == 1) { return $str }
  0            
218 0           return "($str)";
219             }
220              
221             sub for_to_go {
222 0     0 0   my $args = shift;
223 0           my ($iter_atom, $exprs) = match($args);
224 0           my $iter_str = iter_to_go($iter_atom);
225 0           my $exprs_str = atoms_to_go($exprs);
226 0           return "for $iter_str $exprs_str }";
227             }
228              
229             sub iter_to_go {
230 0     0 0   my $atom = shift;
231 0           my ($loop_name, $iter_atom) = flat($atom);
232 0           my $loop = sym_to_go($loop_name);
233 0           my $iter = atom_to_go($iter_atom);
234 0 0         if (is_sym($iter_atom)) {
235 0           my $char = first_char(value($iter_atom));
236 0           given ($char) {
237 0           when ('$') {
238 0           return "_, c := range $iter { $loop := string(c);"
239             }
240 0           when ('%') { return "$loop, _ := range $iter { " }
  0            
241 0           default { return "_, $loop := range $iter { " }
  0            
242             }
243             }
244 0           return "_, $loop := range $iter { ";
245             }
246              
247             sub while_to_go {
248 0     0 0   my $args = shift;
249 0           my ($guide_atom, $exprs) = match($args);
250 0           my $guide_str = atom_to_go($guide_atom);
251 0           my $exprs_str = atoms_to_go($exprs);
252 0           return "for $guide_str { $exprs_str }";
253             }
254              
255             sub if_to_go {
256 0     0 0   my $args = shift;
257 0           my $args_str = cond_expr_to_go($args);
258 0           return "if $args_str";
259             }
260              
261             sub elif_to_go {
262 0     0 0   my $args = shift;
263 0           my $args_str = cond_expr_to_go($args);
264 0           return "else if $args_str";
265             }
266              
267             sub else_to_go {
268 0     0 0   my $args = shift;
269 0           my $args_str = atoms_to_go($args);
270 0           return "else { $args_str }";
271             }
272              
273             sub cond_expr_to_go {
274 0     0 0   my $args = shift;
275 0           my ($cond_atom, $exprs) = match($args);
276 0           my $cond_str = atom_to_go($cond_atom);
277 0           my $exprs_str = atoms_to_go($exprs);
278 0           return "$cond_str { $exprs_str }";
279             }
280              
281             sub given_to_go {
282 0     0 0   my $args = shift;
283 0           my $str = cond_expr_to_go($args);
284 0           return "switch $str";
285             }
286              
287             sub when_to_go {
288 0     0 0   my $args = shift;
289 0           my ($cond_atom, $exprs) = match($args);
290 0           my $cond_str = atom_to_go($cond_atom);
291 0           my $exprs_str = atoms_to_go($exprs);
292 0           return "case $cond_str: $exprs_str";
293             }
294              
295             sub then_to_go {
296 0     0 0   my $args = shift;
297 0           my $args_str = atoms_to_go($args);
298 0           return "default: $args_str";
299             }
300              
301             sub aindex_to_go {
302 0     0 0   my $args = shift;
303 0           my $strs = atoms_to_gos($args);
304 0           my ($sym, $indexs) = match($strs);
305 0           my $index_str = ejoin($indexs, '][');
306 0           return "$sym\[$index_str]";
307             }
308 0     0 0   sub lstr_to_go { my $args = shift; return "`$args`" }
  0            
309 0     0 0   sub str_to_go { my $str = shift; return "`$str`" }
  0            
310              
311             sub string_to_go {
312 0     0 0   my $args = shift;
313 0           my $chars = [];
314 0           my $syms = [];
315 0           for my $atom (@{ atoms($args) }) {
  0            
316 0 0         if (is_sym($atom)) {
317 0           push @{$chars}, '%s';
  0            
318 0           push @{$syms}, atom_to_go($atom);
  0            
319             }
320 0           else { push @{$chars}, value($atom); }
  0            
321             }
322 0           my $str_expr = join '', @{$chars};
  0            
323 0 0         if (len($syms) > 0) {
324 0           my $syms_str = join ',', @{$syms};
  0            
325 0           return "Sprintf(\"$str_expr\", $syms_str)";
326             }
327 0           return "\"$str_expr\"";
328             }
329              
330             sub return_to_go {
331 0     0 0   my $args = shift;
332 0           my $strs = [map { atom_to_go($_) } @{ atoms($args) }];
  0            
  0            
333 0           my $str = join ',', @{$strs};
  0            
334 0           return "return $str";
335             }
336              
337             sub name_to_go {
338 0     0 0   my $name = shift;
339 0           my $chars = [];
340 0           for my $char (split '', $name) {
341 0 0         if (is_alpha($char)) { push @{$chars}, $char; }
  0            
  0            
342 0           else { push @{$chars}, '_'; }
  0            
343             }
344 0           return join '', @{$chars};
  0            
345             }
346              
347             sub sym_to_go {
348 0     0 0   my $name = shift;
349 0           my $first_char = first_char($name);
350 0 0         if ($first_char ~~ ['$', '@', '%']) {
351 0           return name_to_go($name);
352             }
353 0 0         if ($name ~~ ['len', 'append']) { return $name }
  0            
354 0           my $chars = [];
355 0           my $mode = 0;
356 0           for my $char (split '', $name) {
357 0 0         next if $char eq '$';
358 0 0         if ($mode == 0) {
359 0           $mode = 1;
360 0           push @{$chars}, uc($char);
  0            
361             }
362             else {
363 0 0         if ($char eq '-') { $mode = 0 }
  0            
364 0           else { push @{$chars}, $char; }
  0            
365             }
366             }
367 0           return join '', @{$chars};
  0            
368             }
369              
370             sub type_to_go {
371 0     0 0   my $str = shift;
372 0           given ($str) {
373 0           when ('Str') { return 'Str' }
  0            
374 0           when ('Int') { return 'Int' }
  0            
375 0           when ('Bool') { return 'Bool' }
  0            
376 0           when ('Array') { return 'Array{}' }
  0            
377 0           when ('Hash') { return 'Hash{}' }
  0            
378             }
379             }
380              
381             sub type_declare_to_go {
382 0     0 0   my $str = shift;
383 0           given ($str) {
384 0           when ('Str') { return 'Str' }
  0            
385 0           when ('Str+') { return '...Str' }
  0            
386 0           when ('Str?') { return 'Str' }
  0            
387 0           when ('Int') { return 'Int' }
  0            
388 0           when ('Bool') { return 'Bool' }
  0            
389 0           when ('Array') { return 'Array' }
  0            
390 0           when ('Hash') { return 'Hash' }
  0            
391 0           when ('Null') { return 'Null' }
  0            
392 0           when ('Cursor') { return '*Cursor' }
  0            
393 0           when ('Lint') { return '*Lint' }
  0            
394 0           when ('Parser') { return '*Parser' }
  0            
395 0           default { return "*$str" }
  0            
396             }
397             }
398             1;