Source

treeprint / lib / printer.mli

open Spotlib.Spot

(** Display machine with Format like capability *)

module Token : sig
  type t
  val format : Format.t -> t -> unit
  val dump : Format.t -> t -> unit
  val buffer : Buffer.t -> t -> unit
  val show : t -> string
end

type token = Token.t

(** Primitives *)
type assoc = Left | Right | Noassoc
type level = float

type 'a t = assoc -> level -> 'a
include Monad_intf.T with type 'a t := 'a t

type ppr = token t

(* 'a t is monadic *)
val bind : 'a t -> ('a -> 'b t) -> 'b t
val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t

val box : int -> ppr -> ppr
val vbox : int -> ppr -> ppr
val ( ++ ) : ppr -> ppr -> ppr
val cut : ppr
val space : ppr
val flush : ppr
val seq : ppr list -> ppr
val string : string -> ppr
val nop : ppr

(** Level and environments *)

val left : 'a t -> 'a t           
(** Put the arg in the "left" environment *)
val right : 'a t -> 'a t          
(** Put the arg in the "right" environment *)
val noassoc : 'a t -> 'a t        
(** Put the arg in the "noassoc" environment *)
val level : level -> 'a t -> 'a t 
(** Put the arg in the specified level *)
val reset : 'a t -> 'a t          
(** Put the arg in "noassoc" env and 0.0 level *)
(* CR jfuruse: Should be -1.0 ? *)

val check_against_current_level : level -> [ `Same | `Stronger | `Weaker ] t
(** Compare the argument against the current level:
    `Same     : the same as the current level
    `Stronger : the argument is stronger than the current
    `Weak     : the argument is weaker than the current
*)

val need_paren : assoc -> level -> bool t
(** Check the printer object of the level [level] requires parenthesis wrapping or not *)

(** Utilities 
    These implements common printing with auto parenthesis wrapping.
    Note: They may not suit with your own taste.
*)
val parenbox : assoc -> level -> ppr -> ppr
val binop    : assoc -> level -> op:ppr -> ppr -> ppr -> ppr
val list     : level -> ppr -> ppr list -> ppr
val prefix   : level -> op:ppr -> ppr -> ppr
val postfix  : level -> op:ppr -> ppr -> ppr

val parens : string -> string -> ppr -> ppr
(** Surround the given ppr with the left and right strings.
    The level for ppr is reset to -1.0. *)

(** OCaml like printers *)
module OCaml : sig
  val ( + )        : ppr -> ppr -> ppr
  val ( - )        : ppr -> ppr -> ppr
  val ( * )        : ppr -> ppr -> ppr
  val uminus       : ppr -> ppr
  val tuple        : ppr list -> ppr
  val ( ^-> )      : ppr -> ppr -> ppr
  val app          : ppr -> ppr -> ppr
  val sequence     : ppr list -> ppr
  val if_then_else : ppr -> ppr -> ppr -> ppr
  val if_then      : ppr -> ppr -> ppr
end

(** Drivers *)
val buffer : ('a -> ppr) -> Buffer.t -> ?assoc:assoc -> ?level:level -> 'a -> unit
val show : ('a -> ppr) -> ?assoc:assoc -> ?level:level -> 'a -> string
val format : ?assoc:assoc -> ?level:level -> ('a -> ppr) -> Format.t -> 'a -> unit
(** [format] has a different type than [buffer] and [show], 
    so that it could be used smoothly in [Format.fprintf]'s functional setting.
*)

module MakeDrivers(M : sig type t val ppr : t -> ppr end) : sig
  open M
  val format : Format.t -> t -> unit
  val dump : Format.t -> t -> unit
  val buffer : Buffer.t -> ?assoc:assoc -> ?level:level -> t -> unit
  val show : ?assoc:assoc -> ?level:level -> t -> string
end

module Test :sig 
  val test : unit -> unit
end