Module B0_sexp.Sexpq

S-expression queries.

Result paths

type path = (Sexp.index * Sexp.loc) list

The type for result paths. This is a sequence of indexing operations tupled with the source text location of the indexed s-expression in reverse order.

val pp_path : ?pp_loc:Sexp.loc Sexp.fmt -> ?pp_key:string Sexp.fmt -> unit -> path Sexp.fmt

pp_path ~pp_loc ~pp_key () formats paths using pp_loc (defaults to Sexp.pp_loc) and pp_key to format the keys (defaults to Sexp.pp_key).

Query errors

type error_kind = [
  1. | `Key_unbound of string * string list
  2. | `Msg of string
  3. | `Nth_unbound of int * int
  4. | `Out_of_dom of string * string * string list
]

The type for kinds of errors.

  • `Key_unbound (k, dom) on k that should have been in dom (if not empty).
  • `Msg m an arbitrary message m (should not include position information).
  • `Nth_unbound (n, len) on n an out of bound index in a list of length len.
  • `Out_of_dom (kind, v, dom) on v of kind kind that should have been in dom
val pp_error_kind : ?pp_em:string Sexp.fmt -> ?pp_key:string Sexp.fmt -> unit -> error_kind Sexp.fmt

pp_error_kind ~pp_loc ~pp_em ~pp_key () formats error kinds using pp_loc for locations, pp_em for emphasis and pp_key for keys.

type error = error_kind * (path * Sexp.loc)

The type for query errors. The error kind tupled with the path to the offending s-expression and the location of the s-expression.

val pp_error : ?pp_loc:Sexp.loc Sexp.fmt -> ?pp_path:path Sexp.fmt -> ?pp_error_kind:error_kind Sexp.fmt -> ?pp_prefix:unit Sexp.fmt -> unit -> error Sexp.fmt

pp_error ~pp_loc ~pp_path ~pp_error_kind ~pp_prefix () formats errors using pp_loc, pp_path (defaults to pp_path), pp_error_kind (defaults to pp_error_kind) and pp_prefix (defaults formats "Error: ").

val error_to_string : ?pp_error:error Sexp.fmt -> ('a, error) Stdlib.result -> ('a, string) Stdlib.result

error_to_string ~pp_error r converts an error in r to a string using pp_error, defaults to pp_error.

Queries

type 'a t

The type for s-expression queries. A query either succeeds against an s-expression with a value of type 'a or it fails.

val query : 'a t -> Sexp.t -> ('a, error) Stdlib.result

query q s is Ok v if the query q succeeds on s and Error e otherwise.

val query_at_path : 'a t -> (Sexp.t * path) -> ('a, error) Stdlib.result

query_at_path q (s, p) is like query except it assumes s is at path p. Use to further query s-expressions obtained with sexp_with_path so that errors return the full path to errors.

