type:internal
%external
Implement a library using This MR implements two libraries using %external
: stdlib and testlib.
The library stdlib comprises the modules Tezos
, Map
, Big_map
, List
, Set
, Option
, Bitwise
.
The library testlib comprises only the Test
module.
The code looks a bit like (see build/stdlib.ml
):
module Tezos = struct
[@thunk] [@hidden] [@inline] let balance : tez = [%external "BALANCE"]
[@hidden] [@inline] let voting_power (kh : key_hash) : nat = [%external "VOTING_POWER"] kh
...
end
The %external
insertions (represented with an E_raw_code { language = "external" ; _ }
) are replaced by the corresponding E_constant
in the pass 05-self_ast_imperative
(external.ml
).
Needed changes:
- Abstraction: when we had a
M.f
, whereM
was one of the predefined modules, we had some special handling. This MR modifies the abstraction so that it works as a regular module access. - Having in the library
let balance = [%external "BALANCE"]
forces an evaluation ofBALANCE
in the interpreter (I think we should change the type ofbalance
to beunit -> tez
instead of justtez
, but that's left to another MR). To prevent that, a new attribute was added@thunk
, that makebalance
not to evaluate in the interpreter (V_Thunk
values), and also force inlining in the compiling (15-self_mini_c
). - Had to move
CREATE_CONTRACT
check of free variables to15-self_mini_c
: now stdlib functions likefailwith
are free variables (in theTezos.create_contract
argument). So I moved the check tomini-c
, after inlining has been done.
There are two versions of the test library. A real one, and one that's used when we are not in the testing framework, in which everything fails. This is needed to keep remove_unused
working.
TODO (future MRs?):
- Improve the representation of libs (
src/main/build/stdlib.ml
/testlib.ml
), we could write it in a.ligo
file directly and include it as a resource, or compile it as an sexp, and prevent recompilation each time we load it. - Hack in monomorphisation:
(* TODO: This is a hack needed for external typers, as they keep information *)
-> find a more principled way of doing this. EDIT: after discussion with @lesenechal.remi , this hack has been improved. - Handle operations
+
,-
,*
, etc. in the same way (right now the abstractors for each language do custom things?)
Changelog details:
Breaking changes
- Less lenient on the usage of
Map
andBig_map
functions (e.g.Map.update
will only work onmap
s and not onbig_map
s as before)