Commits

camlspotter committed cc80310

higher layer stream and parser added

Comments (0)

Files changed (12)

    pstate
    pfile
    stoken
+   ptoken
    op_prec
 
 LIB = planck
       let diff = t.end_.File.byte - t.start.File.byte in
       Format.fprintf ppf "line %d, character %d-%d" t.start.File.line t.start.File.column (t.start.File.column + diff)
 
+  let merge = function
+    | `Between (p1, p2) -> { p1 with end_ = p2.end_ }
+    | `EndOf p -> { p with start = p.end_ }
 end
 
 module Region : sig
   type t = { start : File.t; end_ : File.t; } with sexp
   include S with type t := t
+  val merge : [< `Between of t * t | `EndOf of t ] -> t
+  (** [merge (`Between (p1, p2))] returns the position starts at the start point of [p1]
+      and ends at the end point of [p2].
+
+      [merge (`EndOf p)] returns the 0-length position starts and ends 
+      at the end point of [p] 
+  *)
+      
 end
+module Make(Stream : Stoken.S) = struct
+
+  include Pbase.Make(Stream)
+  
+  let last_position : Stream.Pos.t t = 
+    stream >>= fun st ->
+    return (match Stream.last_position st with
+      | Some reg -> reg
+      | None -> Stream.Pos.none)
+  
+  (** Efficient version of with_region *)
+  let with_region merger t =
+    last_position >>= fun last_bot_pos ->
+    position      >>= fun last_top_pos ->
+    t             >>= fun res -> 
+    position      >>= fun top_pos ->
+    last_position >>= fun bot_pos ->
+    let pos = 
+      if last_top_pos = top_pos then  (* CR jfuruse: implicitly using the equality of pos *)
+        (* No advancement. OCaml's behaviour is: return the end of the last consumed position *)
+        (* { last_bot_pos with start = last_bot_pos.end_ } *)
+        `EndOf last_bot_pos
+      else 
+        (* { start = last_top_pos.start; end_ = bot_pos.end_ } *)
+        `Between (last_top_pos, bot_pos)
+    in
+    (* \ assert (is_valid pos); *)
+    return (res, merger pos)
+  
+end
+module Make(Stream : Stoken.S) : sig
+  include Pbase.S with type Str.desc   = Stream.desc
+                  and  type Str.Elem.t = Stream.Elem.t
+                  and  type Str.Pos.t  = Stream.Pos.t
+                  and  type Str.Attr.t = Stream.Attr.t
+
+  val last_position : Stream.Pos.t t
+
+  val with_region 
+    : ([ `Between of Stream.Pos.t * Stream.Pos.t
+       | `EndOf of Stream.Pos.t ] -> Stream.Pos.t) (** Position merger *)
+    -> 'a t 
+    -> ('a * Stream.Pos.t) t
+    (** The position merger should calculate [Stream.Pos.t] of the following specification:
+        [`Between (p1, p2)] : a position starts at the start point of [p1] and ends at the end point of [p2]
+        [`EndOf p] : a position starts and ends at the end point of [p] 
+
+        See [Position.Region.merge] for an example.
+    *)
+end
 
 end
 
+(*
 module Make(Base : sig
   include Stream_intf.S
   val memo : Attr.t -> memo
   include Base
   include Extend(Base)
 end
+*)
 
   *)
 end) : X with type stream := Base.t
 
+(*
 module Make(Base : sig
   include Stream_intf.S
   val memo : Attr.t -> memo
          and  type Elem.t = Base.Elem.t
          and  type Pos.t  = Base.Pos.t
          and  type Attr.t = Base.Attr.t
-
+*)
    With memoization.
 *)
 
-module Make(P : sig 
+module type S = sig
+
+  module Under : Planck_intf.S
+
+  module Elem : Elem.S
+  module Pos : Position.S
+  module Attr : sig
+    type t
+    val position      : t -> Pos.t
+    val last_position : t -> Pos.t option
+    val memo          : t -> Smemo.memo
+  end
+
+  include Stream_intf.X with type elem := Elem.t
+                        and  type pos  := Pos.t
+                        and  type attr := Attr.t
+
+  (* CR jfuruse: Elem, Pos and Attr are overridden by restricted ones by this inclusion! *)
+  include Smemo.X with type stream := t
+
+  val create : (Elem.t option * Pos.t) Under.t -> Under.Str.t -> t
+  val last_position : t -> Pos.t option
+end
+
+
+module Make(Elem : Elem.S)(Pos : Position.S)(P : sig 
   include Planck_intf.S
   val run : 'a t -> Str.t -> ('a * Str.t, error) Result.t
-end)(Elem : Elem.S)= struct
+end) = struct
+
+  module Under = P
 
   module Base = struct
     module Elem = Elem
