File Coverage

blib/lib/Mylisp/Estr.pm
Criterion Covered Total %
statement 11 292 3.7
branch 0 82 0.0
condition n/a
subroutine 4 36 11.1
pod 0 31 0.0
total 15 441 3.4


line stmt bran cond sub pod time code
1             package Mylisp::Estr;
2            
3 1     1   22 use 5.012;
  1         4  
4 1     1   8 use experimental 'switch';
  1         3  
  1         6  
5            
6 1     1   130 use Exporter;
  1         2  
  1         133  
7             our @ISA = qw(Exporter);
8             our @EXPORT = qw(is_true is_false is_bool is_str is_estr is_atom is_atoms is_blank estr estr_atom estr_strs estr_ints estr_int json_to_estr estr_to_json char_to_json atoms flat match _name name value off elen erest epush eappend eunshift is_atom_name is_sym clean_ast clean_atom);
9            
10 1     1   10 use Mylisp::Builtin;
  1         2  
  1         5162  
11             sub is_true {
12 0     0 0   my $str = shift;
13 0           return $str eq True;
14             }
15             sub is_false {
16 0     0 0   my $str = shift;
17 0           return $str eq False;
18             }
19             sub is_bool {
20 0     0 0   my $str = shift;
21 0 0         if (is_true($str)) {
22 0           return 1;
23             }
24 0 0         if (is_false($str)) {
25 0           return 1;
26             }
27 0           return 0;
28             }
29             sub is_str {
30 0     0 0   my $str = shift;
31 0           my $char = first_char($str);
32 0           return ord($char) > 6;
33             }
34             sub is_estr {
35 0     0 0   my $str = shift;
36 0           return first_char($str) eq In;
37             }
38             sub is_atom {
39 0     0 0   my $atom = shift;
40 0 0         if (first_char($atom) eq In) {
41 0 0         if (substr($atom, 1, 1) eq Qstr) {
42 0           return 1;
43             }
44             }
45 0           return 0;
46             }
47             sub is_atoms {
48 0     0 0   my $atoms = shift;
49 0 0         if (is_estr($atoms)) {
50 0           for my $atom (@{atoms($atoms)}) {
  0            
51 0 0         if (not(is_atom($atom))) {
52 0           return 0;
53             }
54             }
55 0           return 1;
56             }
57 0           return 1;
58             }
59             sub is_blank {
60 0     0 0   my $str = shift;
61 0           return $str eq Blank;
62             }
63             sub estr {
64 0     0 0   my @args = @_;
65 0           my $estr = to_str([ map { estr_atom($_) } @args ]);
  0            
66 0           return add(In,$estr,Out);
67             }
68             sub estr_atom {
69 0     0 0   my $atom = shift;
70 0 0         if (is_estr($atom)) {
71 0           return $atom;
72             }
73 0 0         if (is_str($atom)) {
74 0           return add(Qstr,$atom);
75             }
76 0           croak("|$atom| not estr or str or int!");
77 0           return False;
78             }
79             sub estr_strs {
80 0     0 0   my $array = shift;
81 0           my $estr = to_str([ map { estr_atom($_) } @{$array} ]);
  0            
  0            
82 0           return add(In,$estr,Out);
83             }
84             sub estr_ints {
85 0     0 0   my $ints = shift;
86 0           my $estrs = [];
87 0           for my $int (@{$ints}) {
  0            
88 0           apush($estrs,estr_int($int));
89             }
90 0           return add(In,to_str($estrs),Out);
91             }
92             sub estr_int {
93 0     0 0   my $int = shift;
94 0           return add(Qint,int_to_str($int));
95             }
96             sub json_to_estr {
97 0     0 0   my $json = shift;
98 0 0         if (is_estr($json)) {
99 0           return $json;
100             }
101 0           my $chars = [];
102 0           my $mode = 0;
103 0           for my $ch (@{to_chars($json)}) {
  0            
104 0 0         if ($mode == 0) {
    0          
    0          
105 0           given ($ch) {
106 0           when ('[') {
107 0           apush($chars,In);
108             }
109 0           when (']') {
110 0           apush($chars,Out);
111             }
112 0           when ('"') {
113 0           apush($chars,Qstr);
114 0           $mode = 1;
115             }
116 0           default {
117 0 0         if (is_digit($ch)) {
118 0           apush($chars,Qint);
119 0           apush($chars,$ch);
120 0           $mode = 2;
121             }
122             }
123             }
124             }
125             elsif ($mode == 1) {
126 0           given ($ch) {
127 0           when ('"') {
128 0           $mode = 0;
129             }
130 0           when (Ep) {
131 0           $mode = 3;
132             }
133 0           default {
134 0           apush($chars,$ch);
135             }
136             }
137             }
138             elsif ($mode == 2) {
139 0 0         if ($ch eq ',') {
140 0           $mode = 0;
141             }
142 0 0         if ($ch eq ']') {
143 0           apush($chars,Out);
144 0           $mode = 0;
145             }
146 0 0         if (is_digit($ch)) {
147 0           apush($chars,$ch);
148             }
149             }
150             else {
151 0           $mode = 1;
152 0           given ($ch) {
153 0           when ('t') {
154 0           apush($chars,"\t");
155             }
156 0           when ('r') {
157 0           apush($chars,"\r");
158             }
159 0           when ('n') {
160 0           apush($chars,"\n");
161             }
162 0           default {
163 0           apush($chars,$ch);
164             }
165             }
166             }
167             }
168 0           return to_str($chars);
169             }
170             sub estr_to_json {
171 0     0 0   my $estr = shift;
172 0 0         if (is_str($estr)) {
173 0           return $estr;
174             }
175 0           my $chars = [];
176 0           my $mode = 0;
177 0           for my $ch (@{to_chars($estr)}) {
  0            
178 0 0         if ($mode == 0) {
    0          
    0          
179 0           given ($ch) {
180 0           when (In) {
181 0           apush($chars,'[');
182             }
183 0           when (Qstr) {
184 0           apush($chars,'"');
185 0           $mode = 1;
186             }
187 0           when (Qint) {
188 0           $mode = 2;
189             }
190 0           when (Out) {
191 0           apush($chars,']');
192 0           $mode = 3;
193             }
194             }
195             }
196             elsif ($mode == 1) {
197 0           given ($ch) {
198 0           when (In) {
199 0           apush($chars,'",[');
200 0           $mode = 0;
201             }
202 0           when (Qstr) {
203 0           apush($chars,'","');
204             }
205 0           when (Qint) {
206 0           apush($chars,'",');
207 0           $mode = 2;
208             }
209 0           when (Out) {
210 0           apush($chars,'"]');
211 0           $mode = 3;
212             }
213 0           default {
214 0           apush($chars,char_to_json($ch));
215             }
216             }
217             }
218             elsif ($mode == 2) {
219 0           given ($ch) {
220 0           when (In) {
221 0           apush($chars,',[');
222 0           $mode = 0;
223             }
224 0           when (Qstr) {
225 0           apush($chars,',"');
226 0           $mode = 1;
227             }
228 0           when (Qint) {
229 0           apush($chars,',');
230             }
231 0           when (Out) {
232 0           apush($chars,']');
233 0           $mode = 3;
234             }
235 0           default {
236 0           apush($chars,$ch);
237             }
238             }
239             }
240             else {
241 0           given ($ch) {
242 0           when (In) {
243 0           apush($chars,',[');
244 0           $mode = 0;
245             }
246 0           when (Qstr) {
247 0           apush($chars,',"');
248 0           $mode = 1;
249             }
250 0           when (Qint) {
251 0           apush($chars,',');
252 0           $mode = 2;
253             }
254 0           when (Out) {
255 0           apush($chars,']');
256             }
257             }
258             }
259             }
260 0           return to_str($chars);
261             }
262             sub char_to_json {
263 0     0 0   my $ch = shift;
264 0           given ($ch) {
265 0           when ("\t") {
266 0           return '\t';
267             }
268 0           when ("\n") {
269 0           return '\n';
270             }
271 0           when ("\r") {
272 0           return '\r';
273             }
274 0           when (Ep) {
275 0           return '\\\\';
276             }
277 0           when ('"') {
278 0           return '\"';
279             }
280 0           default {
281 0           return $ch;
282             }
283             }
284             }
285             sub atoms {
286 0     0 0   my $estr = shift;
287 0           my $estrs = [];
288 0           my $chars = [];
289 0           my $depth = 0;
290 0           my $mode = 0;
291 0           for my $ch (@{to_chars($estr)}) {
  0            
292 0 0         if ($depth == 0) {
    0          
293 0 0         if ($ch eq In) {
294 0           $depth++;;
295             }
296             }
297             elsif ($depth == 1) {
298 0           given ($ch) {
299 0           when (In) {
300 0           $depth++;;
301 0 0         if ($mode) {
302 0           apush($estrs,to_str($chars));
303 0           $chars = [];
304             }
305 0           $mode = 1;
306 0           apush($chars,$ch);
307             }
308 0           when (Qstr) {
309 0 0         if ($mode) {
310 0           apush($estrs,to_str($chars));
311 0           $chars = [];
312             }
313 0           $mode = 1;
314             }
315 0           when (Qint) {
316 0 0         if ($mode) {
317 0           apush($estrs,to_str($chars));
318 0           $chars = [];
319             }
320 0           $mode = 1;
321             }
322 0           when (Out) {
323 0 0         if ($mode) {
324 0           apush($estrs,to_str($chars));
325             }
326             }
327 0           default {
328 0 0         if ($mode) {
329 0           apush($chars,$ch);
330             }
331             }
332             }
333             }
334             else {
335 0 0         if ($ch eq In) {
336 0           $depth++;;
337             }
338 0 0         if ($ch eq Out) {
339 0           $depth --;
340             }
341 0           apush($chars,$ch);
342             }
343             }
344 0           return $estrs;
345             }
346             sub flat {
347 0     0 0   my $estr = shift;
348 0 0         if (is_str($estr)) {
349 0           croak("Str: |$estr| could not flat!");
350             }
351 0           my $atoms = atoms($estr);
352 0 0         if (len($atoms) < 2) {
353 0           croak("flat less two atom");
354             }
355 0           return $atoms->[0],$atoms->[1];
356             }
357             sub match {
358 0     0 0   my $estr = shift;
359 0           my $atoms = atoms($estr);
360 0 0         if (len($atoms) == 0) {
361 0           error("match with blank");
362             }
363 0 0         if (len($atoms) == 1) {
364 0           return $atoms->[0],Blank;
365             }
366 0           return $atoms->[0],estr_strs(rest($atoms));
367             }
368             sub _name {
369 0     0     my $estr = shift;
370 0           my $name = first(atoms($estr));
371 0 0         if (is_atom($name)) {
372 0           croak("(name ..) with atoms");
373             }
374 0           return $name;
375             }
376             sub name {
377 0     0 0   my $estr = shift;
378 0           my $chars = [];
379 0           my $str = substr($estr, 2);
380 0           for my $char (@{to_chars($str)}) {
  0            
381 0 0         if (ord($char) > 6) {
382 0           apush($chars,$char);
383             }
384             else {
385 0           return to_str($chars);
386             }
387             }
388             }
389             sub value {
390 0     0 0   my $estr = shift;
391 0           my $atoms = atoms($estr);
392 0           return $atoms->[1];
393             }
394             sub off {
395 0     0 0   my $estr = shift;
396 0           my $atoms = atoms($estr);
397 0           return tail($atoms);
398             }
399             sub elen {
400 0     0 0   my $estr = shift;
401 0           my $atoms = atoms($estr);
402 0           return len($atoms);
403             }
404             sub erest {
405 0     0 0   my $estr = shift;
406 0           return estr_strs(rest(atoms($estr)));
407             }
408             sub epush {
409 0     0 0   my ($estr,$elem) = @_;
410 0           return add(cut($estr),$elem,Out);
411             }
412             sub eappend {
413 0     0 0   my ($a_one,$a_two) = @_;
414 0           return add(cut($a_one),rest_str($a_two));
415             }
416             sub eunshift {
417 0     0 0   my ($elem,$array) = @_;
418 0           return add(In,$elem,rest_str($array));
419             }
420             sub is_atom_name {
421 0     0 0   my ($atom,$name) = @_;
422 0 0         if (is_atom($atom)) {
423 0           return name($atom) eq $name;
424             }
425 0           return 0;
426             }
427             sub is_sym {
428 0     0 0   my $atom = shift;
429 0           return is_atom_name($atom,'Sym');
430             }
431             sub clean_ast {
432 0     0 0   my $ast = shift;
433 0 0         if (is_atom($ast)) {
434 0           return clean_atom($ast);
435             }
436 0           my $clean_atoms = [];
437 0           for my $atom (@{atoms($ast)}) {
  0            
438 0           apush($clean_atoms,clean_atom($atom));
439             }
440 0           return estr_strs($clean_atoms);
441             }
442             sub clean_atom {
443 0     0 0   my $atom = shift;
444 0           my ($name,$value) = flat($atom);
445 0 0         if (is_str($value)) {
446 0           return estr($name,$value);
447             }
448 0 0         if (is_blank($value)) {
449 0           return estr($name,$value);
450             }
451 0 0         if (is_atom($value)) {
452 0           return estr($name,clean_atom($value));
453             }
454 0           return estr($name,clean_ast($value));
455             }
456             1;