first cut at JSON deparser
[scpubgit/TenDotTcl.git] / json.tcl
CommitLineData
7b31d3c3 1namespace eval ten::json {
2
3 namespace eval deparse {
4
5 variable quotes [
6 list "\"" "\\\"" / \\/ \\ \\\\ \b \\b \f \\f \n \\n \r \\r \t \\t
7 ]
8
9 variable indent
10 variable indentBy 0
11 variable indentIncr
12 variable nl
13
14 proc indent_one {} {
15 variable indentIncr
16 variable indentBy [ expr $indentBy + $indentIncr ]
17 variable indent [ string repeat " " $indentBy ]
18 }
19
20 proc outdent_one {} {
21 variable indentIncr
22 variable indentBy [ expr $indentBy - $indentIncr ]
23 variable indent [ string repeat " " $indentBy ]
24 }
25
26 proc str {str} {
27 variable quotes
28 return \"[ string map $quotes $str ]\"
29 }
30
31 proc num {num} {
32 return $num
33 }
34
35 proc list {args} {
36 variable indent
37 variable nl
38 set out \[
39 indent_one
40 foreach el [lrange $args 0 end] {
41 append out $nl$indent
42 append out [ eval $el ],
43 }
44 outdent_one
45 append out $nl$indent\]
46 return $out
47 }
48
49 proc obj {args} {
50 variable indent
51 variable nl
52 set out \{
53 indent_one
54 dict for {k v} $args {
55 append out $nl$indent[ str $k ]:\ [ eval $v ],
56 }
57 outdent_one
58 append out $nl$indent\}
59 }
60
61 proc deparse {args} {
62 switch -regexp [lindex $args 0] {
63 ^num|str|obj|list$ -
64 default { error "Invalid JSON type [lindex $args 0]" }
65 }
66 return [ eval $args ]
67 }
68 }
69
70 proc deparse_json {data {indentIncr 2}} {
71 set deparse::indentBy 0
72 set deparse::indentIncr $indentIncr
73 if [expr $indentIncr == 0] {
74 set deparse::nl ""
75 } else {
76 set deparse::nl "\n"
77 }
78 namespace inscope deparse eval $data
79 }
80}
81
82puts [ ten::json::deparse_json {
83 list {str foo} {num 0} {obj __remote_object__ {str 512}}
84} 0 ]