val query' : ?pp_error:error Sexp.fmt -> 'a t -> Sexp.t -> ('a, string) Stdlib.result

query' q s is like query except the result is composed with error_to_string.

Success and failure

val succeed : 'a -> 'a t

succeed v is a query that succeeds with value v on any s-expression.

val fail : error_kind -> 'a t

fail k is a query that fails on any s-expression with error kind k.

val failf : ('a, Stdlib.Format.formatter, unit, 'b t) Stdlib.format4 -> 'a

failf fmt ... is fail (`Msg m) with m formatted according to fmt.

Query combinators

val app : ('a -> 'b) t -> 'a t -> 'b t

app fq q queries an s-expression first with fq and then with q and applies the result of latter to the former.

val ($) : ('a -> 'b) t -> 'a t -> 'b t

f $ v is app f v.

val pair : 'a t -> 'b t -> ('a * 'b) t

pair q0 q1 queries an s-expression first with q0 and then with q1 and returns the pair of their result.

val bind : 'a t -> ('a -> 'b t) -> 'b t

bind q f queries an s-expression with q, applies the result to f and re-queries the s-expression with the result.

val map : ('a -> 'b) -> 'a t -> 'b t

map f q is app (succeed f) q.

val some : 'a t -> 'a option t

some q is map Option.some q.

val loc : 'a t -> ('a * (path * Sexp.loc)) t

loc q queries with q an returns the result with the query path and source text location to the queried s-expression.

S-expression queries

Queries for s-expressions. These queries never fail.

val fold : atom:'a t -> list:'a t -> 'a t

fold ~atom ~list queries atoms with atom and lists with list.

val sexp : Sexp.t t

sexp queries any s-expression and returns its generic representation.

val sexp_with_path : (Sexp.t * path) t

sexp_with_path is like sexp but also returns the path toy s-expression.

Atom queries

Queries for atoms. These queries fail on lists.

val atom : string t

atom queries an atom as a string.

val atom_to : kind:string -> (string -> ('a, string) Stdlib.result) -> 'a t

atom_to ~kind p queries an atom and parses it with p. In case of Error m fails with message m. kind is the kind of value parsed, used for the error in case a list is found.

TODO. Maybe combinators to devise an approriate parse function for atom_to are a better idea than the following two combinators.

val enum : kind:string -> Stdlib.Set.Make(Stdlib.String).t -> string t

enum ~kind ss queries an atom for one of the element of ss and fails otherwise. kind is for the kind of elements in ss, it used for error reporting.

val enum_map : kind:string -> 'a Stdlib.Map.Make(Stdlib.String).t -> 'a t

enum_map ~pp_elt ~kind sm queries an atom for it's map in sm and fails if the atom is not bound in sm. kind is for the kind of elements in sm, it used for error reporting.

val bool : bool t

bool queries an atom for one of true or false.

val int : int t

int queries an atom for an integer value parsed with int_of_string.

val int32 : int32 t

int32 queries an atom for an integer value parsed with Int32.of_string.

val int64 : int64 t

int64 queries an atom for an integer value parsed with Int64.of_string.

val float : float t

float queries an atom for a float value parsed with float_of_string.

List queries

Queries for s-expression lists. These queries fail on atoms.

val is_empty : bool t

is_empty queries a list for emptyness.

val hd : 'a t -> 'a t

hd q queries the head of a list with q. Fails on empty lists.

val tl : 'a t -> 'a t

tail q queries the tail of a list with q. Fails on empty lists.

val fold_list : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b t

fold_list f q acc queries the elements of a list from left to right with q and folds the result with f starting with acc.

val list : 'a t -> 'a list t

list q queries the elements of a list with q.

List index queries

val nth : ?absent:'a -> int -> 'a t -> 'a t

nth ?absent n q queries the nth index of a list with q. If n is negative counts from the end of the list, so -1 is the last list element. If the element does not exist this fails if absent is None and succeeds with v if absent is Some v.

val delete_nth : must_exist:bool -> int -> Sexp.t t

delete_nth ~must_exist n deletes the nth element of the list. If the element does not exist this fails when must_exist is true or returns the list unchanged when must_exist is false.

Dictionary queries

Queries for s-expression dictionaries. These queries fail on atoms.

val key : ?absent:'a -> string -> 'a t -> 'a t

key ?absent k q queries the value of key k of a dictionary with q. If k is not bound this fails if absent is None and succeeds with v if absent is Some v.

val delete_key : must_exist:bool -> string -> Sexp.t t

delete_key ~must_exist k deletes key k from the dictionary. If k is not bound this fails when must_exist is true or returns the dictionary unchanged when must_exist is false.

val key_dom : validate:Stdlib.Set.Make(Stdlib.String).t option -> Stdlib.Set.Make(Stdlib.String).t t

key_dom validate queries the key domain of a list of bindings. If validate is Some dom, the query fails if a key is not in dom. The query also fails if a binding is not well-formed. pp_key is used to format keys.

TODO. Not really happy about this function, we lose the key locations which is useful for further deconstruction. Also maybe we rather want binding folds.

val atomic : 'a t -> 'a t

atomic q queries an atom or the atom of a singleton list with q. It fails on empty lists or non-singleton lists.

This is useful for singleton dictionary bindings. In error reporting treats the list as if it doesn't exist syntactically which is the case in dictionary bindings.

Index queries

val index : ?absent:'a -> Sexp.index -> 'a t -> 'a t

index ?absent i q queries the s-expression index i with q using nth or key according to i. Fails on atoms.

val delete_index : must_exist:bool -> Sexp.index -> Sexp.t t

delete_index ~must_exist i deletes the s-expression index i using delete_nth or delete_key according to i.

Path and caret queries

These queries fail on indexing errors, that is if an atom gets indexed.

val path : ?absent:'a -> Sexp.path -> 'a t -> 'a t

path p q queries the s-expression found by p using q. If p can't be found this fails if absent is None and succeeds with v if absent is Some v.

val probe_path : Sexp.path -> (path * Sexp.t * Sexp.path) t

probe_path p is a query that probes for p's existence. Except for indexing errors it always succeeds with (sp, s, rem):

  • If p is found, this is the path to sp to the found expression s and rem is empty.
  • If p is not found, this is the path sp that leads to the s-expression s that could not be indexed and rem has the indexes that could not be performed.
val delete_at_path : must_exist:bool -> Sexp.path -> Sexp.t t

delete_at_path ~must_exist p deletes the s-expression found by p from the queried s-expression. If the path does not exist this fails if must_exist is true and returns the s-expression itself if must_exist is false.

val splice_at_path : ?stub:Sexp.t -> must_exist:bool -> Sexp.path -> rep:Sexp.t -> Sexp.t t

splice_at_path ?stub ~must_exist p ~rep replaces the s-expression found at p by splicing rep. If the path does not exist this fails if must_exist is true and the non-existing part of the path is created if must_exist is false. If elements need to be created stub (defaults to Sexp.atom "") is used.

val splice_at_caret : ?stub:Sexp.t -> must_exist:bool -> Sexp.caret -> rep:Sexp.t -> Sexp.t t

splice_caret ?stub ~must_exist p rep splices the s-expression rep at the caret p of the s-expression. If path of the caret does not exist this fails if must_exist is true and the non-existing part of the path is created if must_exist is false. If atoms need to be create stub (defaults to Sexp.atom "") is used.

OCaml datatype encoding queries

val option : 'a t -> 'a option t

option q queries with q the value of an option represented according the encoding of Sexpg.option.