File Coverage

blib/lib/Mylisp/ToMylisp.pm
Criterion Covered Total %
statement 14 173 8.0
branch 0 18 0.0
condition n/a
subroutine 5 22 22.7
pod 0 17 0.0
total 19 230 8.2


line stmt bran cond sub pod time code
1             package Mylisp::ToMylisp;
2              
3 1     1   16 use 5.012;
  1         3  
4 1     1   4 no warnings "experimental";
  1         1  
  1         26  
5              
6 1     1   4 use Exporter;
  1         2  
  1         64  
7             our @ISA = qw(Exporter);
8             our @EXPORT =
9             qw(ast_to_mylisp atoms_to_mylisp atoms_to_mylisps atom_to_mylisp oper_to_mylisp name_to_mylisp func_to_mylisp args_to_mylisp aindex_to_mylisp for_to_mylisp our_to_mylisp str_to_mylisp string_to_mylisp array_to_mylisp hash_to_mylisp is_kstr tidy_mylisp);
10 1     1   5 use Spp::Builtin;
  1         2  
  1         165  
11 1     1   6 use Spp::Tools;
  1         2  
  1         1263  
12              
13             sub ast_to_mylisp {
14 0     0 0   my $ast = shift;
15 0           my $str = atoms_to_mylisp($ast);
16 0           return tidy_mylisp($str);
17             }
18              
19             sub atoms_to_mylisp {
20 0     0 0   my $atoms = shift;
21             my $strs =
22 0           [map { atom_to_mylisp($_) } @{ atoms($atoms) }];
  0            
  0            
23 0           return join ' ', @{$strs};
  0            
24             }
25              
26             sub atoms_to_mylisps {
27 0     0 0   my $atoms = shift;
28             return estr(
29 0           [map { atom_to_mylisp($_) } @{ atoms($atoms) }]);
  0            
  0            
30             }
31              
32             sub atom_to_mylisp {
33 0     0 0   my $atom = shift;
34 0           my ($name, $args) = flat($atom);
35 0 0         if (
36             $name ~~ [
37             '!=', '&&', '+', '-', '<', '<<', '<=', '==',
38             '>', '=', '>=', '>>', '><', 'eq', 'in', 'le',
39             'ne', 'x', '||'
40             ]
41             )
42             {
43 0           return oper_to_mylisp($name, $args);
44             }
45 0           given ($name) {
46 0           when ('func') { return func_to_mylisp($args) }
  0            
47 0           when ('Aindex') { return aindex_to_mylisp($args) }
  0            
48 0           when ('Str') { return str_to_mylisp($args) }
  0            
49 0           when ('String') { return string_to_mylisp($args) }
  0            
50 0           when ('Array') { return array_to_mylisp($args) }
  0            
51 0           when ('Hash') { return hash_to_mylisp($args) }
  0            
52 0           when ('for') { return for_to_mylisp($args) }
  0            
53 0           when ('our') { return our_to_mylisp($args) }
  0            
54 0           when ('package') { return "(package $args)" }
  0            
55 0           when ('use') { return "(use $args)" }
  0            
56 0           when ('Sym') { return $args }
  0            
57 0           when ('Int') { return $args }
  0            
58 0           when ('Ns') { return $args }
  0            
59 0           when ('Bool') { return $args }
  0            
60 0           when ('Char') { return $args }
  0            
61 0           when ('Type') { return $args }
  0            
62 0           when ('end') { return '(end)' }
  0            
63 0           default { return name_to_mylisp($name, $args) }
  0            
64             }
65             }
66              
67             sub oper_to_mylisp {
68 0     0 0   my ($name, $args) = @_;
69 0           my $strs = atoms_to_mylisps($args);
70 0           my $str = ejoin($strs, " $name ");
71 0           return "($str)";
72             }
73              
74             sub name_to_mylisp {
75 0     0 0   my ($name, $args) = @_;
76 0           my $str = atoms_to_mylisp($args);
77 0           return "($name $str)";
78             }
79              
80             sub func_to_mylisp {
81 0     0 0   my $atoms = shift;
82 0           my ($name_args, $exprs) = match($atoms);
83 0           my ($name, $args) = flat($name_args);
84 0           my $args_str = args_to_mylisp($args);
85 0           my $exprs_str = atoms_to_mylisp($exprs);
86 0           return "(func ($name $args_str) $exprs_str)";
87             }
88              
89             sub args_to_mylisp {
90 0     0 0   my $args = shift;
91 0           my $strs = [];
92 0           for my $arg (@{ atoms($args) }) {
  0            
93 0           my ($name, $type) = flat($arg);
94 0           push @{$strs}, "$name:$type";
  0            
95             }
96 0           return join ' ', @{$strs};
  0            
97             }
98              
99             sub aindex_to_mylisp {
100 0     0 0   my $args = shift;
101 0           my $strs = atoms_to_mylisps($args);
102 0           my ($name, $indexs) = match($strs);
103 0           my $indexs_str = ejoin($indexs, '][');
104 0           return "$name\[$indexs_str]";
105             }
106              
107             sub for_to_mylisp {
108 0     0 0   my $args = shift;
109 0           my ($iter_expr, $exprs) = match($args);
110 0           my ($loop, $iter_atom) = flat($iter_expr);
111 0           my $iter_str = atom_to_mylisp($iter_atom);
112 0           my $exprs_str = atoms_to_mylisp($exprs);
113 0           return "(for ($loop in $iter_str) $exprs_str)";
114             }
115              
116             sub our_to_mylisp {
117 0     0 0   my $args = shift;
118 0           my $strs = atoms_to_mylisps($args);
119 0           my ($slist, $value) = flat($strs);
120 0           return "(my $slist $value)";
121             }
122              
123             sub str_to_mylisp {
124 0     0 0   my $str = shift;
125 0 0         if (is_kstr($str)) { return ":$str" }
  0            
126 0           return "'$str'";
127             }
128              
129             sub string_to_mylisp {
130 0     0 0   my $string = shift;
131 0           my $strs = [map { value($_) } @{ atoms($string) }];
  0            
  0            
132 0           my $str = join '', @{$strs};
  0            
133 0           return "\"$str\"";
134             }
135              
136             sub array_to_mylisp {
137 0     0 0   my $array = shift;
138 0           my $atoms = atoms_to_mylisps($array);
139 0           my $atoms_str = ejoin($atoms, ' ');
140 0           return "[$atoms_str]";
141             }
142              
143             sub hash_to_mylisp {
144 0     0 0   my $pairs = shift;
145 0           my $pairs_strs = [];
146 0           for my $pair (@{ atoms($pairs) }) {
  0            
147 0           my ($name, $key_value) = flat($pair);
148 0           my $pair_strs = atoms_to_mylisps($key_value);
149 0           my ($key, $value) = flat($pair_strs);
150 0           push @{$pairs_strs}, "$key => $value";
  0            
151             }
152 0           my $pairs_str = join ', ', @{$pairs_strs};
  0            
153 0           return "{$pairs_str}";
154             }
155              
156             sub is_kstr {
157 0     0 0   my $str = shift;
158 0           for my $char (split '', $str) {
159 0 0         next if is_alpha($char);
160 0           return 0;
161             }
162 0           return 1;
163             }
164              
165             sub tidy_mylisp {
166 0     0 0   my $str = shift;
167 0           my $chars = [];
168 0           my $depth = 0;
169 0           my $mode = 'expr';
170 0           for my $char (split '', $str) {
171 0 0         if ($mode eq 'expr') {
172 0           given ($char) {
173 0           when ('(') { $depth++ }
  0            
174 0           when (')') { $depth-- }
  0            
175 0           when ("'") { $mode = 'str' }
  0            
176 0           when ('"') { $mode = 'string' }
  0            
177             }
178             }
179 0 0         if ($mode eq 'string') {
180 0           when ('"') { $mode = 'expr' }
  0            
181 0           when ('\\') { $mode = 'stringescape' }
  0            
182             }
183 0 0         if ($mode eq 'str') {
184 0           when ("'") { $mode = 'expr' }
  0            
185 0           when ('\\') { $mode = 'strescape' }
  0            
186             }
187 0 0         if ($mode eq 'stringescape') { $mode = 'string' }
  0            
188 0 0         if ($mode eq 'strescape') { $mode = 'str' }
  0            
189 0           push @{$chars}, $char;
  0            
190 0 0         if ($depth == 0) { push @{$chars}, "\n"; }
  0            
  0            
191             }
192 0           return join '', @{$chars};
  0            
193             }
194             1;