package sexplib

  1. Overview
  2. Docs

Source file sexp_intf.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
(** Sexp_intf: interface specification for handling S-expressions (I/O, etc.) *)

open Format
open Bigarray

module type S = sig
  (** Type of S-expressions *)
  type t = Type.t =
    | Atom of string
    | List of t list

  (** Type of bigstrings *)
  type bigstring = (char, int8_unsigned_elt, c_layout) Array1.t

  val compare : t -> t -> int
  val equal : t -> t -> bool

  (** {6 Defaults} *)

  (** [default_indent] reference to default indentation level for
      human-readable conversions.  Initialisation value: 2. *)
  val default_indent : int ref

  (** {6 S-expression size} *)

  (** [size sexp] @return [(n_atoms, n_chars)], where [n_atoms] is
      the number of atoms in S-expression [sexp], and [n_chars] is the
      number of characters in the atoms of the S-expression. *)
  val size : t -> int * int

  (** {6 Scan functions} *)

  (** [scan_sexp ?buf lexbuf] scans an S-expression from lex buffer
      [lexbuf] using the optional string buffer [buf] for storing
      intermediate strings. *)
  val scan_sexp : ?buf:Buffer.t -> Lexing.lexbuf -> t

  (** [scan_sexps ?buf lexbuf] reads a list of S-expressions from lex buffer [lexbuf]
      using the optional string buffer [buf] for storing intermediate strings. *)
  val scan_sexps : ?buf:Buffer.t -> Lexing.lexbuf -> t list

  (** [scan_rev_sexps ?buf lexbuf] same as {!scan_sexps}, but returns the
      reversed list and is slightly more efficient. *)
  val scan_rev_sexps : ?buf:Buffer.t -> Lexing.lexbuf -> t list

  (** [scan_sexp_opt ?buf lexbuf] is equivalent to [scan_sexp ?buf lexbuf]
      except that it returns [None] when the eof is reached. *)
  val scan_sexp_opt : ?buf:Buffer.t -> Lexing.lexbuf -> t option

  (** [scan_iter_sexps ?buf ~f lexbuf] iterates over all S-expressions scanned from
      lex buffer [lexbuf] using function [f], and the optional string buffer [buf] for
      storing intermediate strings. *)
  val scan_iter_sexps : ?buf:Buffer.t -> f:(t -> unit) -> Lexing.lexbuf -> unit

  (** [scan_fold_sexps ?buf ~f ~init lexbuf] folds over all S-expressions scanned from lex
      buffer [lexbuf] using function [f], initial state [init], and the optional string
      buffer [buf] for storing intermediate strings. *)
  val scan_fold_sexps
    :  ?buf:Buffer.t
    -> f:('a -> t -> 'a)
    -> init:'a
    -> Lexing.lexbuf
    -> 'a

  (** [scan_sexps_conv ?buf ~f lexbuf] maps all S-expressions scanned from lex buffer
      [lexbuf] to some list using function [f], and the optional string buffer [buf] for
      storing intermediate strings. *)
  val scan_sexps_conv : ?buf:Buffer.t -> f:(t -> 'a) -> Lexing.lexbuf -> 'a list

  (** {6 Type and exception definitions for (partial) parsing} *)

  module Parse_pos : sig
    (** Position information after complete parse *)
    type t = Pre_sexp.Parse_pos.t = private
      { mutable text_line : int (** Line position in parsed text *)
      ; mutable text_char : int (** Character position in parsed text *)
      ; mutable global_offset : int (** Global/logical offset *)
      ; mutable buf_pos : int (** Read position in string buffer *)
      }

    (** [create ?text_line ?text_char ?buf_pos ?global_offset ()] @return
        a parse position with the given parameters.

        @param text_line default = [1]
        @param text_char default = [0]
        @param global_offset default = [0]
        @param buf_pos default = [0]
    *)
    val create
      :  ?text_line:int
      -> ?text_char:int
      -> ?buf_pos:int
      -> ?global_offset:int
      -> unit
      -> t

    (** [with_buf_pos t pos] @return a copy of the parse position [t] where
        [buf_pos] is set to [pos]. *)
    val with_buf_pos : t -> int -> t
  end

  module Cont_state : sig
    (** State of parser continuations *)
    type t = Pre_sexp.Cont_state.t =
      | Parsing_toplevel_whitespace
      | Parsing_nested_whitespace
      | Parsing_atom
      | Parsing_list
      | Parsing_sexp_comment
      | Parsing_block_comment

    (** [to_string cont_state] converts state of parser continuation
        [cont_state] to a string. *)
    val to_string : t -> string
  end

  (** Type of result from calling {!Sexp.parse}. *)
  type ('a, 't) parse_result = ('a, 't) Pre_sexp.parse_result =
    | Done of 't * Parse_pos.t
        (** [Done (t, parse_pos)] finished parsing
        an S-expression.  Current parse position
        is [parse_pos]. *)
    | Cont of Cont_state.t * ('a, 't) parse_fun
        (** [Cont (cont_state, parse_fun)] met the end of input before completely
        parsing an S-expression.  The user has to call [parse_fun] to
        continue parsing the S-expression in another buffer.  [cont_state]
        is the current parsing state of the continuation.
        NOTE: the continuation may only be called once and will raise
        [Failure] otherwise! *)

  (** Type of parsing functions with given offsets and lengths. *)
  and ('a, 't) parse_fun = pos:int -> len:int -> 'a -> ('a, 't) parse_result

  (** Module for parsing S-expressions annotated with location information *)
  module Annotated : sig
    (** Position information for annotated S-expressions *)
    type pos = Pre_sexp.Annotated.pos =
      { line : int
      ; col : int
      ; offset : int
      }

    (** Range information for annotated S-expressions *)
    type range = Pre_sexp.Annotated.range =
      { start_pos : pos
      ; end_pos : pos
      }

    (** S-expression annotated with location information *)
    type t = Pre_sexp.Annotated.t =
      | Atom of range * Type.t
      | List of range * t list * Type.t

    (** Type of conversion results of annotated S-expressions. *)
    type 'a conv =
      [ `Result of 'a
      | `Error of exn * t
      ]

    val sexp_of_conv : ('a -> Type.t) -> 'a conv -> Type.t

    (** Exception associated with conversion errors.  First argument describes
        the location, the second the reason. *)
    exception Conv_exn of string * exn

    (** Stack used by annotation parsers *)
    type stack = Pre_sexp.Annotated.stack =
      { mutable positions : pos list
      ; mutable stack : t list list
      }

    (** [get_sexp annot_sexp] @return S-expression associated with annotated
        S-expression [annot_sexp]. *)
    val get_sexp : t -> Type.t

    (** [get_range annot_sexp] @return the range associated with annotated
        S-expression [annot_sexp]. *)
    val get_range : t -> range

    (** [find_sexp annot_sexp sexp] @return [Some res] where [res] is the
        annotated S-expression that is physically equivalent to [sexp] in
        [annot_sexp], or [None] if there is no such S-expression. *)
    val find_sexp : t -> Type.t -> t option

    (** {6 Annotated (partial) parsing} *)

    (** [parse ?parse_pos ?len str] same as {!parse}, but returns an
        S-expression annotated with location information. *)
    val parse : ?parse_pos:Parse_pos.t -> ?len:int -> string -> (string, t) parse_result

    (** [parse_bigstring ?parse_pos ?len str] same as {!parse_bigstring},
        but returns an S-expression annotated with location information. *)
    val parse_bigstring
      :  ?parse_pos:Parse_pos.t
      -> ?len:int
      -> bigstring
      -> (bigstring, t) parse_result

    (** [input_sexp ?parse_pos ic] like {!input_sexp}, but returns an
        annotated S-expression instead. *)
    val input_sexp : ?parse_pos:Parse_pos.t -> in_channel -> t

    (** [input_sexps ?parse_pos ?buf ic] like {!input_sexps}, but returns
        a list of annotated S-expressions. *)
    val input_sexps : ?parse_pos:Parse_pos.t -> ?buf:bytes -> in_channel -> t list

    (** [input_sexps ?parse_pos ?buf ic] like {!input_rev_sexps}, but
        returns a list of annotated S-expressions. *)
    val input_rev_sexps : ?parse_pos:Parse_pos.t -> ?buf:bytes -> in_channel -> t list

    (** {6 Loading of annotated S-expressions} *)

    (** NOTE: these functions should only be used if an annotated S-expression
        is required. *)

    (** [load_sexp ?strict ?buf file] like {!load_sexp}, but returns an
        annotated S-expression. *)
    val load_sexp : ?strict:bool -> ?buf:bytes -> string -> t

    (** [load_sexps ?buf file] like {!load_sexps}, but returns a list of
        annotated S-expressions. *)
    val load_sexps : ?buf:bytes -> string -> t list

    (** [load_rev_sexps ?buf file] like {!load_rev_sexps}, but returns a
        list of annotated S-expressions. *)
    val load_rev_sexps : ?buf:bytes -> string -> t list

    (** {6 String and bigstring conversions} *)

    (** [of_string str] same as {!of_string}, but returns an annotated
        S-expression. *)
    val of_string : string -> t

    (** [of_string_many] same as {!of_string_many}, but returns a list of annotated
        S-expressions.

        Similar to {!of_string_many}, on parse failure it raises [Parsexp.Parse_error]
        rather than a native [Sexplib.Sexp.Parse_error]. *)
    val of_string_many : string -> t list

    (** [of_bigstring bstr] same as {!of_string}, but operates on bigstrings. *)
    val of_bigstring : bigstring -> t

    (** Converters using annotations for determining error locations *)

    (** [conv f annot_sexp] converts the S-expression associated with
        annotated S-expression [annot_sexp] using [f].  @return [`Result
        res] on success, or [`Error (exn, sub_annot_sexp)] otherwise, where
        [exn] is the exception associated with the conversion error, and
        [sub_annot_sexp] is the annotated S-expression on which conversion
        failed. *)
    val conv : (Type.t -> 'a) -> t -> 'a conv

    (** [get_conv_exn ~file ~exc annot_sexp] @return the exception that
        would be raised for a given [file] and exception [exc]
        if conversion had failed on annotated S-expression [annot_sexp].
        The format of the exception message is "file:line:col" *)
    val get_conv_exn : file:string -> exc:exn -> t -> exn
  end

  (** Type of state maintained during parsing *)
  type 't parse_state = 't Pre_sexp.parse_state = private
    { parse_pos : Parse_pos.t (** Current parse position *) }

  (** Type of parse errors *)
  type parse_error = Pre_sexp.parse_error =
    { err_msg : string (** Reason why parsing failed *)
    ; parse_state :
        [ `Sexp of t list list parse_state | `Annot of Annotated.stack parse_state ]
        (** State of parser *)
    }

  (** Exception raised during partial parsing *)
  exception Parse_error of parse_error

  (** {6 Unannotated (partial) parsing} *)

  (** [parse ?parse_pos ?len str] (partially) parses an S-expression in string buffer
      [str] starting out with position information provided in [parse_pos] and reading at
      most [len] characters.  To parse a single atom that is not delimited by whitespace
      it is necessary to call this function a second time with the returned continuation,
      and a dummy buffer that contains whitespace.

      [parse] starts parsing [str] at position [parse_pos.buf_pos].  Each subsequent
      [parse_fun] from a [Cont] uses the [buf] and [pos] that is supplied to it.  The
      final [parse_fun] that returns [Done] mutates the [buf_pos] in the originally
      supplied [parse_pos], and then returns it.

      @param parse_pos default = [Parse_pos.create ()]
      @param len default = [String.length str - parse_pos.Parse_pos.buf_pos]
  *)
  val parse : ?parse_pos:Parse_pos.t -> ?len:int -> string -> (string, t) parse_result

  (** [parse_bigstring ?parse_pos ?len str] same as {!parse}, but operates on
      bigstrings. *)
  val parse_bigstring
    :  ?parse_pos:Parse_pos.t
    -> ?len:int
    -> bigstring
    -> (bigstring, t) parse_result

  (** [input_sexp ?parse_pos ic] parses an S-expression from input channel
      [ic] using initial position information in [parse_pos].  NOTE: this
      function is not as fast on files as {!Sexp.load_sexp}, and is also
      slightly slower than the scan-functions.  But it is guaranteed that
      [input_sexp] is only going to read data parseable as an S-expression.
      Thus, subsequent input functions will see the data immediately
      following it.

      @param parse_pos default = [Parse_pos.create ()]
  *)
  val input_sexp : ?parse_pos:Parse_pos.t -> in_channel -> t

  (** [input_sexps ?parse_pos ?buf ic] parses
      S-expressions from input channel [ic] until EOF is reached.  Faster than
      the scan-functions.

      @param parse_pos default = [Parse_pos.create ()]
  *)
  val input_sexps : ?parse_pos:Parse_pos.t -> ?buf:bytes -> in_channel -> t list

  (** [input_rev_sexps ?parse_pos ?buf ic] same as {!Sexp.input_sexps},
      but returns a reversed list of S-expressions, which is slightly more
      efficient. *)
  val input_rev_sexps : ?parse_pos:Parse_pos.t -> ?buf:bytes -> in_channel -> t list

  (** {6 Loading of (converted) S-expressions} *)

  (** [load_sexp ?strict ?buf file] reads one S-expression from [file] using
      buffer [buf] for storing intermediate data.  Faster than the
      scan-functions.

      @raise Parse_error if the S-expression is unparseable.

      @raise Failure if parsing reached the end of file before one S-expression
      could be read.

      @raise Failure if [strict] is true and there is more than one
      S-expression in the file.

      @param strict default = [true]
  *)
  val load_sexp : ?strict:bool -> ?buf:bytes -> string -> t

  (** [load_sexps ?buf file] reads a list of S-expressions
      from [file] using buffer [buf] for storing intermediate data.
      Faster than the scan-functions.

      @raise Parse_error if there is unparseable data in the file.

      @raise Failure if parsing reached the end of file before the last
      S-expression could be fully read.
  *)
  val load_sexps : ?buf:bytes -> string -> t list

  (** [load_rev_sexps ?buf file] same as {!Sexp.load_sexps}, but returns a
      reversed list of S-expressions, which is slightly more efficient. *)
  val load_rev_sexps : ?buf:bytes -> string -> t list

  (** [load_sexp_conv ?strict ?buf file f] like {!Sexp.load_sexp}, but
      performs a conversion on the fly using [f].  Performance is equivalent
      to executing {!Sexp.load_sexp} and performing conversion when there
      are no errors.  In contrast to the plain S-expression loader, this
      function not only performs the conversion, it will give exact error
      ranges for conversion errors.

      @raise Parse_error if there is unparseable data in the file.

      @raise Failure if parsing reached the end of file before the last
      S-expression could be fully read.
  *)
  val load_sexp_conv
    :  ?strict:bool
    -> ?buf:bytes
    -> string
    -> (t -> 'a)
    -> 'a Annotated.conv

  (** [load_sexp_conv_exn ?strict ?buf file f] like {!load_sexp_conv},
      but returns the converted value or raises [Of_sexp_error] with exact
      location information in the case of a conversion error. *)
  val load_sexp_conv_exn : ?strict:bool -> ?buf:bytes -> string -> (t -> 'a) -> 'a

  (** [load_sexps_conv ?buf file f] like {!Sexp.load_sexps}, but performs
      a conversion on the fly using [f].  Performance is equivalent to
      executing {!Sexp.load_sexps} and performing conversion when there
      are no errors.  In contrast to the plain S-expression loader, this
      function not only performs the conversion, it will give exact error
      ranges for conversion errors.

      @raise Parse_error if there is unparseable data in the file.

      @raise Failure if parsing reached the end of file before the last
      S-expression could be fully read.
  *)
  val load_sexps_conv : ?buf:bytes -> string -> (t -> 'a) -> 'a Annotated.conv list

  (** [load_sexps_conv_exn ?buf file f] like {!load_sexps_conv}, but returns
      the converted value or raises [Of_sexp_error] with exact location
      information in the case of a conversion error. *)
  val load_sexps_conv_exn : ?buf:bytes -> string -> (t -> 'a) -> 'a list

  (** {6 Output of S-expressions to I/O-channels} *)

  (** NOTE: for performance reasons these output functions may need to
      allocate large strings to write out huge S-expressions.  This may
      cause problems on 32-bit platforms.  If you think that you may need to
      write huge S-expressions on such platforms, you might want to use the
      pretty-printers that write to formatters instead (see further below). *)

  (** [output_hum oc sexp] outputs S-expression [sexp] to output channel
      [oc] in human readable form. *)
  val output_hum : out_channel -> t -> unit

  (** [output_hum_indent indent oc sexp] outputs S-expression [sexp]
      to output channel [oc] in human readable form using indentation level
      [indent].
  *)
  val output_hum_indent : int -> out_channel -> t -> unit

  (** [output_mach oc sexp] outputs S-expression [sexp] to output channel
      [oc] in machine readable (i.e. most compact) form. *)
  val output_mach : out_channel -> t -> unit

  (** [output oc sexp] same as [output_mach]. *)
  val output : out_channel -> t -> unit

  (** {6 Output of S-expressions to file} *)

  (** All save-functions write to a temporary file before moving it into
      place to avoid intermittent garbling of existing files, which may
      cause problems for other processes that try to read. *)

  (** [save_hum ?perm file sexp] outputs S-expression [sexp] to [file] in human
      readable form.

      @param perm default = umask
  *)
  val save_hum : ?perm:int -> string -> t -> unit

  (** [save_mach ?perm file sexp] outputs S-expression [sexp] to [file]
      in machine readable (i.e. most compact) form.

      @param perm default = umask
  *)
  val save_mach : ?perm:int -> string -> t -> unit

  (** [save ?perm file sexp] same as {!save_mach}. *)
  val save : ?perm:int -> string -> t -> unit

  (** [save_sexps_hum ?perm file sexps] outputs S-expression list [sexps] to
      [file] in human readable form, each sexp being followed by a newline.

      @param perm default = umask
  *)
  val save_sexps_hum : ?perm:int -> string -> t list -> unit

  (** [save_sexps_mach ?perm file sexps] outputs S-expression list [sexps] to
      [file] in machine readable form, each sexp being followed by a
      newline.

      @param perm default = umask
  *)
  val save_sexps_mach : ?perm:int -> string -> t list -> unit

  (** [save_sexps ?perm file sexp] same as {!save_sexps_mach}. *)
  val save_sexps : ?perm:int -> string -> t list -> unit

  (** {6 Output of S-expressions to formatters} *)

  (** [pp_hum ppf sexp] outputs S-expression [sexp] to formatter [ppf]
      in human readable form. *)
  val pp_hum : formatter -> t -> unit

  (** [pp_hum_indent n ppf sexp] outputs S-expression [sexp] to formatter
      [ppf] in human readable form and indentation level [n]. *)
  val pp_hum_indent : int -> formatter -> t -> unit

  (** [pp_mach ppf sexp] outputs S-expression [sexp] to formatter [ppf]
      in machine readable (i.e. most compact) form. *)
  val pp_mach : formatter -> t -> unit

  (** [pp ppf sexp] same as [pp_mach]. *)
  val pp : formatter -> t -> unit

  (** {6 String and bigstring conversions} *)

  (** Module encapsulating the exception raised by string converters when
      type conversions fail. *)
  module Of_string_conv_exn : sig
    type t =
      { exc : exn
      ; sexp : Type.t
      ; sub_sexp : Type.t
      }

    exception E of t
  end

  (** [of_string str] parses a string [str] as an S-expression. *)
  val of_string : string -> t

  (** [of_string_many] parses a string containing zero or more S-expressions.

      Unlike many other functions in this module, on parse failure it raises
      [Parsexp.Parse_error] rather than a native [Sexplib.Sexp.Parse_error].
  *)
  val of_string_many : string -> t list

  (** [of_string_conv str conv] like {!of_string}, but performs type conversion
      with [conv].  @return conversion result. *)
  val of_string_conv : string -> (t -> 'a) -> 'a Annotated.conv

  (** [of_string_many_conv_exn str conv] like {!of_string_many}, but performs type
      conversion with [conv]. Raises if type conversion fails.

      Unlike many other functions in this module, on parse failure it raises
      [Parsexp.Parse_error] rather than a native [Sexplib.Sexp.Parse_error].

      It still raises [Sexplib.Sexp.Of_string_conv_exn] on sexp conversion errors.

      @return conversion result. *)
  val of_string_many_conv_exn : string -> (t -> 'a) -> 'a list

  (** [of_string_conv_exn str conv] like {!of_string_conv}, but raises
      {!Of_string_conv_exn.E} if type conversion fails.  @return converted
      value. *)
  val of_string_conv_exn : string -> (t -> 'a) -> 'a

  (** [of_bigstring bstr] same as {!of_string}, but operates on bigstrings. *)
  val of_bigstring : bigstring -> t

  (** [of_bigstring_conv bstr conv] like {!of_bigstring}, but performs
      type conversion with [conv].  @return conversion result. *)
  val of_bigstring_conv : bigstring -> (t -> 'a) -> 'a Annotated.conv

  (** [of_bigstring_conv_exn bstr conv] like {!of_bigstring_conv}, but raises
      {!Of_string_conv_exn.E} if type conversion fails.  @return converted
      value. *)
  val of_bigstring_conv_exn : bigstring -> (t -> 'a) -> 'a

  (** [to_string_hum ?indent sexp] converts S-expression [sexp] to a
      string in human readable form with indentation level [indent].

      @param indent default = [!default_indent]
  *)
  val to_string_hum : ?indent:int -> t -> string

  (** [to_string_mach sexp] converts S-expression [sexp] to a string in
      machine readable (i.e. most compact) form. *)
  val to_string_mach : t -> string

  (** [to_string sexp] same as [to_string_mach]. *)
  val to_string : t -> string

  (** {6 Buffer conversions} *)

  (** [to_buffer_hum ~buf ?indent sexp] outputs the S-expression [sexp]
      converted to a string in human readable form to buffer [buf].

      @param indent default = [!default_indent]
  *)
  val to_buffer_hum : buf:Buffer.t -> ?indent:int -> t -> unit

  (** [to_buffer_mach ~buf sexp] outputs the S-expression [sexp] converted
      to a string in machine readable (i.e. most compact) form to buffer [buf].
  *)
  val to_buffer_mach : buf:Buffer.t -> t -> unit

  (** [to_buffer ~buf sexp] same as {!to_buffer_mach}. *)
  val to_buffer : buf:Buffer.t -> t -> unit

  (** [to_buffer_gen ~buf ~add_char ~add_string sexp] outputs the S-expression
      [sexp] converted to a string to buffer [buf] using the output functions
      [add_char] and [add_string]. *)
  val to_buffer_gen
    :  buf:'buffer
    -> add_char:('buffer -> char -> unit)
    -> add_string:('buffer -> string -> unit)
    -> t
    -> unit

  (** {6 Utilities for automated type conversions} *)

  (** [unit] the unit-value as expressed by an S-expression. *)
  val unit : t

  val is_unit : t -> bool

  (** [sexp_of_t sexp] maps S-expressions which are part of a type with
      automated S-expression conversion to themselves. *)
  val sexp_of_t : t -> t

  (** [t_of_sexp sexp] maps S-expressions which are part of a type with
      automated S-expression conversion to themselves. *)
  val t_of_sexp : t -> t

  val t_sexp_grammar : t Sexplib0.Sexp_grammar.t

  (** {6 Utilities for conversion error handling} *)

  (** Type of successful search results.  [`Found] means that an
      S-expression was found at the immediate position, and [`Pos (pos,
      found)] indicates that it was found at position [pos] within a
      structure (= S-expression list) where [found] describes recursively
      where it was found in that structure. *)
  type found =
    [ `Found
    | `Pos of int * found
    ]

  (** Type of search results.  [`Not_found] means that an
      S-expression was not found within another S-expression. *)
  type search_result =
    [ `Not_found
    | found
    ]

  (** [search_physical sexp ~contained] @return the search result
      indicating whether, and if, where the S-expression [contained]
      was found within S-expression [sexp]. *)
  val search_physical : t -> contained:t -> search_result

  (** [subst_found sexp ~subst found] @return the S-expression that
      results from substituting [subst] within S-expression [sexp]
      at the location described by [found]. *)
  val subst_found : t -> subst:t -> found -> t

  (** S-expressions annotated with relative source positions and comments *)
  module With_layout : sig
    (* relative source positions *)
    type pos = Src_pos.Relative.t =
      { row : int
      ; col : int
      }

    val sexp_of_pos : pos -> Type.t

    (** S-expressions annotated with relative source positions and comments. All the
        positions are relative to the opening paren of the enclosing list, or the first
        character of the file. *)
    type t = Type_with_layout.t =
      | Atom of pos * string * string option (* second is quoted representation *)
      | List of pos * t_or_comment list * pos

    (* positions of left and right parens *)
    and t_or_comment = Type_with_layout.t_or_comment =
      | Sexp of t
      | Comment of comment

    and comment = Type_with_layout.comment =
      | Plain_comment of pos * string (* line or block comment *)
      | Sexp_comment of pos * comment list * t

    (* position of #; *)

    val sexp_of_t : t -> Type.t
    val sexp_of_comment : comment -> Type.t
    val sexp_of_t_or_comment : t_or_comment -> Type.t

    module Forget : sig
      val t : t -> Type.t
      val t_or_comment : t_or_comment -> Type.t option
      val t_or_comments : t_or_comment list -> Type.t list
    end

    module Render : sig
      type asexp
      type 'a t (* monad for position-respecting asexp rendering *)

      val return : 'a -> 'a t
      val bind : 'a t -> f:('a -> 'b t) -> 'b t
      val sexp : asexp -> unit t (* assumes that positions in [asexp] are relative *)
      val run : (char -> unit) -> unit t -> unit
    end
    with type asexp := t_or_comment

    module Parser : sig
      type token

      val sexp : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> t_or_comment
      val sexp_opt : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> t_or_comment option
      val sexps : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> t_or_comment list
      val rev_sexps : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> t_or_comment list

      (* for debugging only, cannot be used otherwise anyway *)
      val sexps_abs
        :  (Lexing.lexbuf -> token)
        -> Lexing.lexbuf
        -> Type_with_layout.Parsed.t_or_comment list
    end

    module Lexer : sig
      val main : ?buf:Buffer.t -> Lexing.lexbuf -> Parser.token
    end
  end
end
OCaml

Innovation. Community. Security.