Anonymous user
JSON: Difference between revisions
→{{header|Standard ML}}: + generic loop
(→{{header|Standard ML}}: + generic loop) |
|||
Line 3,548:
</pre>
=={{header|Standard ML}}==
Works on Unix/Linux/BSD with jq (github.com/stedolan/jq/ ) installed. Data storage in strings,
<lang Standard ML>
val Validate = fn jsonstring =>
Line 3,580:
end;
local▼
datatype
datatype 'a content = value of 'a | block of ('a,'a content) element list | arr of 'a content list |marker of int ;
exception Dtype of string ;
val unarr = fn arr lst => lst | _ => (raise Dtype "unarr" ; []) ;▼
val unblock = fn block lst => lst | _ => (raise Dtype "unblock" ; []) ;▼
(* --- example loop to apply a function 'dothis', which returns type jvals, to the structure ---- *)
datatype jvals = St of string | It of IntInf.int | Rl of real | Bl of bool ; (* returned type by 'dothis' *)
val rec gothruAndDo = fn dothis => fn storedObject =>
let
val walk = fn elem ( n, value v) => elem (dothis n , value (dothis v) )
| elem ( n, block v) => elem (dothis n , block ( (gothruAndDo dothis) (rev (tl (rev v)))) )
| elem ( n, arr v) => elem (dothis n , arr ( List.map (block o (gothruAndDo dothis) o unblock) (rev (tl (rev v))) ) )
| _ => elem (St "", value (It (IntInf.fromInt ~1)))
in
List.map walk storedObject
end;
(* ------------------------------------ end of loop example ------------------------------------ *)
▲local
exception Dtype of string ;
val markbToInt = fn markerb NrChars => NrChars | _ => (raise Dtype "markerb!" ; ~1) ;
val markToInt = fn marker NrChars => NrChars | _ => (raise Dtype "marker!" ; ~1) ;
▲val unarr = fn arr lst => lst | _ => (raise Dtype "unarr" ; []) ;
▲val unblock = fn block lst => lst | _ => (raise Dtype "unblock" ; []) ;
fun readarr rtag rc = fn #"]"::S => [ marker (List.length S) ] (* process array *)
| S => let val tmp = (rtag rc ("",S)) in (block tmp) ::
( readarr rtag rc ( List.drop (S,(List.length S) - markbToInt ( hd (rev tmp))) )) end ;
Line 3,600 ⟶ 3,620:
val rec readNaVa = fn rc : string * char list -> string content * char list => fn
("",[]) => []
| (sr,[]) => [ elem (sr,
| (sr,#":":: #"["::S) =>
let val tmp = arr (readarr readNaVa rc S) in (*
( elem (sr, tmp )) :: (readNaVa rc ("" , List.drop (S,(List.length S) - (markToInt (hd (rev(unarr tmp)))) ) ))
end
| (sr, #":":: #"{"::S) =>
let val tmp = readNaVa rc ("",S ) in (*
( elem (sr, block tmp)) :: (readNaVa rc ("" , List.drop (S,(List.length S) -(markbToInt ( hd (rev tmp)))) ))
end
Line 3,614 ⟶ 3,634:
| (sr,#"}"::S) => [ markerb (List.length S) ]
| (sr,#":"::S) =>
let val tmp = rc ("",S) in (*
elem ( sr, #1 tmp) :: (readNaVa rc ("", #2 tmp ) )
end
| (sr,#","::S) => readNaVa rc (sr , S)
| (sr,#"{"::a::S) => readNaVa rc (sr^(str a) , S)
| (sr,a::S) => readNaVa rc (sr^(str a) , S) ; (* name field *)
val rec readcontent = fn
(sc,a::[]) => (
| (sc,#","::t) => (
| (sc, #"}"::t) => (
| (sc, #"]"::t) => (
| (sc, a::t) => readcontent( ( sc^(str a) ),t) ;
Line 3,633 ⟶ 3,653:
val rec put = fn
[] => ""
| (elem h)::t => (#1 h) ^ ":" ^ ( ( fn
^ ","
^ (put t)
Line 3,648 ⟶ 3,668:
(Substring.tokens (fn x=> x= tok ) (Substring.full S) )) ) ^ (if tok = #"}" then str tok else "" )
in▼
▲in
val storeJsString = fn input =>
Line 3,658 ⟶ 3,678:
end ;
</lang>Example
<lang Standard ML>
val testString="{\"firstName\":\"John\",\"lastName\":\"Smith\",\"age\":25,\"address\":{\"streetAddress\":\"21 2nd Street\",\"city\":\"New York\",\"state\":\"NY\",\"postalCode\":\"10021\"},\"phoneNumber\":[{\"type\":\"home\",\"numbers\":[{\"o\":\"212 555-1234\",\"h\":\"119 323-1234\"}]},{\"type\":\"fax\",\"number\":\"646 555-4567\"}]}" ;
testString = (writeJS o storeJsString) testString ;
val it = true : bool (* because the test string was unformatted *)
val toMlVal = fn input =>
case String.isPrefix "\"" input
of true => St (String.substring (input,1,(String.size input)-2) )
| _ => case IntInf.fromString input of
SOME n => It n
| NONE => case Real.fromString input of
SOME x => Rl x
| NONE => case Bool.fromString input of
SOME b => Bl b
| NONE => St "" ;
val toMlVal = fn: string -> jvals
List.nth (gothruAndDo toMlVal (storeJsString testString ) ,3);
val it =
elem
(St "address",
block
[elem (St "streetAddress", value (St "21 2nd Street")),
elem (St "city", value (St "New York")),
elem (St "state", value (St "NY")),
elem (St "postalCode", value (St "10021"))]):
(jvals, jvals content) element
</lang>
|