diff --git a/src/bin/cli.ml b/src/bin/cli.ml index 11777b504..fd3fa05be 100644 --- a/src/bin/cli.ml +++ b/src/bin/cli.ml @@ -37,6 +37,14 @@ let syntax = info ~docv ~doc ["syntax" ; "s"] in value @@ opt string "auto" info +let bigmap = + let open Arg in + let info = + let docv = "BIGMAP" in + let doc = "$(docv) is necessary when your storage embeds a big_map." in + info ~docv ~doc ["bigmap"] in + value @@ flag info + let amount = let open Arg in let info = @@ -76,30 +84,30 @@ let compile_parameter = (term , Term.info ~docs cmdname) let compile_storage = - let f source entry_point expression syntax = + let f source entry_point expression syntax bigmap = toplevel @@ let%bind value = trace (simple_error "compile-storage") @@ - Ligo.Run.compile_contract_storage source entry_point expression (Syntax_name syntax) in + Ligo.Run.compile_contract_storage ?bigmap:(Some bigmap) source entry_point expression (Syntax_name syntax) in Format.printf "%s\n" value; ok () in let term = - Term.(const f $ source 0 $ entry_point 1 $ expression "STORAGE" 2 $ syntax) in + Term.(const f $ source 0 $ entry_point 1 $ expression "STORAGE" 2 $ syntax $ bigmap) in let cmdname = "compile-storage" in let docs = "Subcommand: compile an initial storage in ligo syntax to a michelson expression. The resulting michelson expression can be passed as an argument in a transaction which originates a contract. See `ligo " ^ cmdname ^ " --help' for a list of options specific to this subcommand." in (term , Term.info ~docs cmdname) let dry_run = - let f source entry_point storage input amount syntax = + let f source entry_point storage input bigmap amount syntax = toplevel @@ let%bind output = - Ligo.Run.run_contract ~amount source entry_point storage input (Syntax_name syntax) in + Ligo.Run.run_contract ~bigmap ~amount source entry_point storage input (Syntax_name syntax) in Format.printf "%a\n" Ast_simplified.PP.expression output ; ok () in let term = - Term.(const f $ source 0 $ entry_point 1 $ expression "PARAMETER" 2 $ expression "STORAGE" 3 $ amount $ syntax) in + Term.(const f $ source 0 $ entry_point 1 $ expression "PARAMETER" 2 $ expression "STORAGE" 3 $ bigmap $ amount $ syntax) in let cmdname = "dry-run" in let docs = "Subcommand: run a smart-contract with the given storage and input." in (term , Term.info ~docs cmdname) diff --git a/src/contracts/big_map.ligo b/src/contracts/big_map.ligo index b5f6d44c5..461c2c206 100644 --- a/src/contracts/big_map.ligo +++ b/src/contracts/big_map.ligo @@ -5,6 +5,7 @@ function main(const p : unit; const s : storage_) : list(operation) * storage_ i var toto : option (int) := Some(0); block { toto := r[23]; + r[2] := 444; s.0 := r; } with ((nil: list(operation)), s) diff --git a/src/main/run_source.ml b/src/main/run_source.ml index 10904914a..71f7d3b55 100644 --- a/src/main/run_source.ml +++ b/src/main/run_source.ml @@ -46,6 +46,17 @@ include struct ok () end +let transpile_value_literals + (e:Ast_typed.annotated_expression) : (Mini_c.value * _) result = + let%bind (_ , ty) = + let open Transpiler in + let (f , _) = functionalize e in + let%bind main = translate_main f e.location in + ok main + in + let%bind lit = Run_typed.convert_to_literals e in + ok (lit , snd ty) + let transpile_value (e:Ast_typed.annotated_expression) : (Mini_c.value * _) result = let%bind (f , ty) = @@ -196,8 +207,20 @@ let compile_contract_parameter : string -> string -> string -> s_syntax -> strin in ok expr +(* Replace occurrences of E_map with E_big_map in the AST *) +let rec transform_map_to_big_map (e: Ast_simplified.expression) : Ast_simplified.expression result = + let open Ast_simplified in + match e.wrap_content with + | E_tuple [fst;snd] -> + let%bind tr_fst = transform_map_to_big_map fst in + let new_tuple = Location.wrap (E_tuple [tr_fst;snd]) in + ok @@ new_tuple + | E_map lst -> + let tr_map = Location.wrap (E_big_map lst) in + ok @@ tr_map + | _ -> fail @@ simple_error "can not replace map with big_map" -let compile_contract_storage : string -> string -> string -> s_syntax -> string result = fun source_filename entry_point expression syntax -> +let compile_contract_storage ?(bigmap = false) source_filename entry_point expression syntax : string result = let%bind syntax = syntax_to_variant syntax (Some source_filename) in let%bind (program , storage_tv) = let%bind simplified = parsify syntax source_filename in @@ -212,6 +235,7 @@ let compile_contract_storage : string -> string -> string -> s_syntax -> string in let%bind expr = let%bind simplified = parsify_expression syntax expression in + let%bind simplified = if bigmap then transform_map_to_big_map simplified else ok @@ simplified in let%bind typed = let env = let last_declaration = Location.unwrap List.(hd @@ rev program) in @@ -225,7 +249,7 @@ let compile_contract_storage : string -> string -> string -> s_syntax -> string Ast_typed.assert_type_value_eq (storage_tv , typed.type_annotation) in let%bind (mini_c , mini_c_ty) = trace (simple_error "transpiling expression") @@ - transpile_value typed in + (if bigmap then transpile_value_literals typed else transpile_value typed) in let%bind michelson = trace (simple_error "compiling expression") @@ Compiler.translate_value mini_c mini_c_ty in @@ -249,7 +273,7 @@ let type_file ?(debug_simplify = false) ?(debug_typed = false) )) ; ok typed -let run_contract ?amount source_filename entry_point storage input syntax = +let run_contract ?(bigmap = false) ?amount source_filename entry_point storage input syntax = let%bind syntax = syntax_to_variant syntax (Some source_filename) in let%bind typed = type_file syntax source_filename in @@ -257,11 +281,12 @@ let run_contract ?amount source_filename entry_point storage input syntax = parsify_expression syntax storage in let%bind input_simpl = parsify_expression syntax input in + let%bind input_simpl = if bigmap then transform_map_to_big_map input_simpl else ok @@ input_simpl in let options = let open Proto_alpha_utils.Memory_proto_alpha in let amount = Option.bind (fun amount -> Protocol.Alpha_context.Tez.of_string amount) amount in (make_options ?amount ()) in - Run_simplified.run_simplityped ~options typed entry_point (Ast_simplified.e_pair storage_simpl input_simpl) + Run_simplified.run_simplityped ?input_to_value:(Some bigmap) ~options typed entry_point (Ast_simplified.e_pair storage_simpl input_simpl) let run_function ?amount source_filename entry_point parameter syntax = let%bind syntax = syntax_to_variant syntax (Some source_filename) in diff --git a/src/main/run_typed.ml b/src/main/run_typed.ml index 9c5157c27..aef51cd56 100644 --- a/src/main/run_typed.ml +++ b/src/main/run_typed.ml @@ -30,7 +30,7 @@ let evaluate_typed Transpiler.untranspile result typed_main.type_annotation in ok typed_result -(* returns a big_map if any *) +(* returns a big_map if any. used to reconstruct the map from the diff when uncompiling *) let rec fetch_big_map (v: Mini_c.value) : Mini_c.value option = match v with | D_pair (l , r) -> @@ -40,7 +40,7 @@ let rec fetch_big_map (v: Mini_c.value) : Mini_c.value option = | None -> fetch_big_map r end | D_big_map _ as bm -> Some bm - | _ -> let () = Printf.printf "lal\n" in None + | _ -> None (* try to convert expression to a literal *) let rec exp_to_value (exp: Mini_c.expression) : Mini_c.value result = @@ -67,6 +67,7 @@ let rec exp_to_value (exp: Mini_c.expression) : Mini_c.value result = let%bind fstl = exp_to_value fst in let%bind sndl = exp_to_value snd in ok @@ D_pair (fstl , sndl) + | E_constant ("UNIT", _) -> ok @@ D_unit | E_constant ("UPDATE", _) -> let rec handle_prev upd = match upd.content with