Skip to content

Commit

Permalink
Bugfixes and documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
ifazk committed Dec 29, 2021
1 parent fd3475b commit 7f215ab
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 4 deletions.
94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# pp-binary-ints

An OCaml library for printing `int`s as unsigned binary integers.

The pretty printers are fairly customizable. The following options are supported.

- Padding with zeros or spaces so that binary integers satisfy a minimum width.
- Prefixing the integers `0b`.
- Separating every four bits with `_` (underscore).
- Choose if zeros should be printed similar to non_zero ints.

# Installation
Install this library using `opam`.

```
opam install pp-binary-ints
```

# Examples

The library provides four main functions.

- `Int.to_string` converts ints to strings.
- `Int.to_string_with ~flags ~min_width` converts ints to strings, customizing the output with `flags` and `min_width`.
- `Int.pp_int` is a simple `Format` module style pretty printer.
- `Int.pp_binary_int ~flags ~min_width` is a customizable `Format` module style pretty printer.

## Basic use

```ocaml
# #require "pp-binary-ints";;
# module Pp_Bin = Pp_binary_ints.Int;;
# Pp_Bin.to_string 0b110111;;
- : string = "110111"
# Pp_Bin.to_string 0o777;;
- : string = "111111111"
# Pp_Bin.to_string 1234;;
- : string = "10011010010"
```

## Customizing padding and minimum width

```ocaml
# #require "pp-binary-ints";;
# module Pp_Bin = Pp_binary_ints.Int;;
# (* Zero Padding *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Zeros } ~min_width:13 0b110111;;
- : string = "0000000110111"
# (* Default is space padding on the right *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.default ~min_width:13 0b110111;;
- : string = "110111 "
# (* Space padding on the left is also possible *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Left} ~min_width:13 0b110111;;
- : string = " 110111"
```

## Separators and prefixes

```ocaml
# (* Separate every 4 digits with _ *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with separators = true } ~min_width:1 0b110111;;
- : string = "11_0111"
# (* Prefix non-zero *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true } ~min_width:1 0b110111;;
- : string = "0b110111"
# (* Prefix non-zero with separators *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true; separators = true } ~min_width:1 0b110111;;
- : string = "0b11_0111"
```

## Zero printing behaviour

We support pretty printing `0` (zero) both how OCaml's `Printf` woould print it,
as well as printing it similar to how we print non zero integers. The default
behaviour is to follow `Printf`'s zero printing.

```ocaml
# (* Prefix's are not added to zero by default *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true } ~min_width:1 0;;
- : string = "0"
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true; zero_printing = InheritNonZero } ~min_width:1 0;;
- : string = "0b0"
# (* For Zero padding, separators are not used by default *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Zeros; separators = true } ~min_width:6 0;;
- : string = "000000"
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Zeros; separators = true; zero_printing = InheritNonZero } ~min_width:6 0;;
- : string = "0_0000"
# (* All the above options can be combined *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ padding = Zeros; separators = true; prefix_non_zero = true; zero_printing = InheritNonZero } ~min_width:8 0;;
- : string = "0b0_0000"
# (* The library is careful not to write "0b_" when prefixing, 'b' is always follewd by a digit *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ padding = Zeros; separators = true; prefix_non_zero = true; zero_printing = InheritNonZero } ~min_width:7 0;;
- : string = "0b00000"
```
84 changes: 83 additions & 1 deletion lib/index.mld
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,86 @@ A library for pretty printing boolean integers.

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

{1 Examples}

The library provides four main functions.

{ul
{- {!module-Pp_binary_ints.module-Int.val-to_string} converts ints to strings.}
{- {!module-Pp_binary_ints.module-Int.val-to_string_with} converts ints to strings, customizing the output with the [~flags] and [~min_width] named arguments.}
{- {!module-Pp_binary_ints.module-Int.val-pp_int} is a simple {!module-Format} module style pretty printer.}
{- {!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].}
}

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


{2 Basic use}

{[
# #require "pp-binary-ints";;
# module Pp_Bin = Pp_binary_ints.Int;;
# Pp_Bin.to_string 0b110111;;
- : string = "110111"
# Pp_Bin.to_string 0o777;;
- : string = "111111111"
# Pp_Bin.to_string 1234;;
- : string = "10011010010"
]}

{2 Customizing padding and minimum width}

{[
# #require "pp-binary-ints";;
# module Pp_Bin = Pp_binary_ints.Int;;
# (* Zero Padding *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Zeros } ~min_width:13 0b110111;;
- : string = "0000000110111"
# (* Default is space padding on the right *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.default ~min_width:13 0b110111;;
- : string = "110111 "
# (* Space padding on the left is also possible *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Left} ~min_width:13 0b110111;;
- : string = " 110111"
]}

