2019-05-13 00:56:22 +04:00
|
|
|
open Trace
|
|
|
|
open Mini_c
|
|
|
|
open Environment
|
2019-05-13 16:20:23 +04:00
|
|
|
open Michelson
|
2019-05-13 00:56:22 +04:00
|
|
|
|
2019-09-10 17:19:15 +04:00
|
|
|
let empty : environment = []
|
|
|
|
|
2019-05-13 00:56:22 +04:00
|
|
|
let get : environment -> string -> michelson result = fun e s ->
|
2019-08-21 00:51:16 +04:00
|
|
|
let%bind (_ , position) =
|
2019-05-13 00:56:22 +04:00
|
|
|
let error =
|
|
|
|
let title () = "Environment.get" in
|
|
|
|
let content () = Format.asprintf "%s in %a"
|
|
|
|
s PP.environment e in
|
|
|
|
error title content in
|
|
|
|
generic_try error @@
|
|
|
|
(fun () -> Environment.get_i s e) in
|
2019-10-17 17:48:24 +04:00
|
|
|
let rec aux_bubble = fun n ->
|
2019-05-13 00:56:22 +04:00
|
|
|
match n with
|
|
|
|
| 0 -> i_dup
|
|
|
|
| n -> seq [
|
2019-10-17 17:48:24 +04:00
|
|
|
dip @@ aux_bubble (n - 1) ;
|
2019-05-13 00:56:22 +04:00
|
|
|
i_swap ;
|
|
|
|
]
|
|
|
|
in
|
2019-10-17 17:48:24 +04:00
|
|
|
let aux_dig = fun n -> seq [
|
|
|
|
dipn n i_dup ;
|
|
|
|
i_dig n ;
|
|
|
|
]
|
|
|
|
in
|
|
|
|
let code =
|
|
|
|
if position < 2
|
|
|
|
then aux_bubble position
|
|
|
|
else aux_dig position in
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
ok code
|
|
|
|
|
|
|
|
let set : environment -> string -> michelson result = fun e s ->
|
2019-08-21 00:51:16 +04:00
|
|
|
let%bind (_ , position) =
|
2019-10-17 17:48:24 +04:00
|
|
|
generic_try (simple_error "Environment.set") @@
|
2019-05-13 00:56:22 +04:00
|
|
|
(fun () -> Environment.get_i s e) in
|
2019-10-17 17:48:24 +04:00
|
|
|
let rec aux_bubble = fun n ->
|
2019-05-13 00:56:22 +04:00
|
|
|
match n with
|
|
|
|
| 0 -> dip i_drop
|
|
|
|
| n -> seq [
|
|
|
|
i_swap ;
|
2019-10-17 17:48:24 +04:00
|
|
|
dip (aux_bubble (n - 1)) ;
|
2019-05-13 00:56:22 +04:00
|
|
|
]
|
|
|
|
in
|
2019-10-17 17:48:24 +04:00
|
|
|
let aux_dug = fun n -> seq [
|
|
|
|
dipn (n + 1) i_drop ;
|
|
|
|
i_dug n ;
|
|
|
|
] in
|
|
|
|
let code =
|
|
|
|
if position < 2
|
|
|
|
then aux_bubble position
|
|
|
|
else aux_dug position in
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
ok code
|
2019-08-21 12:28:27 +04:00
|
|
|
|
|
|
|
let pack_closure : environment -> selector -> michelson result = fun e lst ->
|
|
|
|
let%bind () = Assert.assert_true (e <> []) in
|
|
|
|
|
|
|
|
(* Tag environment with selected elements. Only the first occurence
|
|
|
|
of each name from the selector in the environment is kept. *)
|
|
|
|
let e_lst =
|
|
|
|
let e_lst = Environment.to_list e in
|
|
|
|
let aux selector (s , _) =
|
|
|
|
match List.mem s selector with
|
|
|
|
| true -> List.remove_element s selector , true
|
|
|
|
| false -> selector , false in
|
|
|
|
let e_lst' = List.fold_map_right aux lst e_lst in
|
|
|
|
let e_lst'' = List.combine e_lst e_lst' in
|
|
|
|
e_lst''
|
|
|
|
in
|
|
|
|
|
|
|
|
let (_ , code) =
|
|
|
|
let aux = fun (first , code) (_ , b) ->
|
|
|
|
match b with
|
|
|
|
| false -> (first , seq [dip code ; i_swap])
|
|
|
|
| true -> (false ,
|
|
|
|
match first with
|
|
|
|
| true -> i_dup
|
|
|
|
| false -> seq [dip code ; i_dup ; dip i_pair ; i_swap]
|
|
|
|
)
|
|
|
|
in
|
|
|
|
List.fold_right' aux (true , seq []) e_lst in
|
|
|
|
|
|
|
|
ok code
|
|
|
|
|
|
|
|
let unpack_closure : environment -> michelson result = fun e ->
|
2019-08-21 18:34:39 +04:00
|
|
|
let aux = fun code _ -> seq [ i_unpair ; dip code ] in
|
|
|
|
ok (List.fold_right' aux (seq []) e)
|