Author: coke
Date: Fri Oct 21 08:48:09 2005
New Revision: 9529

Added:
   trunk/runtime/parrot/library/JSON.imc
   trunk/t/library/json.t
Modified:
   trunk/MANIFEST
   trunk/config/gen/makefiles/root.in
Log:
11:56 <Coke> JSON?
11:56 <purl> well, JSON is Javascript Object Notation, at 
             http://www.crockford.com/JSON/

Here is a first pass at adding JSON to the library.



Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Fri Oct 21 08:48:09 2005
@@ -1630,6 +1630,7 @@ lib/Test/Builder.pm                     
 lib/Test/More.pm                                  [devel]
 lib/Test/Simple.pm                                [devel]
 lib/Text/Balanced.pm                              [devel]
+runtime/parrot/library/JSON.imc                   [library]
 runtime/parrot/library/Data/Sort.imc              [library]
 runtime/parrot/library/Data/Escape.imc            [library]
 runtime/parrot/library/Data/Replace.imc           [library]
@@ -1928,6 +1929,7 @@ t/pmc/tqueue.t                          
 t/pmc/undef.t                                     []
 t/library/data_escape.t                           []
 t/library/dumper.t                                []
+t/library/json.t                                  []
 t/library/getopt_long.t                           []
 t/library/md5.t                                   []
 t/library/parrotlib.t                             []

Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in  (original)
+++ trunk/config/gen/makefiles/root.in  Fri Oct 21 08:48:09 2005
@@ -250,6 +250,7 @@ GEN_LIBRARY = \
     $(LIBRARY_DIR)/Digest/MD5.pbc \
     $(LIBRARY_DIR)/dumper.pbc \
     $(LIBRARY_DIR)/Getopt/Long.pbc \
+    $(LIBRARY_DIR)/JSON.pbc \
     $(LIBRARY_DIR)/ncurses.pbc \
     $(LIBRARY_DIR)/parrotlib.pbc \
     $(LIBRARY_DIR)/pcre.pbc \

