From: Matt S Trout Date: Tue, 19 Jun 2012 16:29:08 +0000 (+0000) Subject: first cut at JSON deparser X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=7b31d3c356d8f567075ac5118b9449b0bc3292cb;p=scpubgit%2FTenDotTcl.git first cut at JSON deparser --- diff --git a/json.tcl b/json.tcl new file mode 100644 index 0000000..659c152 --- /dev/null +++ b/json.tcl @@ -0,0 +1,84 @@ +namespace eval ten::json { + + namespace eval deparse { + + variable quotes [ + list "\"" "\\\"" / \\/ \\ \\\\ \b \\b \f \\f \n \\n \r \\r \t \\t + ] + + variable indent + variable indentBy 0 + variable indentIncr + variable nl + + proc indent_one {} { + variable indentIncr + variable indentBy [ expr $indentBy + $indentIncr ] + variable indent [ string repeat " " $indentBy ] + } + + proc outdent_one {} { + variable indentIncr + variable indentBy [ expr $indentBy - $indentIncr ] + variable indent [ string repeat " " $indentBy ] + } + + proc str {str} { + variable quotes + return \"[ string map $quotes $str ]\" + } + + proc num {num} { + return $num + } + + proc list {args} { + variable indent + variable nl + set out \[ + indent_one + foreach el [lrange $args 0 end] { + append out $nl$indent + append out [ eval $el ], + } + outdent_one + append out $nl$indent\] + return $out + } + + proc obj {args} { + variable indent + variable nl + set out \{ + indent_one + dict for {k v} $args { + append out $nl$indent[ str $k ]:\ [ eval $v ], + } + outdent_one + append out $nl$indent\} + } + + proc deparse {args} { + switch -regexp [lindex $args 0] { + ^num|str|obj|list$ - + default { error "Invalid JSON type [lindex $args 0]" } + } + return [ eval $args ] + } + } + + proc deparse_json {data {indentIncr 2}} { + set deparse::indentBy 0 + set deparse::indentIncr $indentIncr + if [expr $indentIncr == 0] { + set deparse::nl "" + } else { + set deparse::nl "\n" + } + namespace inscope deparse eval $data + } +} + +puts [ ten::json::deparse_json { + list {str foo} {num 0} {obj __remote_object__ {str 512}} +} 0 ]