The example files, in full, are available in this
gist.
We start from a basic, meaningless, but didactic piece of Michelson:
parameter
(or
(address %ep1)
(or
(signature %sign_stuff)
(unit %default)));
storage
(pair
(pair
(nat %some_counter)
(string %some_name))
(or %a_variant_thing (bytes %some_data) (key %the_key)));
code {FAILWITH};
The code { }
section is irrelevant for this example, hence we just use
FAILWITH
.
One generates the corresponding OCaml code with:
flextesa ocaml-of-michel example.tz example.ml
ocamlformat -i --enable-out example.ml
ocamlformat
is icing on the cake for code-generators which do not need to
care about pretty-printing any more.
In the case of a whole contract (likely most common), we generate
one Parameter
and one Storage
sub-modules, following all their
dependencies down to representations of Michelson primitive types
(called M_*
).
Here we see the corresponding parameter type:
type t =
| Default of M_unit.t
| Ep1 of M_address.t
| Sign_stuff of M_signature.t
[@@deriving show, eq]
→ the code generator has reconstructed an OCaml
variant from the
annotations of multiple or
s of the parameter-type (a.k.a. “entry-points” 😉,
cf. example.tz l. 2). It has also assigned a couple of
ppx_deriving
AST-attributes.
Similarly records are reconstructed from “pairs of pairs” for the storage
type, and an intermediary A_variant_thing
module has been created for the more
complex type of the field %a_variant_thing
:
module Storage = struct
open! Result_extras
type t = {
a_variant_thing : A_variant_thing.t;
some_counter : M_nat.t;
some_name : M_string.t;
}
[@@deriving show, eq, make]
let layout () : Pairing_layout.t = `P (`P (`V, `V), `V)
We also see the value layout
which remembers how the arrangement of pairs
is in the original Michelson.
For now, the code-generator creates to_concrete
and of_json
functions which
are helpful to generate tezos-client
commands and to parse the results of RPCs
respectively. In the case of variants, a special to_concrete_entry_point
which
returns an entry-point name and its parameter (hence without the Left/Right
“path”).
One can check the result of ocamlc -i example.ml
,
or better, of ocamlfind ocamlc -i example.ml -package ppx_deriving.std
to get,
and overview. See the module-type for Parameter
:
module Parameter :
sig
type t =
Default of M_unit.t
| Ep1 of M_address.t
| Sign_stuff of M_signature.t
val pp :
Ppx_deriving_runtime.Format.formatter -> t -> Ppx_deriving_runtime.unit
val show : t -> Ppx_deriving_runtime.string
val equal : t -> t -> Ppx_deriving_runtime.bool
val layout : unit -> Pairing_layout.t
val to_concrete : t -> string
val to_concrete_entry_point :
t -> [ `Name of string ] * [ `Literal of string ]
val of_json : Json_value.t -> (t, [> Json_value.parse_error ]) result
end