module Pass_square_rec = (* Utilities lens *) let dels (s:string) = del s s (************************************************************************ * Recursive square lens *************************************************************************) (* test square with left and right as dels *) let lr (body:lens) = let k = key "c" . body* in let d = dels "ab" in [ square d k d ] let rec lr2 = lr lr2 test lr2 get "abcabcabab" = { "c" { "c" } } let open_tag = key /[a-z]+/ let close_tag = del /[a-z]+/ "a" (* Basic element *) let xml_element (body:lens) = let g = del ">" ">" . body . del "" ">" ] * let rec xml_rec = xml_element xml_rec test xml_rec get "" = { "a" { "b" { "c" { "d" { "e" } } } } } test xml_rec get "" = { "a" { "b" } { "c" } { "d" } { "e" } } test xml_rec put "" after clear "/x/y/z" = "" (* mismatch tag *) test xml_rec get "" = * test xml_rec get "" = * test xml_rec get "" = * (* test ctype_nullable and typecheck *) let rec z = let k = key "ab" in let d = dels "ab" in [ square k z? d ] test z get "abab" = { "ab" } (* test tip handling when using store inside body *) let c (body:lens) = let sto = store "c" . body* in let d = dels "ab" in let k = key "ab" in [ square k sto d ] let rec cc = c cc test cc get "abcabcabab" = { "ab" = "c" { "ab" = "c" } } (* test mixing regular and recursive lenses *) let reg1 = let k = key "y" in let d = dels "y" in let e = dels "" in [ square k e d ] let reg2 = let k = key "y" in let d = dels "y" in [ square k reg1 d ] let rec rec2 = let d1 = dels "x" in let k1 = key "x" in let body = reg2 | rec2 in [ square k1 body d1 ]? test rec2 get "xyyyyx" = { "x" { "y" { "y" } } } test rec2 put "" after clear "/x/y/y" = "xyyyyx" (* test correct put behavior *) let input3 = "aaxyxbbaaaxyxbb" let b3 = dels "y" let sqr3 = let k = key /[x]/ in let d = dels "x" in [ del /[a]*/ "a" . square k b3 d . del /[b]*/ "b" ]* test sqr3 get input3 = { "x" }{ "x" } test sqr3 put input3 after clear "/x[1]" = input3 let b4 = dels "x" let rec sqr4 = let k = key /[b]|[c]/ in let d = del /[b]|[c]/ "b" in [ del /[a]+/ "a" . square k (b4|sqr4) d ] test sqr4 put "aabaaacxcb" after rm "x" = "aabaaacxcb" (* test concat multiple squares *) let rex = /[a-z]/ let rec csqr = let k = key rex in let d = del rex "a" in let e = dels "" in [ square k e d . csqr* . square d e d ] test csqr get "aabbccdd" = { "a" { "b" } } test csqr put "aabbccdd" after clear "/a" = "aabbccdd" test csqr put "aabb" after clear "/a/z" = "aazzaabb"