@@ 261,7 261,7 @@ structure Json :> JSON = struct
| chkPos (c :: rest) = isDigit c andalso chkPosAfterFirst rest
fun chkNumber (#"-" :: rest) = chkPos rest
- | chkNumber digits = chkPos digits
+ | chkNumber cc = chkPos cc
in
if chkNumber digits
then case Real.fromString (implode digits) of
@@ 328,15 328,28 @@ structure Json :> JSON = struct
fun stringEscape s =
let fun esc x = [x, #"\\"]
fun escape' acc [] = rev acc
- | escape' acc (x :: xs) = escape' (case x of
- #"\"" => esc x @ acc
- | #"\\" => esc x @ acc
- | #"\b" => esc #"b" @ acc
- | #"\f" => esc #"f" @ acc
- | #"\n" => esc #"n" @ acc
- | #"\r" => esc #"r" @ acc
- | #"\t" => esc #"t" @ acc
- | _ => x :: acc) xs
+ | escape' acc (x :: xs) =
+ escape' (case x of
+ #"\"" => esc x @ acc
+ | #"\\" => esc x @ acc
+ | #"\b" => esc #"b" @ acc
+ | #"\f" => esc #"f" @ acc
+ | #"\n" => esc #"n" @ acc
+ | #"\r" => esc #"r" @ acc
+ | #"\t" => esc #"t" @ acc
+ | _ =>
+ let val c = Char.ord x
+ in
+ if c < 0x20
+ then let val hex = Word.toString (Word.fromInt c)
+ in (rev o explode) (if c < 0x10
+ then ("\\u000" ^ hex)
+ else ("\\u00" ^ hex))
+ end @ acc
+ else
+ x :: acc
+ end)
+ xs
in
implode (escape' [] (explode s))
end