From 43a7facd090aaaf0176bcd04812bf2849650e3df Mon Sep 17 00:00:00 2001 From: Alec Berryman Date: Thu, 24 Dec 2009 17:48:16 -0600 Subject: [PATCH] json reader: correctly handle empty objects in objects Attempting to parse { "foo" : {} } previously resulted in an error. (close-hash) expected to consolidate an object into the values of the containing object (in the first line of code). While there is none in the case of the empty hash, the structure of the accumulator looked like it contained an unconsolidated object, so it folded the values into the keys and got very confused. --- basis/json/reader/reader-tests.factor | 5 ++++- basis/json/reader/reader.factor | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/basis/json/reader/reader-tests.factor b/basis/json/reader/reader-tests.factor index 79a0e4b5af..390fce1f94 100644 --- a/basis/json/reader/reader-tests.factor +++ b/basis/json/reader/reader-tests.factor @@ -1,4 +1,4 @@ -USING: arrays json.reader kernel strings tools.test +USING: assocs arrays json.reader kernel strings tools.test hashtables json ; IN: json.reader.tests @@ -58,3 +58,6 @@ IN: json.reader.tests { 0 } [ " 0" json> ] unit-test { 0 } [ "0 " json> ] unit-test { 0 } [ " 0 " json> ] unit-test + +! empty objects are allowed as values in objects +{ H{ { "foo" H{ } } } } [ "{ \"foo\" : {}}" json> ] unit-test diff --git a/basis/json/reader/reader.factor b/basis/json/reader/reader.factor index bdfeaa3e51..082bbd8446 100644 --- a/basis/json/reader/reader.factor +++ b/basis/json/reader/reader.factor @@ -15,7 +15,7 @@ IN: json.reader ] dip ; DEFER: j-string - + : convert-string ( str -- str ) read1 { @@ -30,17 +30,17 @@ DEFER: j-string dup [ 1string append j-string append ] [ drop ] if ; - + : j-string ( -- str ) "\\\"" read-until CHAR: \" = [ convert-string ] unless ; - + : second-last ( seq -- second-last ) [ length 2 - ] keep nth ; inline : third-last ( seq -- third-last ) [ length 3 - ] keep nth ; inline - + : last2 ( seq -- second-last last ) [ second-last ] [ last ] bi ; inline @@ -68,12 +68,12 @@ DEFER: j-string dup pop >array over push ; : (close-hash) ( accum -- accum' ) - dup length 3 >= [ v-over-push ] when - dup dup [ pop ] dip pop swap + dup [ length 3 >= ] [ last V{ } = not ] bi@ and [ v-over-push ] when + dup dup [ pop ] bi@ swap zip H{ } assoc-clone-like over push ; - + : scan ( accum char -- accum ) - ! 2dup . . ! Great for debug... + ! 2dup 1string swap . . ! Great for debug... [ { { CHAR: \" [ j-string over push ] } @@ -91,13 +91,13 @@ DEFER: j-string { CHAR: f [ 4 read drop f over push ] } { CHAR: n [ 3 read drop json-null over push ] } [ value [ over push ] dip [ scan ] when* ] - } case + } case ] when* ; : (json-parser>) ( string -- object ) [ V{ } clone [ read1 dup ] [ scan ] while drop first ] with-string-reader ; - + PRIVATE> - + : json> ( string -- object ) (json-parser>) ;