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
|
type line =
{ pos_fname : string
; pos_lnum : int
; pos_bol : int
}
type t =
| SameLine of
{ line : line
; cnum_start : int
; offset : int
}
| MultiLine of
{ line_start : line
; cnum_start : int
; line_end : line
; offset : int
}
let filename = function
| SameLine { line = { pos_fname; _ }; _ } -> pos_fname
| MultiLine { line_start = { pos_fname; _ }; _ } -> pos_fname
let line' = function
| SameLine { line; _ } -> line
| MultiLine { line_start; _ } -> line_start
let line_end' = function
| SameLine { line; _ } -> line
| MultiLine { line_end; _ } -> line_end
let cnum = function
| SameLine { cnum_start; _ } -> cnum_start
| MultiLine { cnum_start; _ } -> cnum_start
let line t = (line' t).pos_lnum
let line_end t = (line_end' t).pos_lnum
let column = function
| SameLine { line = { pos_bol; _ }; cnum_start; _ } -> cnum_start - pos_bol
| MultiLine { line_start = { pos_bol; _ }; cnum_start; _ } -> cnum_start - pos_bol
let dummy_line = { pos_fname = "<dumnmy>"; pos_lnum = 0; pos_bol = 0 }
let dummy = SameLine { line = dummy_line; cnum_start = 0; offset = 0 }
let create ?(last_line = dummy_line) (p1 : Lexing.position) (p2 : Lexing.position) : t =
if p1.pos_fname = p2.pos_fname && p1.pos_lnum = p2.pos_lnum && p1.pos_bol = p2.pos_bol
then
let line =
if last_line.pos_fname == p1.pos_fname
&& last_line.pos_lnum = p1.pos_lnum
&& last_line.pos_bol = p1.pos_bol
then last_line
else { pos_fname = p1.pos_fname; pos_lnum = p1.pos_lnum; pos_bol = p1.pos_bol }
in
SameLine { line; cnum_start = p1.pos_cnum; offset = p2.pos_cnum - p1.pos_cnum }
else
let line_start =
{ pos_fname = p1.pos_fname; pos_lnum = p1.pos_lnum; pos_bol = p1.pos_bol }
in
let line_end =
{ pos_fname = p2.pos_fname; pos_lnum = p2.pos_lnum; pos_bol = p2.pos_bol }
in
MultiLine
{ line_start
; cnum_start = p1.pos_cnum
; line_end
; offset = p2.pos_cnum - p1.pos_cnum
}
let p1 : t -> Lexing.position = function
| SameLine { line = { pos_fname; pos_lnum; pos_bol }; cnum_start; offset = _ } ->
{ pos_bol; pos_lnum; pos_fname; pos_cnum = cnum_start }
| MultiLine
{ line_start = { pos_fname; pos_lnum; pos_bol }
; cnum_start
; line_end = _
; offset = _
} -> { pos_bol; pos_lnum; pos_fname; pos_cnum = cnum_start }
let p2 : t -> Lexing.position = function
| SameLine { line = { pos_fname; pos_lnum; pos_bol }; cnum_start; offset } ->
{ pos_bol; pos_lnum; pos_fname; pos_cnum = cnum_start + offset }
| MultiLine
{ line_end = { pos_fname; pos_lnum; pos_bol }; line_start = _; cnum_start; offset }
-> { pos_bol; pos_lnum; pos_fname; pos_cnum = cnum_start + offset }
|