2019-05-13 00:56:22 +04:00
|
|
|
open Mini_c.Types
|
2019-09-05 17:21:01 +04:00
|
|
|
open Proto_alpha_utils.Memory_proto_alpha
|
|
|
|
open X
|
2019-05-13 16:20:23 +04:00
|
|
|
open Proto_alpha_utils.Trace
|
2019-09-05 17:21:01 +04:00
|
|
|
open Protocol
|
2019-05-13 00:56:22 +04:00
|
|
|
open Script_typed_ir
|
|
|
|
open Script_ir_translator
|
|
|
|
|
2019-09-13 22:30:09 +04:00
|
|
|
let rec translate_value ?bm_opt (Ex_typed_value (ty, value)) : value result =
|
2019-05-13 00:56:22 +04:00
|
|
|
match (ty, value) with
|
2019-10-17 13:45:27 +04:00
|
|
|
| Pair_t ((a_ty, _, _), (b_ty, _, _), _ , _), (a, b) -> (
|
2019-09-13 22:30:09 +04:00
|
|
|
let%bind a = translate_value ?bm_opt @@ Ex_typed_value(a_ty, a) in
|
|
|
|
let%bind b = translate_value ?bm_opt @@ Ex_typed_value(b_ty, b) in
|
2019-05-13 00:56:22 +04:00
|
|
|
ok @@ D_pair(a, b)
|
|
|
|
)
|
2019-10-17 13:45:27 +04:00
|
|
|
| Union_t ((a_ty, _), _, _ , _), L a -> (
|
2019-09-13 22:30:09 +04:00
|
|
|
let%bind a = translate_value ?bm_opt @@ Ex_typed_value(a_ty, a) in
|
2019-05-13 00:56:22 +04:00
|
|
|
ok @@ D_left a
|
|
|
|
)
|
2019-10-17 13:45:27 +04:00
|
|
|
| Union_t (_, (b_ty, _), _ , _), R b -> (
|
2019-09-13 22:30:09 +04:00
|
|
|
let%bind b = translate_value ?bm_opt @@ Ex_typed_value(b_ty, b) in
|
2019-05-13 00:56:22 +04:00
|
|
|
ok @@ D_right b
|
|
|
|
)
|
|
|
|
| (Int_t _), n ->
|
|
|
|
let%bind n =
|
|
|
|
trace_option (simple_error "too big to fit an int") @@
|
|
|
|
Alpha_context.Script_int.to_int n in
|
|
|
|
ok @@ D_int n
|
|
|
|
| (Nat_t _), n ->
|
|
|
|
let%bind n =
|
|
|
|
trace_option (simple_error "too big to fit an int") @@
|
|
|
|
Alpha_context.Script_int.to_int n in
|
|
|
|
ok @@ D_nat n
|
2019-06-10 13:58:16 +04:00
|
|
|
| (Timestamp_t _), n ->
|
|
|
|
let n =
|
|
|
|
Z.to_int @@
|
|
|
|
Alpha_context.Script_timestamp.to_zint n in
|
|
|
|
ok @@ D_timestamp n
|
2019-05-13 00:56:22 +04:00
|
|
|
| (Mutez_t _), n ->
|
|
|
|
let%bind n =
|
|
|
|
generic_try (simple_error "too big to fit an int") @@
|
|
|
|
(fun () -> Int64.to_int @@ Alpha_context.Tez.to_mutez n) in
|
2019-09-24 16:29:18 +04:00
|
|
|
ok @@ D_mutez n
|
2019-05-13 00:56:22 +04:00
|
|
|
| (Bool_t _), b ->
|
|
|
|
ok @@ D_bool b
|
|
|
|
| (String_t _), s ->
|
|
|
|
ok @@ D_string s
|
2019-09-07 20:42:59 +04:00
|
|
|
| (Bytes_t _), b ->
|
|
|
|
ok @@ D_bytes (Tezos_stdlib.MBytes.to_bytes b)
|
2019-10-17 13:45:27 +04:00
|
|
|
| (Address_t _), (s , _) ->
|
2019-05-13 00:56:22 +04:00
|
|
|
ok @@ D_string (Alpha_context.Contract.to_b58check s)
|
|
|
|
| (Unit_t _), () ->
|
|
|
|
ok @@ D_unit
|
|
|
|
| (Option_t _), None ->
|
|
|
|
ok @@ D_none
|
2019-10-17 13:45:27 +04:00
|
|
|
| (Option_t (o_ty, _, _)), Some s ->
|
2019-05-13 00:56:22 +04:00
|
|
|
let%bind s' = translate_value @@ Ex_typed_value (o_ty, s) in
|
|
|
|
ok @@ D_some s'
|
2019-10-17 13:45:27 +04:00
|
|
|
| (Map_t (k_cty, v_ty, _ , _)), m ->
|
2019-05-13 00:56:22 +04:00
|
|
|
let k_ty = Script_ir_translator.ty_of_comparable_ty k_cty in
|
|
|
|
let lst =
|
|
|
|
let aux k v acc = (k, v) :: acc in
|
|
|
|
let lst = Script_ir_translator.map_fold aux m [] in
|
|
|
|
List.rev lst in
|
|
|
|
let%bind lst' =
|
|
|
|
let aux (k, v) =
|
|
|
|
let%bind k' = translate_value (Ex_typed_value (k_ty, k)) in
|
|
|
|
let%bind v' = translate_value (Ex_typed_value (v_ty, v)) in
|
|
|
|
ok (k', v')
|
|
|
|
in
|
|
|
|
bind_map_list aux lst
|
|
|
|
in
|
|
|
|
ok @@ D_map lst'
|
2019-09-13 22:30:09 +04:00
|
|
|
| (Big_map_t (k_cty, v_ty, _)), m ->
|
|
|
|
let k_ty = Script_ir_translator.ty_of_comparable_ty k_cty in
|
|
|
|
let lst =
|
|
|
|
let aux k v acc = (k, v) :: acc in
|
|
|
|
let lst = Script_ir_translator.map_fold aux m.diff [] in
|
|
|
|
List.rev lst in
|
2019-09-23 01:39:15 +04:00
|
|
|
let%bind original_big_map =
|
2019-09-13 22:30:09 +04:00
|
|
|
match bm_opt with
|
|
|
|
| Some (D_big_map l) -> ok @@ l
|
2019-09-23 01:39:15 +04:00
|
|
|
| _ -> ok []
|
|
|
|
(* | _ -> fail @@ simple_error "Do not have access to the original big_map" . When does this matter? *)
|
|
|
|
in
|
2019-09-13 22:30:09 +04:00
|
|
|
let%bind lst' =
|
|
|
|
let aux orig (k, v) =
|
|
|
|
let%bind k' = translate_value (Ex_typed_value (k_ty, k)) in
|
|
|
|
let orig_rem = List.remove_assoc k' orig in
|
|
|
|
match v with
|
|
|
|
| Some vadd ->
|
|
|
|
let%bind v' = translate_value (Ex_typed_value (v_ty, vadd)) in
|
|
|
|
if (List.mem_assoc k' orig) then ok @@ (k', v')::orig_rem
|
|
|
|
else ok @@ (k', v')::orig
|
|
|
|
| None -> ok orig_rem in
|
|
|
|
bind_fold_list aux original_big_map lst in
|
|
|
|
ok @@ D_big_map lst'
|
2019-10-17 13:45:27 +04:00
|
|
|
| (List_t (ty, _ , _)), lst ->
|
2019-07-20 18:18:50 +04:00
|
|
|
let%bind lst' =
|
2019-05-13 00:56:22 +04:00
|
|
|
let aux = fun t -> translate_value (Ex_typed_value (ty, t)) in
|
2019-07-20 18:18:50 +04:00
|
|
|
bind_map_list aux lst
|
2019-05-13 00:56:22 +04:00
|
|
|
in
|
2019-07-20 18:18:50 +04:00
|
|
|
ok @@ D_list lst'
|
2019-06-11 04:52:09 +04:00
|
|
|
| (Set_t (ty, _)), (module S) -> (
|
|
|
|
let lst = S.OPS.elements S.boxed in
|
|
|
|
let lst' =
|
|
|
|
let aux acc cur = cur :: acc in
|
|
|
|
let lst = List.fold_left aux lst [] in
|
|
|
|
List.rev lst in
|
|
|
|
let%bind lst'' =
|
|
|
|
let aux = fun t -> translate_value (Ex_typed_value (ty_of_comparable_ty ty, t)) in
|
|
|
|
bind_map_list aux lst'
|
|
|
|
in
|
|
|
|
ok @@ D_set lst''
|
|
|
|
)
|
2019-10-17 13:45:27 +04:00
|
|
|
| (Operation_t _) , (op , _) ->
|
2019-05-13 00:56:22 +04:00
|
|
|
ok @@ D_operation op
|
|
|
|
| ty, v ->
|
|
|
|
let%bind error =
|
|
|
|
let%bind m_data =
|
|
|
|
trace_tzresult_lwt (simple_error "unparsing unrecognized data") @@
|
2019-05-13 16:20:23 +04:00
|
|
|
Proto_alpha_utils.Memory_proto_alpha.unparse_michelson_data ty v in
|
2019-05-13 00:56:22 +04:00
|
|
|
let%bind m_ty =
|
|
|
|
trace_tzresult_lwt (simple_error "unparsing unrecognized data") @@
|
2019-05-13 16:20:23 +04:00
|
|
|
Proto_alpha_utils.Memory_proto_alpha.unparse_michelson_ty ty in
|
2019-05-13 00:56:22 +04:00
|
|
|
let error_content () =
|
|
|
|
Format.asprintf "%a : %a"
|
|
|
|
Michelson.pp m_data
|
|
|
|
Michelson.pp m_ty in
|
|
|
|
ok @@ (fun () -> error (thunk "this value can't be transpiled back yet") error_content ())
|
|
|
|
in
|
|
|
|
fail error
|