Added: trunk/runtime/parrot/library/JSON.imc
==============================================================================
--- (empty file)
+++ trunk/runtime/parrot/library/JSON.imc       Fri Oct 21 08:48:09 2005
@@ -0,0 +1,332 @@
+=head1 TITLE
+
+JSON.imc - PIR implementation of JSON data interchange format.
+
+=head1 SYNOPSIS
+
+ ...
+
+ # generate a JSON representation of a PMC.
+ $S0 = _json( $P0 )
+
+ # generate a PMC from a JSON representation:
+ $P1 = _json_to_pmc( "[1,2,3]" ) 
+ #$P1 is now a array-like container PMC with three Integer elements.
+
+ .end
+ .include 'library/JSON.imc'
+
+=head1 DESCRIPTION
+
+PIR implementation of JSON
+
+=cut
+
+=head1 FUNCTIONS
+
+This library provides the following functions:
+
+=over 4
+
+=item (string) = _json(pmc, ?pretty] )
+
+Convert a PMC to a JSON-serialized string
+
+=over 4
+
+=item pmc
+
+Required. The PMC to dump.
+
+=item pretty
+
+Optional. Boolean: If true, then the generated string will be very
+readable for humans. Defaults to false, which will generate the
+most compact string possible.
+
+=back
+
+=cut
+
+.const string _json_prefix = '  '
+
+.sub _json
+    .param pmc thing
+    .param int pretty     :optional
+    .param int has_pretty :opt_flag
+
+    .local string result
+
+    if has_pretty goto done_init
+    pretty = 0
+
+done_init:
+    result = _json_any(thing,pretty,0)
+    unless pretty goto plain
+    result .= "\n"
+plain:
+    .return (result)
+.end
+
+.sub _json_any
+    .param pmc thing
+    .param int pretty
+    .param int indent
+
+done_init:
+    if_null thing, json_null
+
+    $I0 = does thing, "array"
+    if $I0 goto json_array
+
+    $I0 = does thing, "hash"
+    if $I0 goto json_hash
+
+    $I0 = does thing, "string"
+    if $I0 goto json_string
+
+    $I0 = does thing, "boolean"
+    if $I0 goto json_boolean
+
+    $I0 = does thing, "integer"
+    if $I0 goto json_integer
+
+    $I0 = does thing, "float"
+    if $I0 goto json_float
+
+    # Default to a null. We could in the future make this more
+    # clever, or conditional.
+json_null:
+    .return _json_null(thing,pretty,indent)
+json_string:
+    .return _json_string(thing,pretty,indent)
+json_array:
+    .return _json_array(thing,pretty,indent)
+json_hash:
+    .return _json_hash(thing,pretty,indent)
+json_boolean:
+    .return _json_boolean(thing,pretty,indent)
+json_integer:
+    .return _json_number(thing,pretty,indent)
+json_float:
+    .return _json_number(thing,pretty,indent)
+
+.end
+
+.sub '_json_null'
+  .param pmc thing  # ignored, but needed for the ``API''
+  .param int pretty
+  .param int indent
+
+  unless pretty goto plain
+  unless indent goto plain
+
+  .local string result
+  result = repeat _json_prefix, indent
+  result .= 'null'
+  .return (result)
+
+plain:
+  .return ('null')
+.end
+
+.sub '_json_string'
+  .param pmc thing
+  .param int pretty
+  .param int indent
+
+  .local string result
+
+  $S0 = thing
+  result = '"' . $S0
+  result = result . '"'
+
+  unless pretty goto plain
+  unless indent goto plain
+
+  $S0 = repeat _json_prefix, indent
+  result = $S0 . result
+
+plain:
+  .return (result)
+.end
+
+.sub '_json_boolean'
+  .param pmc thing
+  .param int pretty
+  .param int indent
+
+  .local string result
+
+  result = 'true'
+  if thing goto got_value
+  result = 'false'
+
+got_value:
+
+  unless pretty goto plain
+  unless indent goto plain
+
+  $S0 = repeat _json_prefix, indent
+  result = $S0 . result
+
+plain:
+  .return (result)
+.end
+
+.sub '_json_number'
+  .param pmc thing
+  .param int pretty
+  .param int indent
+
+  .local string result
+
+  result = thing
+
+  unless pretty goto plain
+  unless indent goto plain
+
+  $S0 = repeat _json_prefix, indent
+  result = $S0 . result
+
+plain:
+  .return (result)
+.end
+
+.sub '_json_array'
+  .param pmc thing
+  .param int pretty
+  .param int indent
+
+  .local string result
+
+  result = '['
+
+  unless pretty goto pre_loop
+  unless indent goto pre_loop
+ 
+  $S0 = repeat _json_prefix, indent
+  result = $S0 . result
+  result .= "\n"
+
+pre_loop:
+  inc indent
+  .local int pos,len
+  pos = 0
+  len = thing
+  unless pretty goto loop
+  result .= "\n"
+
+loop:
+  if pos >= len goto done_loop
+  $P1 = thing[pos]
+  $S0 = _json_any($P1,pretty,indent)
+  result .= $S0
+  inc pos
+  if pos == len goto loop
+  result .= ","
+  unless pretty goto loop
+  result .= "\n"
+  goto loop
+
+done_loop:
+  dec indent
+
+  .local string optional_newline,optional_indent
+  optional_newline = ''
+  optional_indent = ''
+
+  unless pretty goto done
+  optional_newline = "\n"
+
+  unless indent goto done
+  optional_indent = repeat _json_prefix, indent
+
+done:
+  result .= optional_newline
+  result .= optional_indent
+  result .= ']'
+
+  .return (result)
+.end
+
+.sub '_json_hash'
+  .param pmc thing
+  .param int pretty
+  .param int indent
+
+  .local string result,separator
+
+  result = '{'
+  separator = ':'
+
+  unless pretty goto pre_loop
+  separator = ' : '
+  unless indent goto pre_loop
+ 
+  $S0 = repeat _json_prefix, indent
+  result = $S0 . result
+  result .= "\n"
+
+pre_loop:
+  inc indent
+  .local int pos,len
+  pos = 0
+  len = thing
+  unless pretty goto loop
+  result .= "\n"
+  .local pmc iter 
+  iter = new .Iterator, thing
+  iter = 0
+  .local string key
+
+loop:
+  if pos >= len goto done_loop
+  key = shift iter
+  $S0 = _json_string(key,pretty,indent)
+  result .= $S0
+  result .= separator
+  $P1 = thing[key]
+  $S0 = _json_any($P1,pretty,indent)
+  result .= $S0
+  inc pos
+  if pos == len goto loop
+  result .= ","
+  unless pretty goto loop
+  result .= "\n"
+  goto loop
+
+done_loop:
+  dec indent
+
+  .local string optional_newline,optional_indent
+  optional_newline = ''
+  optional_indent = ''
+
+  unless pretty goto done
+  optional_newline = "\n"
+
+  unless indent goto done
+  optional_indent = repeat _json_prefix, indent
+
+done:
+  result .= optional_newline
+  result .= optional_indent
+  result .= '}'
+
+  .return (result)
+.end
+
+=head1 TODO
+
+=over 4
+
+=item Hashed subentries are not entirely pretty yet.
+
+=item Pending a more comprehensive test suite from Roger Browne
+
+=item String Escaping
+
+=item implement _jsan_to_pmc
+
+=cut

Added: trunk/t/library/json.t
==============================================================================
--- (empty file)
+++ trunk/t/library/json.t      Fri Oct 21 08:48:09 2005
@@ -0,0 +1,77 @@
+#! perl -w
+# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
+# $Id $
+
+=head1 NAME
+
+t/library/json.t - test JSON library
+
+=head1 SYNOPSIS
+
+       % perl -Ilib t/library/json.t
+
+=head1 DESCRIPTION
+
+Tests JSON->Parrot and Parrot->JSON conversions.
+
+=cut
+
+use strict;
+
+use Parrot::Test tests => 2;
+use Test::More;
+
+use vars qw($SKIP);
+
+SKIP: {
+    local $SKIP = "Not implemented yet.";
+
+# no. 1
+pir_output_is(<<'CODE', <<'OUT', 'Create JSON of an empty string');
+
+.sub test :main
+    $S0 =_json( '', 1 )
+    print $S0
+.end
+.include 'library/JSON.imc'
+CODE
+""
+OUT
+
+# no. 2
+pir_output_is(<<'CODE', <<'OUT', 'Create JSON of an array');
+
+.sub test :main
+    .local pmc array
+
+    new array, .PerlArray
+    push array, 0
+    push array, 1
+    push array, 2
+    push array, 3
+    push array, 4
+    push array, 5
+    push array, 6
+    push array, 7
+    push array, 8
+    push array, 9
+
+    $S0 = _json( array, 1 )
+    print $S0
+.end
+.include 'library/JSON.imc'
+CODE
+[
+  0,
+  1,
+  2,
+  3,
+  4,
+  5,
+  6,
+  7,
+  8,
+  9
+]
+OUT
+}

Reply via email to