1. camlspotter
  2. planck

Source

planck / lib / stoken.ml

The default branch has multiple heads

(** Stream of parser result, i.e. results of a lowr parser, or a lexer.
   With memoization.
*)

module Make(P : sig 
  include Planck_intf.S
  val run : 'a t -> Str.t -> ('a * Str.t, error) Result.t
end)(Elem : Elem.S)= struct

  module Base = struct
    module Elem = Elem
    module Pos = P.Str.Pos
    module Attr = struct
      type t = { last_position : Pos.t option (* last consumed token position *);
                 position      : Pos.t;
                 memo          : Smemo.memo
               }
      let position t = t.position
      let last_position t = t.last_position
      let memo t = t.memo
    end
  end

  module Str = Stream.Make(Base)
  include Str

  include Smemo.Extend(struct
    include Str
    let memo = Base.Attr.memo
  end)

  open Base

  let create (m : ('a option * Pos.t) P.t) = fun st ->
    let rec f last_pos st = lazy begin
      match P.run m st with
      | Result.Ok ((None, pos), _st') -> 
          null_desc { Attr.last_position = last_pos; 
                      position      = pos; 
                      memo          = Smemo.create () } (* EOS case *)
      | Result.Ok ((Some v, pos), st') -> 
          cons_desc v { Attr.last_position = last_pos;
                        position = pos;
                        memo = Smemo.create () } (f (Some pos) st')
      | Result.Error (pos, s) -> raise (P.Critical_error (pos, s))
    end
    in
    f None st
  ;;

  let last_position st : Pos.t option = Base.Attr.last_position (attr st)
end