-    module Pos = P.Str.Pos
+    module Pos = Pos
     module Attr = struct
       type t = { last_position : Pos.t option (* last consumed token position *);
                  position      : Pos.t;
       let memo t = t.memo
     end
   end
+  include Base
 
-  module Str = Stream.Make(Base)
+  module Str = Stream.Extend(Base)
   include Str
 
   include Smemo.Extend(struct
+    include Base
     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
+(** Create a stream from a result of a parser *)
+
+module type S = sig
+
+  module Under : Planck_intf.S
+
+  module Elem : Elem.S
+  module Pos : Position.S
+  module Attr : sig
+    type t
+    val position      : t -> Pos.t
+    val last_position : t -> Pos.t option
+    val memo          : t -> Smemo.memo
+  end
+
+  include Stream_intf.X with type elem := Elem.t
+                        and  type pos  := Pos.t
+                        and  type attr := Attr.t
+
+  (* CR jfuruse: Elem, Pos and Attr are overridden by restricted ones by this inclusion! *)
+  include Smemo.X with type stream := t
+
+  val create : (Elem.t option * Pos.t) Under.t -> Under.Str.t -> t
+  val last_position : t -> Pos.t option
+end
+
+module Make(E: Elem.S)(Pos: Position.S)(P : sig
+  include Planck_intf.S
+  val run : 'a t -> Str.t -> ('a * Str.t, error) Result.t
+end) : S with type Elem.t = E.t
+         and  type Pos.t  = Pos.t
+         and  type 'a Under.t = 'a P.t
+         and  type Under.Str.desc = P.Str.desc
   | Cons of 'a * 'a desc lazy_t
   | Null
 
-module Make(P : Base) = struct
+module Extend(P : Base) = struct
+
+  type elem = P.Elem.t
+  type pos = P.Pos.t
+  type attr = P.Attr.t
 
   open Spotlib.Stream
-  include P
+  open P
 
   type desc = (Elem.t option * Attr.t) Spotlib.Stream.desc
   type t = (Elem.t option * Attr.t) Spotlib.Stream.t (* None means EOS *)
   let position s = Attr.position (attr s)
 
 end
+
+module Make(P : Base) = struct
+  include P
+  include Extend(P)
+end
+
   | Cons of 'a * 'a desc lazy_t
   | Null
 
-module Make (Base : Base) : S 
+(* CR jfuruse: Bad naming: It is a real creator of the stream, but called Extend. *)
+module Extend (Base : Base) : X
+  with type pos  = Base.Pos.t
+  and  type elem = Base.Elem.t
+  and  type attr = Base.Attr.t
+(** The functor [Extend] creates a stream module based on [Base] *)
+
+module Make (Base : Base) : S
   with type Pos.t  = Base.Pos.t
   and  type Elem.t = Base.Elem.t
   and  type Attr.t = Base.Attr.t
-(** The functor [Make] creates a stream module based on [Base] *)
+(** Same as [Extend] but includes [Base : Base].
+    Do not use [Make] if your [Base] contains something more than [Stream_intf.Base],
+    since the [Base] in the result of [Make] does not contain the extra things not 
+    in [Stream_intf.Base]. Instead, you must declare:
+
+    module M = struct
+      include Base
+      include Extend(Base)
+    end
+*)

lib/stream_intf.ml

 end
 
 (* Standard interface *)
-module type S = sig
-  include Base
+module type X = sig
 
+  (** the parameters *)    
+  type elem
+  type pos
+  type attr
   type desc
+
   type t = desc Lazy.t
   (** Stream type [t] is lazy by nature, and [desc] is its forced form. *)
 
-  val null : Attr.t -> t
+  val null : attr -> t
   (** Create a null stream *)
 
-  val null_desc : Attr.t -> desc
-  val cons_desc : Elem.t -> Attr.t -> t -> desc
+  val null_desc : attr -> desc
+  val cons_desc : elem -> attr -> t -> desc
   (** Create a null/cons cell desc, useful for stream creation *)
 
   (** Destructors *)
-  val peek : t -> (Elem.t * t) option
+  val peek : t -> (elem * t) option
 
   val is_null : t -> bool
   (** Null check *)
 
-  val attr : t -> Attr.t
-  val position : t -> Pos.t
+  val attr : t -> attr
+  val position : t -> pos
   (** Attribute and Position of the head element or null *)
 
-  val to_list : t -> Elem.t list
-  val iter : (Elem.t -> unit) -> t -> unit
-  val fold_right : (Elem.t -> 'a -> 'a) -> t -> 'a -> 'a
-  val map : (Elem.t -> 'a) -> t -> 'a Spotlib.Stream.t
+  val to_list : t -> elem list
+  val iter : (elem -> unit) -> t -> unit
+  val fold_right : (elem -> 'a -> 'a) -> t -> 'a -> 'a
+  val map : (elem -> 'a) -> t -> 'a Spotlib.Stream.t
   (** Iteration, folding and map *)
 
-  val rev_between : t -> t -> Elem.t list
+  val rev_between : t -> t -> elem list
   (** [rev_between t1 t2] returns the elemens between the two steam positions [t1] and [t2].
       [t2] must be a postfix of [t1].
       The elements are returned in the reverse order in the stream.
       This can be quite costy operation. Use with care.
   *)
 
-  val between : t -> t -> Elem.t list
+  val between : t -> t -> elem list
   (** Same as [rev_between] but the elements are in the same ordered in the streams.
 
       [between t1 t2] is actually defined as [List.rev (rev_between t1 t2)].
       The same notes of [rev_between] apply to this function too.
   *)
 end
+
+module type S = sig
+  include Base
+  include X with type elem := Elem.t
+            and  type pos  := Pos.t
+            and  type attr := Attr.t
+end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.