Skip to content

Commit 2fc82e8

Browse files
committed
Preparing release 0.1.1.
1 parent f2bfc0d commit 2fc82e8

29 files changed

+3841
-162
lines changed

CHANGES.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## 0.1.0 - 2021-12-29
7+
## [0.1.1] - 2021-12-31
8+
### Added
9+
- Support for `int32`, `int64`, and `nativeint`.
10+
- `*.{make_pp_int,make_to_string}` with optional arguments.
11+
12+
## [0.1.0] - 2021-12-29
813

914
Initial release.

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ The library provides four main functions.
2727
- `Int.pp_int` is a simple `Format` module style pretty printer.
2828
- `Int.pp_binary_int ~flags ~min_width` is a customizable `Format` module style pretty printer.
2929

30+
There are also versions available for `int32`, `int64`, and `nativeint` in the
31+
modules
32+
- `Int32`,
33+
- `Int64`, and
34+
- `Nativeint`.
35+
36+
A generic functor to generate binary-int printers is provided in the `MakePP`
37+
module.
38+
3039
## Basic use
3140

3241
```ocaml

dune-project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
(maintainers "Ifaz Kabir")
88
(source (github ifazk/pp-binary-ints))
99
(documentation https://ifazk.github.io/pp-binary-ints/)
10-
(version 0.1.0)
10+
(version 0.1.1)
1111

1212
(package
1313
(name pp-binary-ints)

lib/Flags.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
type padding =
2+
| Left
3+
| Right (* default *)
4+
| Zeros
5+
6+
type zero_printing =
7+
| OCaml (* depends on padding setting: bunch of zeros (no separators, no prefixs), or space padding on the left or right *)
8+
| InheritNonZero
9+
10+
type flags =
11+
{ padding: padding
12+
; separators: bool
13+
; prefix_non_zero: bool
14+
; zero_printing: zero_printing
15+
}
16+
17+
let default =
18+
{ padding = Right
19+
; separators = false
20+
; prefix_non_zero = false
21+
; zero_printing = OCaml
22+
}

lib/Flags.mli

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(** The Flags module contains types to modify how binary integers are
2+
printed. *)
3+
4+
type padding = Left | Right | Zeros
5+
(** [padding] controls whether spaces are are added on the left or right or if
6+
zero prefixes are added. *)
7+
8+
type zero_printing = OCaml | InheritNonZero
9+
(** [zero_printing] controls whether zeros printed similar to how [Printf]
10+
prints zeros or if zeros are printed similar to non-zero integers. *)
11+
12+
type flags = {
13+
padding : padding;
14+
separators : bool;
15+
prefix_non_zero : bool;
16+
zero_printing : zero_printing;
17+
}
18+
(** [flags] are passed to pretty printing functions to customize the output. *)
19+
20+
val default : flags
21+
(** A default set of flags. *)

lib/index.mld

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
A library for pretty printing boolean integers.
33

44
{1 Library pp-binary-ints}
5-
The entry point of this library is the module:
6-
{!module-Pp_binary_ints.module-Int}.
5+
The entry point of this library is the module: {!module-Pp_binary_ints}.
76

87
{1 Examples}
98

@@ -16,8 +15,15 @@ The library provides four main functions.
1615
{- {!module-Pp_binary_ints.module-Int.val-pp_binary_int} is a customizable {!module-Format} module style pretty printer which takes in named arguments [~flags] and [~min_width].}
1716
}
1817

19-
The options to customize the outputs can be found in {!module-Pp_binary_ints.Int.Flags}.
18+
The options to customize the outputs can be found in {!module-Pp_binary_ints.Flags}.
2019

20+
We also offer versions of these functions for `int32`, `int64`, `nativeint`, in
21+
the following modules.
22+
{ul
23+
{- {!module-Pp_binary_ints.module-Int32}}
24+
{- {!module-Pp_binary_ints.module-Int64}}
25+
{- {!module-Pp_binary_ints.module-Nativeint}}
26+
}
2127

2228
{2 Basic use}
2329

lib/int.ml

Lines changed: 6 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,10 @@
1-
module Int = Stdlib.Int
1+
module Int: MakePP.S with type t = int = Stdlib.Int
22

3-
module Flags = struct
4-
type padding =
5-
| Left
6-
| Right (* default *)
7-
| Zeros
8-
9-
type zero_printing =
10-
| OCaml (* depends on padding setting: bunch of zeros (no separators, no prefixs), or space padding on the left or right *)
11-
| InheritNonZero
12-
13-
type flags =
14-
{ padding: padding
15-
; separators: bool
16-
; prefix_non_zero: bool
17-
; zero_printing: zero_printing
18-
}
19-
20-
let default =
21-
{ padding = Right
22-
; separators = false
23-
; prefix_non_zero = false
24-
; zero_printing = OCaml
25-
}
3+
module Dec = struct
4+
let prefix = "0b"
5+
let suffix = ""
266
end
277

28-
(* Underscore printing is tricky.
29-
Underscores and prefixes both count towards min width.
30-
Min width 5, no prefix, zero padding.
31-
Ob1111 should be printed as 01111, not _1111
32-
Min width 6, prefix.
33-
Ob1111 should be printed as 0b1111.
34-
Min width 5, with prefix.
35-
0b111 should be printed as 0b111.
36-
*)
37-
38-
(* Utilities *)
39-
let nat_pred n =
40-
if (n > 0) then
41-
n - 1
42-
else
43-
0
44-
45-
let drop_next_bit rev_bits =
46-
rev_bits lsr 1
47-
48-
let get_next_bit_char rev_bits =
49-
if Int.equal 0 (Int.logand 1 rev_bits) then
50-
'0'
51-
else
52-
'1'
53-
54-
(* The next few functions assume zero padding.
55-
For space padding, 1 will be passed as the min_width
56-
If prefix is set to false, then 0 will be passed as the prefix_size.
57-
*)
58-
let not_at_end ~(min_width:int) ~prefix_size rev_bits =
59-
((rev_bits <> 0) || (min_width > prefix_size))
60-
61-
let last_padding ~min_width ~prefix_size rev_bits =
62-
let open Int in
63-
equal rev_bits 0 &&
64-
equal min_width (prefix_size + 1)
65-
66-
let print_underscore ~min_width ~count ~separators ~prefix_size rev_bits =
67-
let open Int in
68-
separators &&
69-
(equal 0 ((count + 1) mod 5)) &&
70-
(not_at_end ~min_width ~prefix_size rev_bits) &&
71-
(not (last_padding ~min_width ~prefix_size rev_bits))
72-
73-
let rec push_chars ~buf ~separators ~prefix_size ~min_width ~count rev_bits : unit =
74-
if print_underscore ~min_width ~count ~separators ~prefix_size rev_bits then
75-
( Buffer.add_char buf '_'
76-
; push_chars ~buf ~separators ~prefix_size ~min_width:(nat_pred min_width) ~count:(count + 1) rev_bits
77-
)
78-
else if (not_at_end ~min_width ~prefix_size rev_bits) then
79-
( Buffer.add_char buf (get_next_bit_char rev_bits)
80-
; let rev_bits = drop_next_bit rev_bits in
81-
let min_width = nat_pred min_width in
82-
let count = count + 1 in
83-
push_chars ~buf ~separators ~prefix_size
84-
~min_width
85-
~count
86-
rev_bits
87-
)
88-
else
89-
()
90-
91-
let rev_buffer ~separators ~prefix ~min_width n : Buffer.t =
92-
let buf = Buffer.create 16 in (* TODO: consider min_width for initial size *)
93-
let prefix_size = (if prefix then 2 else 0) in
94-
( push_chars ~buf ~separators ~prefix_size ~min_width ~count:0 n
95-
; if prefix then
96-
begin
97-
Buffer.add_char buf 'b';
98-
Buffer.add_char buf '0';
99-
end
100-
; buf
101-
)
102-
103-
(* end of assuming zero padding *)
104-
105-
let pp_spaces fmt n =
106-
for _ = 1 to n do
107-
Format.pp_print_char fmt ' ';
108-
done
109-
110-
let pp_rev_buffer fmt buf =
111-
let len = Buffer.length buf in
112-
for i = 1 to len do
113-
Format.pp_print_char fmt (Buffer.nth buf (len - i))
114-
done
115-
116-
let pp_binary_int ~flags ~min_width fmt n =
117-
let open Flags in
118-
let min_width = max 1 min_width in
119-
let {padding; prefix_non_zero; separators; zero_printing} = flags in
120-
let buf =
121-
match padding with
122-
| Left | Right ->
123-
let prefix = prefix_non_zero && ((not (Int.equal 0 n)) || (zero_printing = InheritNonZero)) in
124-
let min_width = if prefix then 3 else 1 in
125-
rev_buffer
126-
~separators
127-
~prefix
128-
~min_width
129-
n
130-
| Zeros ->
131-
if (zero_printing = OCaml) && Int.equal n 0 then
132-
rev_buffer ~separators:false ~prefix:false ~min_width 0
133-
else
134-
let prefix = prefix_non_zero in
135-
let min_width = max min_width (if prefix then 3 else 1) in
136-
rev_buffer ~separators ~prefix ~min_width n
137-
in
138-
let len = Buffer.length buf in
139-
match padding with
140-
| Left ->
141-
begin
142-
pp_spaces fmt (min_width - len);
143-
pp_rev_buffer fmt buf;
144-
end
145-
| Right ->
146-
begin
147-
pp_rev_buffer fmt buf;
148-
pp_spaces fmt (min_width - len);
149-
end
150-
| Zeros ->
151-
pp_rev_buffer fmt buf
152-
153-
let pp_int fmt n =
154-
pp_binary_int ~flags:(Flags.default) ~min_width:1 fmt n
155-
156-
let to_string n : string =
157-
Format.asprintf "%a" pp_int n
8+
module Flags = Flags
1589

159-
let to_string_with ~flags ~min_width : int -> string =
160-
Format.asprintf "%a" (pp_binary_int ~flags ~min_width)
10+
include (MakePP.Make (Int) (Dec))

lib/int.mli

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
type t = int
2+
13
module Flags : sig
24
(** The Flags module contains types to modify how binary integers are
35
printed. *)
@@ -33,6 +35,13 @@ val pp_binary_int :
3335
val pp_int : Format.formatter -> int -> unit
3436
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the formatter [fmt]. *)
3537

38+
val make_pp_int :
39+
?flags:Flags.flags -> ?min_width:int -> unit -> Format.formatter -> int -> unit
40+
(** [make_pp_int ?flags ?min_width ()] is just [pp_binary_int ~flags
41+
~min_width], but [flags] and [min_width] are optional. If omitted default
42+
values of [Flags.default] and [1] are passed to pp_binary_int. This version
43+
is nicer to with with the [Format] or [Fmt] modules. *)
44+
3645
val to_string_with : flags:Flags.flags -> min_width:int -> int -> string
3746
(** [to_string_width ~flags ~min_width n] converts the integer [n] to a binary
3847
integer [n]. customizing the output with [~flags]. [~min_width] pads the
@@ -41,3 +50,9 @@ val to_string_with : flags:Flags.flags -> min_width:int -> int -> string
4150

4251
val to_string : int -> string
4352
(** [to_string n] converts the integer [n] to a binary integer [n]. *)
53+
54+
val make_to_string :
55+
?flags:Flags.flags -> ?min_width:int -> unit -> int -> string
56+
(** [make_to_string ?flags ?min_width ()] is just [to_string_with ~flags
57+
~min_width], but [flags] and [min_width] are optional. If omitted default
58+
values of [Flags.default] and [1] are passed to to_string_with. *)

lib/int32.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module I: Internal.S with type t = int32 = Stdlib.Int32
2+
3+
module Dec = struct
4+
let prefix = "0b"
5+
let suffix = "l"
6+
end
7+
8+
include (MakePP.Make (I) (Dec))

lib/int32.mli

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
type t = int32
2+
3+
val pp_binary_int :
4+
flags:Flags.flags -> min_width:int -> Format.formatter -> int32 -> unit
5+
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the
6+
formatter [fmt], customizing the output with [~flags]. [~min_width] pads the
7+
output with enough spaces or zeros so that the output is at least
8+
[~min_width] characters, depends on [flags.padding]. *)
9+
10+
val pp_int : Format.formatter -> int32 -> unit
11+
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the formatter [fmt]. *)
12+
13+
val make_pp_int :
14+
?flags:Flags.flags -> ?min_width:int -> unit -> Format.formatter -> int32 -> unit
15+
(** [make_pp_int ?flags ?min_width ()] is just [pp_binary_int ~flags
16+
~min_width], but [flags] and [min_width] are optional. If omitted default
17+
values of [Flags.default] and [1] are passed to pp_binary_int. This version
18+
is nicer to with with the [Format] or [Fmt] modules. *)
19+
20+
val to_string_with : flags:Flags.flags -> min_width:int -> int32 -> string
21+
(** [to_string_width ~flags ~min_width n] converts the integer [n] to a binary
22+
integer [n]. customizing the output with [~flags]. [~min_width] pads the
23+
output with enough spaces or zeros so that the output is at least
24+
[~min_width] characters, depends on [flags.padding]. *)
25+
26+
val to_string : int32 -> string
27+
(** [to_string n] converts the integer [n] to a binary integer [n]. *)
28+
29+
val make_to_string :
30+
?flags:Flags.flags -> ?min_width:int -> unit -> int32 -> string
31+
(** [make_to_string ?flags ?min_width ()] is just [to_string_with ~flags
32+
~min_width], but [flags] and [min_width] are optional. If omitted default
33+
values of [Flags.default] and [1] are passed to to_string_with. *)

lib/int64.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module I: Internal.S with type t = int64 = Stdlib.Int64
2+
3+
module Dec = struct
4+
let prefix = "0b"
5+
let suffix = "L"
6+
end
7+
8+
include (MakePP.Make (I) (Dec))

lib/int64.mli

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
type t = int64
2+
3+
val pp_binary_int :
4+
flags:Flags.flags -> min_width:int -> Format.formatter -> int64 -> unit
5+
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the
6+
formatter [fmt], customizing the output with [~flags]. [~min_width] pads the
7+
output with enough spaces or zeros so that the output is at least
8+
[~min_width] characters, depends on [flags.padding]. *)
9+
10+
val pp_int : Format.formatter -> int64 -> unit
11+
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the formatter [fmt]. *)
12+
13+
val make_pp_int :
14+
?flags:Flags.flags -> ?min_width:int -> unit -> Format.formatter -> int64 -> unit
15+
(** [make_pp_int ?flags ?min_width ()] is just [pp_binary_int ~flags
16+
~min_width], but [flags] and [min_width] are optional. If omitted default
17+
values of [Flags.default] and [1] are passed to pp_binary_int. This version
18+
is nicer to with with the [Format] or [Fmt] modules. *)
19+
20+
val to_string_with : flags:Flags.flags -> min_width:int -> int64 -> string
21+
(** [to_string_width ~flags ~min_width n] converts the integer [n] to a binary
22+
integer [n]. customizing the output with [~flags]. [~min_width] pads the
23+
output with enough spaces or zeros so that the output is at least
24+
[~min_width] characters, depends on [flags.padding]. *)
25+
26+
val to_string : int64 -> string
27+
(** [to_string n] converts the integer [n] to a binary integer [n]. *)
28+
29+
val make_to_string :
30+
?flags:Flags.flags -> ?min_width:int -> unit -> int64 -> string
31+
(** [make_to_string ?flags ?min_width ()] is just [to_string_with ~flags
32+
~min_width], but [flags] and [min_width] are optional. If omitted default
33+
values of [Flags.default] and [1] are passed to to_string_with. *)

0 commit comments

Comments
 (0)