A new 0.9.3 relase is available. Still not 1.0.0 just in case. The change I’m most glad I managed to make is that the lexer is now re-entrant and doesn’t use any mutable state. Where can I apply for the “Designed for multicore OCaml” certification sticker?
Breaking change in the functor interface
I found an oversight that took a breaking change to fix. It didn’t break any package that was already in the OPAM repository, so I’m glad I noticed it before it caused anyone trouble.
My idea to make the functor take separate integer and float modules turned out to be misguided: it wouldn’t compose with Otoml.get_float ~strict:false
and similar functions that apply type conversions.
Logically, Otoml.get_float ~strict:false (Otoml.integer 5)
should produce Otoml.TomlFloat 5.0
. However, it means that get_float
needs to know how to convert integers to float. If integer and float types are in separate modules, that isn’t possible.
So I combined both integers and floats in a single TomlNumber
. That way people who want to bring their own bignum libraries will have to write more code, but numbers will behave as they are expected to in a dynamically typed format.
module BigNumber = struct
type int = Z.t
type float = Decimal.t
let int_of_string = Z.of_string
let int_to_string = Z.to_string
let int_of_boolean b = if b then Z.one else Z.zero
let int_to_boolean n = (n <> Z.zero)
(* Can't just reuse Decimal.to/of_string because their optional arguments
would cause a signature mismatch. *)
let float_of_string s = Decimal.of_string s
(* Decimal.to_string uses "NaN" spelling
while TOML requires all special float values to be lowercase. *)
let float_to_string x = Decimal.to_string x |> String.lowercase_ascii
let float_of_boolean b = if b then Decimal.one else Decimal.zero
let float_to_boolean x = (x <> Decimal.zero)
let float_of_int = Decimal.of_bigint
let int_of_float = Decimal.to_bigint
end
module Otoml = Otoml.Base.Make (BigNumber) (Otoml.Base.StringDate)
The next release will likely be 1.0.0 for real.