JSON in newLISP - via Perl

Started by Kirill, October 04, 2009, 08:13:10 AM

Previous topic - Next topic

Kirill

Hi there,



I have a JSON file with some contact data:



km@krot:/home/km/bin> ls -l /home/km/conf/fcontacts.json
-rw-r-----  1 km  km  192274 Oct  4 03:29 /home/km/conf/fcontacts.json


JSON is not a good format for newLISP to handle yet. I didn't have enough patience to wait for json.lsp finishing parsing of this file.



Perl's JSON::XS is a lot faster:



km@krot:/home/km/bin> time ./perl2lsp.pl > /dev/null
0.118u 0.027s 0:00.15 86.6%     1615+1376k 0+0io 0pf+0w


perl2lsp.pl is a quick hack that convert's Perl's data structures to sexps.



I post the entire code here, maybe it will be useful to someone.



use strict;
use utf8;

use feature qw(:5.10);

use IO::All;
use JSON;

my $xfile = '/home/km/conf/fcontacts.json';
my $abook = from_json(io($xfile)->utf8->slurp());

say "(set 'abook:abook";
say "'", dump_data($abook);
say ')';

sub dump_data {
    my $data = shift;
    given (ref $data) {
        when ('HASH') { return dump_hash($data) }
        when ('ARRAY') { return dump_array($data) }
        default { return quote($data) }
    };
}

sub dump_array {
    my @ret = ('(', join(' ', map { dump_data($_) } @{$_[0]}), ')', "n");
    return '', @ret;
}

sub dump_hash {
    my @ret = ('(', "n");
    while (my ($k, $v) = each %{$_[0]}) {
        push @ret, '(', quote($k), ' ', dump_data($v), ')', "n";
    }
    push @ret, ')', "n";
    return join '', @ret;
}

sub quote {
    my $x = shift;
    return 'nil' if !defined $x;
    return $x if $x =~ /^-?d+(.d+)?$/;
    $x =~ s/"/\"/g;
    $x =~ s/n/\n/g;
    $x =~ s/r/\r/g;
    $x =~ s/t/\t/g;
    return '"' . $x . '"';
}


The output is not pretty, but hey, it gets parsed by newLISP, so I'm happy with that.



-- Kirill