-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
3,841 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
type padding = | ||
| Left | ||
| Right (* default *) | ||
| Zeros | ||
|
||
type zero_printing = | ||
| OCaml (* depends on padding setting: bunch of zeros (no separators, no prefixs), or space padding on the left or right *) | ||
| InheritNonZero | ||
|
||
type flags = | ||
{ padding: padding | ||
; separators: bool | ||
; prefix_non_zero: bool | ||
; zero_printing: zero_printing | ||
} | ||
|
||
let default = | ||
{ padding = Right | ||
; separators = false | ||
; prefix_non_zero = false | ||
; zero_printing = OCaml | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
(** The Flags module contains types to modify how binary integers are | ||
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. *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,160 +1,10 @@ | ||
module Int = Stdlib.Int | ||
module Int: MakePP.S with type t = int = Stdlib.Int | ||
|
||
module Flags = struct | ||
type padding = | ||
| Left | ||
| Right (* default *) | ||
| Zeros | ||
|
||
type zero_printing = | ||
| OCaml (* depends on padding setting: bunch of zeros (no separators, no prefixs), or space padding on the left or right *) | ||
| InheritNonZero | ||
|
||
type flags = | ||
{ padding: padding | ||
; separators: bool | ||
; prefix_non_zero: bool | ||
; zero_printing: zero_printing | ||
} | ||
|
||
let default = | ||
{ padding = Right | ||
; separators = false | ||
; prefix_non_zero = false | ||
; zero_printing = OCaml | ||
} | ||
module Dec = struct | ||
let prefix = "0b" | ||
let suffix = "" | ||
end | ||
|
||
(* Underscore printing is tricky. | ||
Underscores and prefixes both count towards min width. | ||
Min width 5, no prefix, zero padding. | ||
Ob1111 should be printed as 01111, not _1111 | ||
Min width 6, prefix. | ||
Ob1111 should be printed as 0b1111. | ||
Min width 5, with prefix. | ||
0b111 should be printed as 0b111. | ||
*) | ||
|
||
(* Utilities *) | ||
let nat_pred n = | ||
if (n > 0) then | ||
n - 1 | ||
else | ||
0 | ||
|
||
let drop_next_bit rev_bits = | ||
rev_bits lsr 1 | ||
|
||
let get_next_bit_char rev_bits = | ||
if Int.equal 0 (Int.logand 1 rev_bits) then | ||
'0' | ||
else | ||
'1' | ||
|
||
(* The next few functions assume zero padding. | ||
For space padding, 1 will be passed as the min_width | ||
If prefix is set to false, then 0 will be passed as the prefix_size. | ||
*) | ||
let not_at_end ~(min_width:int) ~prefix_size rev_bits = | ||
((rev_bits <> 0) || (min_width > prefix_size)) | ||
|
||
let last_padding ~min_width ~prefix_size rev_bits = | ||
let open Int in | ||
equal rev_bits 0 && | ||
equal min_width (prefix_size + 1) | ||
|
||
let print_underscore ~min_width ~count ~separators ~prefix_size rev_bits = | ||
let open Int in | ||
separators && | ||
(equal 0 ((count + 1) mod 5)) && | ||
(not_at_end ~min_width ~prefix_size rev_bits) && | ||
(not (last_padding ~min_width ~prefix_size rev_bits)) | ||
|
||
let rec push_chars ~buf ~separators ~prefix_size ~min_width ~count rev_bits : unit = | ||
if print_underscore ~min_width ~count ~separators ~prefix_size rev_bits then | ||
( Buffer.add_char buf '_' | ||
; push_chars ~buf ~separators ~prefix_size ~min_width:(nat_pred min_width) ~count:(count + 1) rev_bits | ||
) | ||
else if (not_at_end ~min_width ~prefix_size rev_bits) then | ||
( Buffer.add_char buf (get_next_bit_char rev_bits) | ||
; let rev_bits = drop_next_bit rev_bits in | ||
let min_width = nat_pred min_width in | ||
let count = count + 1 in | ||
push_chars ~buf ~separators ~prefix_size | ||
~min_width | ||
~count | ||
rev_bits | ||
) | ||
else | ||
() | ||
|
||
let rev_buffer ~separators ~prefix ~min_width n : Buffer.t = | ||
let buf = Buffer.create 16 in (* TODO: consider min_width for initial size *) | ||
let prefix_size = (if prefix then 2 else 0) in | ||
( push_chars ~buf ~separators ~prefix_size ~min_width ~count:0 n | ||
; if prefix then | ||
begin | ||
Buffer.add_char buf 'b'; | ||
Buffer.add_char buf '0'; | ||
end | ||
; buf | ||
) | ||
|
||
(* end of assuming zero padding *) | ||
|
||
let pp_spaces fmt n = | ||
for _ = 1 to n do | ||
Format.pp_print_char fmt ' '; | ||
done | ||
|
||
let pp_rev_buffer fmt buf = | ||
let len = Buffer.length buf in | ||
for i = 1 to len do | ||
Format.pp_print_char fmt (Buffer.nth buf (len - i)) | ||
done | ||
|
||
let pp_binary_int ~flags ~min_width fmt n = | ||
let open Flags in | ||
let min_width = max 1 min_width in | ||
let {padding; prefix_non_zero; separators; zero_printing} = flags in | ||
let buf = | ||
match padding with | ||
| Left | Right -> | ||
let prefix = prefix_non_zero && ((not (Int.equal 0 n)) || (zero_printing = InheritNonZero)) in | ||
let min_width = if prefix then 3 else 1 in | ||
rev_buffer | ||
~separators | ||
~prefix | ||
~min_width | ||
n | ||
| Zeros -> | ||
if (zero_printing = OCaml) && Int.equal n 0 then | ||
rev_buffer ~separators:false ~prefix:false ~min_width 0 | ||
else | ||
let prefix = prefix_non_zero in | ||
let min_width = max min_width (if prefix then 3 else 1) in | ||
rev_buffer ~separators ~prefix ~min_width n | ||
in | ||
let len = Buffer.length buf in | ||
match padding with | ||
| Left -> | ||
begin | ||
pp_spaces fmt (min_width - len); | ||
pp_rev_buffer fmt buf; | ||
end | ||
| Right -> | ||
begin | ||
pp_rev_buffer fmt buf; | ||
pp_spaces fmt (min_width - len); | ||
end | ||
| Zeros -> | ||
pp_rev_buffer fmt buf | ||
|
||
let pp_int fmt n = | ||
pp_binary_int ~flags:(Flags.default) ~min_width:1 fmt n | ||
|
||
let to_string n : string = | ||
Format.asprintf "%a" pp_int n | ||
module Flags = Flags | ||
|
||
let to_string_with ~flags ~min_width : int -> string = | ||
Format.asprintf "%a" (pp_binary_int ~flags ~min_width) | ||
include (MakePP.Make (Int) (Dec)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module I: Internal.S with type t = int32 = Stdlib.Int32 | ||
|
||
module Dec = struct | ||
let prefix = "0b" | ||
let suffix = "l" | ||
end | ||
|
||
include (MakePP.Make (I) (Dec)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
type t = int32 | ||
|
||
val pp_binary_int : | ||
flags:Flags.flags -> min_width:int -> Format.formatter -> int32 -> unit | ||
(** [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 -> int32 -> unit | ||
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the formatter [fmt]. *) | ||
|
||
val make_pp_int : | ||
?flags:Flags.flags -> ?min_width:int -> unit -> Format.formatter -> int32 -> unit | ||
(** [make_pp_int ?flags ?min_width ()] is just [pp_binary_int ~flags | ||
~min_width], but [flags] and [min_width] are optional. If omitted default | ||
values of [Flags.default] and [1] are passed to pp_binary_int. This version | ||
is nicer to with with the [Format] or [Fmt] modules. *) | ||
|
||
val to_string_with : flags:Flags.flags -> min_width:int -> int32 -> 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 : int32 -> string | ||
(** [to_string n] converts the integer [n] to a binary integer [n]. *) | ||
|
||
val make_to_string : | ||
?flags:Flags.flags -> ?min_width:int -> unit -> int32 -> string | ||
(** [make_to_string ?flags ?min_width ()] is just [to_string_with ~flags | ||
~min_width], but [flags] and [min_width] are optional. If omitted default | ||
values of [Flags.default] and [1] are passed to to_string_with. *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module I: Internal.S with type t = int64 = Stdlib.Int64 | ||
|
||
module Dec = struct | ||
let prefix = "0b" | ||
let suffix = "L" | ||
end | ||
|
||
include (MakePP.Make (I) (Dec)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
type t = int64 | ||
|
||
val pp_binary_int : | ||
flags:Flags.flags -> min_width:int -> Format.formatter -> int64 -> unit | ||
(** [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 -> int64 -> unit | ||
(** [pp_binary_int ~flags ~min_width fmt n] prints the integer [n] on the formatter [fmt]. *) | ||
|
||
val make_pp_int : | ||
?flags:Flags.flags -> ?min_width:int -> unit -> Format.formatter -> int64 -> unit | ||
(** [make_pp_int ?flags ?min_width ()] is just [pp_binary_int ~flags | ||
~min_width], but [flags] and [min_width] are optional. If omitted default | ||
values of [Flags.default] and [1] are passed to pp_binary_int. This version | ||
is nicer to with with the [Format] or [Fmt] modules. *) | ||
|
||
val to_string_with : flags:Flags.flags -> min_width:int -> int64 -> 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 : int64 -> string | ||
(** [to_string n] converts the integer [n] to a binary integer [n]. *) | ||
|
||
val make_to_string : | ||
?flags:Flags.flags -> ?min_width:int -> unit -> int64 -> string | ||
(** [make_to_string ?flags ?min_width ()] is just [to_string_with ~flags | ||
~min_width], but [flags] and [min_width] are optional. If omitted default | ||
values of [Flags.default] and [1] are passed to to_string_with. *) |
Oops, something went wrong.