struct
type t = {
mutable unfinished_line : string option;
lines : item Queue.t;
mutable parsed_lines : int;
filename : string option;
}
let make ?filename () =
{unfinished_line = None;
lines = Queue.create ();
parsed_lines = 0;
filename}
let feed_line p s =
Queue.enqueue p.lines s
let feed_string p s =
let lines = String.split s ~on:'\n' in
let rec faux = function
| [] -> assert false
| [ "" ] -> ()
| [ s ] ->
p.unfinished_line <- Some s;
| h :: t ->
Queue.enqueue p.lines (Line.of_string_unsafe h);
faux t
in
match p.unfinished_line, lines with
| _, [] -> assert false
| _, [""] -> ()
| None, l -> faux l
| Some s, h :: t ->
p.unfinished_line <- None;
faux ((s ^ h) :: t)
let queued_lines p = Queue.length p.lines
let peek_line p = Queue.peek p.lines
let next_line p =
let l = Queue.dequeue p.lines in
if l <> None then (
p.parsed_lines <- p.parsed_lines + 1;
);
l
exception No_next_line
let next_line_exn p =
match next_line p with
| Some s -> s
| None -> raise No_next_line
let current_position p =
Pos.make ?source:p.filename ~line:p.parsed_lines ()
let is_empty p =
Queue.is_empty p.lines && p.unfinished_line = None
let contents p = Queue.to_list p.lines, p.unfinished_line
let empty p = (Queue.clear p.lines; p.unfinished_line <- None)
end