Skip to content

Commit

Permalink
Merge pull request #7 from Armael/pos_to
Browse files Browse the repository at this point in the history
Add Position.{to_offset,to_lexing}
  • Loading branch information
Armael authored May 30, 2022
2 parents 131eefa + 7faa4be commit d8162fd
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 37 deletions.
6 changes: 6 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v2.1.0
------

- Add functions Position.{to_offset,to_lexing}
these allow computing an offset/Lexing.position from a Position.t and Input.t

v2.0.0
------

Expand Down
24 changes: 18 additions & 6 deletions lib/pp_loc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,22 @@ module Position = struct
let of_line_col l c = Line_col (l, c)
let shift l n = Shift (l, n)

let rec to_offset (input:Input.raw) (self:t) : int =
let rec to_offset_raw (input:Input.raw) (self:t) : int =
match self with
| Offset offset -> offset
| Full pos -> pos.Lexing.pos_cnum
| Line_col (line, col) ->
let lazy index = input.Input.line_offsets in
Line_offsets.find_offset index ~line ~col
| Shift (pos, n) -> to_offset input pos + n
| Shift (pos, n) -> to_offset_raw input pos + n

let rec to_full (input:Input.raw) (self:t) : Lexing.position =
let to_offset (input:Input.t) (self:t) : int =
let input, close = Input.open_raw input in
let off = to_offset_raw input self in
close ();
off

let rec to_lexing_raw (input:Input.raw) (self:t) : Lexing.position =
match self with
| Full pos -> pos
| Offset offset ->
Expand All @@ -149,7 +155,13 @@ module Position = struct
{Lexing.pos_cnum=offset; pos_lnum=line; pos_bol=bol;
pos_fname="";}
| Shift (pos, n) ->
to_full input (Offset (to_offset input pos + n))
to_lexing_raw input (Offset (to_offset_raw input pos + n))

let to_lexing ?(filename="") (input:Input.t) (self:t) : Lexing.position =
let input, close = Input.open_raw input in
let pos = to_lexing_raw input self in
close ();
{ pos with pos_fname = filename }
end

type loc = Position.t * Position.t
Expand Down Expand Up @@ -426,8 +438,8 @@ let pp
let locs =
List.map
(fun (start_pos,end_pos) ->
Position.to_full input_raw start_pos,
Position.to_full input_raw end_pos)
Position.to_lexing_raw input_raw start_pos,
Position.to_lexing_raw input_raw end_pos)
locs
in
locs
Expand Down
71 changes: 40 additions & 31 deletions lib/pp_loc.mli
Original file line number Diff line number Diff line change
@@ -1,35 +1,4 @@

(** A position in a file or string.
It is abstract to provide more flexibility than {!Lexing.position}.
@since 2.0
*)
module Position : sig
type t

(** Convert position. The filename is ignored, the offset, line, and column
are potentially used so they matter. *)
val of_lexing : Lexing.position -> t

(** Build a position from a byte offset in the input. *)
val of_offset : int -> t

(** [of_line_col line col] builds the position indicating the character
at column [col] and line [line] of the input.
Lines and columns start at 1.
*)
val of_line_col : int -> int -> t

(** [shift pos n] is the position located [n] bytes after [pos]. *)
val shift : t -> int -> t
end

(** The type of source locations: start position, end position.
The end position is not inclusive, it is just {i past} the end
of the highlighted range. *)
type loc = Position.t * Position.t

(** Abstraction over the input containing the input to read from. *)
module Input : sig
(** The abstract input type.
Expand Down Expand Up @@ -103,6 +72,46 @@ module Input : sig
t
end

(** A position in a file or string.
It is abstract to provide more flexibility than {!Lexing.position}.
@since 2.0
*)
module Position : sig
type t

(** Convert position. The filename is ignored, the offset, line, and column
are potentially used so they matter. *)
val of_lexing : Lexing.position -> t

(** Build a position from a byte offset in the input. *)
val of_offset : int -> t

(** [of_line_col line col] builds the position indicating the character
at column [col] and line [line] of the input.
Lines and columns start at 1.
*)
val of_line_col : int -> int -> t

(** [shift pos n] is the position located [n] bytes after [pos]. *)
val shift : t -> int -> t

(** [to_offset input pos] computes the offset in bytes corresponding to
position [pos] within [input]. *)
val to_offset : Input.t -> t -> int

(** [to_lexing input pos] computes the full position corresponding to position
[pos] within input [input]. The filename is set to [filename] if specified,
or to a dummy value otherwise (the empty string). *)
val to_lexing : ?filename:string -> Input.t -> t -> Lexing.position
end

(** The type of source locations: start position, end position.
The end position is not inclusive, it is just {i past} the end
of the highlighted range. *)
type loc = Position.t * Position.t

(** Quote the parts of the input corresponding to the input locations.
There are two different styles for highlighting errors, depending on whether
Expand Down

0 comments on commit d8162fd

Please sign in to comment.