--- /dev/null
+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 ]