Sexp: constructors and Sexp.Traverse (with new functions)

This commit is contained in:
Simon Cruanes 2014-09-18 00:28:58 +02:00
parent 05316f7e38
commit bb070c7f78
2 changed files with 50 additions and 6 deletions

View file

@ -48,6 +48,11 @@ let of_list l = List l
let of_pair (x,y) = List[x;y]
let of_triple (x,y,z) = List[x;y;z]
let of_variant name args = List (Atom name :: args)
let of_field name t = List [Atom name; t]
let of_record l =
List (List.map (fun (n,x) -> of_field n x) l)
let _with_in filename f =
let ic = open_in filename in
try
@ -572,7 +577,7 @@ module Traverse = struct
| Some _ as res -> res
| None -> _list_any f tl
let list_any e f = match e with
let list_any f e = match e with
| Atom _ -> None
| List l -> _list_any f l
@ -583,7 +588,7 @@ module Traverse = struct
| Some y -> _list_all f (y::acc) tl
| None -> _list_all f acc tl
let list_all e f = match e with
let list_all f e = match e with
| Atom _ -> []
| List l -> _list_all f [] l
@ -607,6 +612,25 @@ module Traverse = struct
| List l -> Some l
| Atom _ -> None
let rec _get_field name l = match l with
| List [Atom n; x] :: _ when name=n -> Some x
| _ :: tl -> _get_field name tl
| [] -> None
let get_field name e = match e with
| List l -> _get_field name l
| Atom _ -> None
let rec _get_variant s args l = match l with
| [] -> None
| (s', f) :: _ when s=s' -> f args
| _ :: tl -> _get_variant s args tl
let get_variant l e = match e with
| List (Atom s :: args) -> _get_variant s args l
| List _ -> None
| Atom s -> _get_variant s [] l
let return x = Some x
let (>>=) e f = match e with

View file

@ -50,6 +50,17 @@ val of_unit : t
val of_pair : t * t -> t
val of_triple : t * t * t -> t
val of_variant : string -> t list -> t
(** [of_variant name args] is used to encode algebraic variants
into a S-expr. For instance [of_variant "some" (of_int 1)]
represents the value [Some 1] *)
val of_field : string -> t -> t
(** Used to represent one record field *)
val of_record : (string * t) list -> t
(** Represent a record by its named fields *)
(** {2 Serialization (encoding)} *)
val to_buf : Buffer.t -> t -> unit
@ -213,12 +224,12 @@ end
(** {6 Traversal of S-exp} *)
module Traverse : sig
val list_any : t -> (t -> 'a option) -> 'a option
(** [list_any (List l) f] tries [f x] for every element [x] in [List l],
val list_any : (t -> 'a option) -> t -> 'a option
(** [list_any f (List l)] tries [f x] for every element [x] in [List l],
and returns the first non-None result (if any). *)
val list_all : t -> (t -> 'a option) -> 'a list
(** [list_all (List l) f] returns the list of all [y] such that [x] in [l]
val list_all : (t -> 'a option) -> t -> 'a list
(** [list_all f (List l)] returns the list of all [y] such that [x] in [l]
and [f x = Some y] *)
val to_int : t -> int option
@ -233,6 +244,15 @@ module Traverse : sig
val to_triple : t -> (t * t * t) option
val get_field : string -> t -> t option
(** [get_field name e], when [e = List [(n1,x1); (n2,x2) ... ]], extracts
the [xi] such that [name = ni], if it can find it. *)
val get_variant : (string * (t list -> 'a option)) list -> t -> 'a option
(** [get_variant l e] checks whether [e = List (Atom s :: args)], and
if some pair of [l] is [s, f]. In this case, it calls [f args]
and returns its result, otherwise it returns None. *)
val (>>=) : 'a option -> ('a -> 'b option) -> 'b option
val return : 'a -> 'a option