package grace

  1. Overview
  2. Docs
A fancy diagnostics library that allows your compilers to exit with grace

Install

Dune Dependency

Authors

Maintainers

Sources

grace-0.2.0.tbz
sha256=821df54882c9253eac69f47bcf3a71ffdc61c77fdae42587c32aada5b56cfeae
sha512=007afa83251da3ddecd874e120ea89dce0253c387a64a5fece69069d3486ec5eb6c82d6bf0febaf23dd322bd9eaadc2f7882e33f05a2e1fa18a41294e7dc3ba1

doc/src/grace/range.ml.html

Source file range.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
open Import
open Index

module T = struct
  type t =
    { start : Byte_index.t
    ; stop : Byte_index.t
    ; source : Source.t
    }
  [@@deriving equal, hash, sexp]

  let compare t1 t2 =
    let start_cmp = Byte_index.compare t1.start t2.start in
    if start_cmp = 0 then Byte_index.compare t1.stop t2.stop else start_cmp
  ;;
end

include T
include Comparable.Make (T)

let check_invariants { start; stop; source } =
  (* 0 <= start <= stop <= eof *)
  if Byte_index.(start > stop)
  then
    invalid_argf
      "range start %a is greater than range stop %a"
      Byte_index.pp
      start
      Byte_index.pp
      stop
      ();
  let eos = Source.length source in
  if Byte_index.(stop > of_int eos)
  then
    invalid_argf
      "range beyond end of source; stop = %a > %d = eos"
      Byte_index.pp
      stop
      eos
      ()
;;

let invariant t =
  Invariant.invariant [%here] t [%sexp_of: t] (fun () -> check_invariants t)
;;

let pp ppf { start; stop; source = _ } =
  Format.fprintf ppf "[%a, %a)" Byte_index.pp start Byte_index.pp stop
;;

let create ~source start stop =
  let t = { start; stop; source } in
  check_invariants t;
  t
;;

let initial source = create ~source Byte_index.initial Byte_index.initial

let eos source =
  let eos_index = Byte_index.of_int @@ Source.length source in
  create ~source eos_index eos_index
;;

let[@inline] source t = t.source
let[@inline] start t = t.start
let[@inline] stop t = t.stop
let[@inline] split t = t.start, t.stop

let merge t1 t2 =
  assert (Source.equal t1.source t2.source);
  let start = Byte_index.min t1.start t2.start in
  let stop = Byte_index.max t1.stop t2.stop in
  { start; stop; source = t1.source }
;;

let inter t1 t2 =
  assert (Source.equal t1.source t2.source);
  let start = Byte_index.max t1.start t2.start in
  let stop = Byte_index.min t1.stop t2.stop in
  { start; stop; source = t1.source }
;;

let are_disjoint t1 t2 =
  assert (Source.equal t1.source t2.source);
  let first, last = if Byte_index.(t1.stop < t2.stop) then t1, t2 else t2, t1 in
  Byte_index.(first.stop <= last.start)
;;

let contains { start; stop; _ } elem = Byte_index.(start <= elem && elem < stop)

let of_lex ?source (start, stop) =
  let source = Option.value source ~default:(`File start.Lexing.pos_fname) in
  create ~source (Byte_index.of_lex start) (Byte_index.of_lex stop)
;;

let of_lexbuf ?source lexbuf =
  let source = Option.value source ~default:(`File lexbuf.Lexing.lex_curr_p.pos_fname) in
  create
    ~source
    (Byte_index.of_int @@ Lexing.lexeme_start lexbuf)
    (Byte_index.of_int @@ Lexing.lexeme_end lexbuf)
;;
OCaml

Innovation. Community. Security.