number parsing and nested array
Matt S Trout [Tue, 19 Jun 2012 17:29:53 +0000 (17:29 +0000)]
json.tcl

index f9c9e68..9d382e6 100644 (file)
--- a/json.tcl
+++ b/json.tcl
@@ -114,12 +114,18 @@ namespace eval ten::json {
       }
     }
 
-    proc parse_list {} {
+    proc eat_char {} {
       variable json
       set json [ string range $json 1 end ]
+    }
+
+    proc parse_list {} {
+      variable json
+      eat_char
       set tcl {list}
       while {"$json" ne ""} {
         if {[string index $json 0] eq "]"} {
+          eat_char
           return $tcl
         }
         lappend tcl [ parse ]
@@ -142,6 +148,17 @@ namespace eval ten::json {
       list str [subst -nocommand -novariable [string range $string 1 end-1]]
     }
 
+    proc parse_num {} {
+      variable json
+      string is double -failindex last $json
+      if {$last == 0} {
+        error "Saw number but wasn't - $json"
+      }
+      set num [string range $json 0 [expr {$last - 1}]]
+      set json [string range $json $last end]
+      list num $num
+    }
+
     proc parse {} {
       variable json
       set json [string trimleft $json]
@@ -153,7 +170,7 @@ namespace eval ten::json {
         {\[} { parse_list }
         {\"} { parse_str }
 
-        {[-0-9]} { parse_number }
+        {[-0-9]} { parse_num }
 
         default { error "argh" }
       }
@@ -161,8 +178,12 @@ namespace eval ten::json {
   }
 
   proc parse_json {json} {
-    set parse::json $json
-    parse::parse
+    set parse::json [ string trim $json ]
+    set result [ parse::parse ]
+    if {[string trimleft $parse::json] ne ""} {
+      error "Had JSON left over: $parse::json"
+    }
+    return $result
   }
 }
 
@@ -187,4 +208,4 @@ dict for {k v} [ ten::json::tclify_json [
 
 #puts [ ten::json::parse_json $jtext ]
 
-puts [ ten::json::parse_json {["foo"]} ]
+puts [ ten::json::parse_json {["foo",2345,["bar"]]} ]