Source file cst.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
open! Import

type t =
  | Atom of
      { loc : Positions.range
      ; atom : string
      ; unescaped : string option
      }
  | List of
      { loc : Positions.range
      ; elements : t_or_comment list
      }

and t_or_comment =
  | Sexp of t
  | Comment of comment

and comment =
  | Plain_comment of
      { loc : Positions.range
      ; comment : string
      }
  | Sexp_comment of
      { hash_semi_pos : Positions.pos
      ; comments : comment list
      ; sexp : t
      }
[@@deriving_inline sexp_of]

let rec sexp_of_t =
  (function
    | Atom { loc = loc__002_; atom = atom__004_; unescaped = unescaped__006_ } ->
      let bnds__001_ = [] in
      let bnds__001_ =
        let arg__007_ = sexp_of_option sexp_of_string unescaped__006_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "unescaped"; arg__007_ ] :: bnds__001_
      in
      let bnds__001_ =
        let arg__005_ = sexp_of_string atom__004_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "atom"; arg__005_ ] :: bnds__001_
      in
      let bnds__001_ =
        let arg__003_ = Positions.sexp_of_range loc__002_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "loc"; arg__003_ ] :: bnds__001_
      in
      Sexplib0.Sexp.List (Sexplib0.Sexp.Atom "Atom" :: bnds__001_)
    | List { loc = loc__009_; elements = elements__011_ } ->
      let bnds__008_ = [] in
      let bnds__008_ =
        let arg__012_ = sexp_of_list sexp_of_t_or_comment elements__011_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "elements"; arg__012_ ] :: bnds__008_
      in
      let bnds__008_ =
        let arg__010_ = Positions.sexp_of_range loc__009_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "loc"; arg__010_ ] :: bnds__008_
      in
      Sexplib0.Sexp.List (Sexplib0.Sexp.Atom "List" :: bnds__008_)
      : t -> Sexplib0.Sexp.t)

and sexp_of_t_or_comment =
  (function
    | Sexp arg0__013_ ->
      let res0__014_ = sexp_of_t arg0__013_ in
      Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "Sexp"; res0__014_ ]
    | Comment arg0__015_ ->
      let res0__016_ = sexp_of_comment arg0__015_ in
      Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "Comment"; res0__016_ ]
      : t_or_comment -> Sexplib0.Sexp.t)

and sexp_of_comment =
  (function
    | Plain_comment { loc = loc__018_; comment = comment__020_ } ->
      let bnds__017_ = [] in
      let bnds__017_ =
        let arg__021_ = sexp_of_string comment__020_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "comment"; arg__021_ ] :: bnds__017_
      in
      let bnds__017_ =
        let arg__019_ = Positions.sexp_of_range loc__018_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "loc"; arg__019_ ] :: bnds__017_
      in
      Sexplib0.Sexp.List (Sexplib0.Sexp.Atom "Plain_comment" :: bnds__017_)
    | Sexp_comment
        { hash_semi_pos = hash_semi_pos__023_
        ; comments = comments__025_
        ; sexp = sexp__027_
        } ->
      let bnds__022_ = [] in
      let bnds__022_ =
        let arg__028_ = sexp_of_t sexp__027_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "sexp"; arg__028_ ] :: bnds__022_
      in
      let bnds__022_ =
        let arg__026_ = sexp_of_list sexp_of_comment comments__025_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "comments"; arg__026_ ] :: bnds__022_
      in
      let bnds__022_ =
        let arg__024_ = Positions.sexp_of_pos hash_semi_pos__023_ in
        Sexplib0.Sexp.List [ Sexplib0.Sexp.Atom "hash_semi_pos"; arg__024_ ] :: bnds__022_
      in
      Sexplib0.Sexp.List (Sexplib0.Sexp.Atom "Sexp_comment" :: bnds__022_)
      : comment -> Sexplib0.Sexp.t)
;;

[@@@end]

let compare = Caml.compare
let compare_t_or_comment = Caml.compare
let compare_comment = Caml.compare

module Forget = struct
  (* In cps to prevent non-tail recursion.
     The polymorphism in the signature ensures that each function returns
     only through the continuation. *)
  module Cps : sig
    val forget_t : t -> (Sexp.t -> 'r) -> 'r
    val forget_toc : t_or_comment -> (Sexp.t option -> 'r) -> 'r
    val forget_tocs : t_or_comment list -> (Sexp.t list -> 'r) -> 'r
  end = struct
    let rec forget_t t k =
      match t with
      | Atom { atom; _ } -> k (Sexp.Atom atom)
      | List { elements; _ } -> forget_tocs elements (fun xs -> k (Sexp.List xs))

    and forget_tocs tocs k =
      match tocs with
      | [] -> k []
      | toc :: tocs ->
        forget_toc toc (function
          | None -> forget_tocs tocs k
          | Some x -> forget_tocs tocs (fun xs -> k (x :: xs)))

    and forget_toc toc k =
      match toc with
      | Comment _ -> k None
      | Sexp t -> forget_t t (fun x -> k (Some x))
    ;;
  end

  let t x = Cps.forget_t x (fun y -> y)
  let t_or_comment x = Cps.forget_toc x (fun y -> y)
  let t_or_comments x = Cps.forget_tocs x (fun y -> y)
end