{2 Separators and prefixes}

{[
# (* Separate every 4 digits with _ *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with separators = true } ~min_width:1 0b110111;;
- : string = "11_0111"
# (* Prefix non-zero *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true } ~min_width:1 0b110111;;
- : string = "0b110111"
# (* Prefix non-zero with separators *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true; separators = true } ~min_width:1 0b110111;;
- : string = "0b11_0111"
]}

{2 Zero printing behaviour}

We support pretty printing `0` (zero) both how OCaml's `Printf` woould print it,
as well as printing it similar to how we print non zero integers. The default
behaviour is to follow `Printf`'s zero printing.

{[
# (* Prefix's are not added to zero by default *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true } ~min_width:1 0;;
- : string = "0"
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with prefix_non_zero = true; zero_printing = InheritNonZero } ~min_width:1 0;;
- : string = "0b0"
# (* For Zero padding, separators are not used by default *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Zeros; separators = true } ~min_width:6 0;;
- : string = "000000"
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ default with padding = Zeros; separators = true; zero_printing = InheritNonZero } ~min_width:6 0;;
- : string = "0_0000"
# (* All the above options can be combined *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ padding = Zeros; separators = true; prefix_non_zero = true; zero_printing = InheritNonZero } ~min_width:8 0;;
- : string = "0b0_0000"
# (* The library is careful not to write "0b_" when prefixing, 'b' is always follewd by a digit *);;
# Pp_Bin.to_string_with ~flags:Pp_Bin.Flags.{ padding = Zeros; separators = true; prefix_non_zero = true; zero_printing = InheritNonZero } ~min_width:7 0;;
- : string = "0b00000"
]}
3 changes: 1 addition & 2 deletions lib/int.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ let last_padding ~min_width ~prefix_size rev_bits =
let print_underscore ~min_width ~count ~separators ~prefix_size rev_bits =
let open Int in
separators &&
(count > 0) &&
(equal 0 (count mod 4)) &&
(equal 0 ((count + 1) mod 5)) &&
(not_at_end ~min_width ~prefix_size rev_bits) &&
(not (last_padding ~min_width ~prefix_size rev_bits))

Expand Down
21 changes: 20 additions & 1 deletion lib/int.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,41 @@ module Flags : sig
printed. *)

type padding = Left | Right | Zeros
(** [padding] controls whether spaces are are added on the left or right or if
zero prefixes are added. *)

type zero_printing = OCaml | InheritNonZero
(** [zero_printing] controls whether zeros printed similar to how [Printf]
prints zeros or if zeros are printed similar to non-zero integers. *)

type flags = {
padding : padding;
separators : bool;
prefix_non_zero : bool;
zero_printing : zero_printing;
}
(** [flags] are passed to pretty printing functions to customize the
output. *)

val default : flags
(** A default set of flags. *)
end

val pp_binary_int :
flags:Flags.flags -> min_width:int -> Format.formatter -> int -> unit
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer $n$ *)
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the
formatter [fmt], customizing the output with [~flags]. [~min_width] pads the
output with enough spaces or zeros so that the output is at least
[~min_width] characters, depends on [flags.padding]. *)

val pp_int : Format.formatter -> int -> unit
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the formatter [fmt]. *)

val to_string_with : flags:Flags.flags -> min_width:int -> int -> string
(** [to_string_width ~flags ~min_width n] converts the integer [n] to a binary
integer [n]. customizing the output with [~flags]. [~min_width] pads the
output with enough spaces or zeros so that the output is at least
[~min_width] characters, depends on [flags.padding]. *)

val to_string : int -> string
(** [to_string n] converts the integer [n] to a binary integer [n]. *)
14 changes: 14 additions & 0 deletions test/large.ml
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,17 @@ let%test "right inherit 8" =
let%test "right inherit 9" =
["10001 ";"0b10001 ";"1_0001 ";"0b1_0001 "] =
test_width right_inherit_configs 9 0b10001

(** * Large printing *)

let%test "zero inherit 16" =
["0000000000110111";"0b00000000110111";"0_0000_0011_0111";"0b0000_0011_0111"] =
test_width zero_inherit_configs 16 0b110111

let%test "left inherit 16" =
[" 110111";" 0b110111";" 11_0111";" 0b11_0111"] =
test_width left_inherit_configs 16 0b110111

let%test "right inherit 16" =
["110111 ";"0b110111 ";"11_0111 ";"0b11_0111 "] =
test_width right_inherit_configs 16 0b110111

0 comments on commit 7f215ab

Please sign in to comment.