diff --git a/src/main/compile/of_mini_c.ml b/src/main/compile/of_mini_c.ml index 3e36432b5..3b86631ed 100644 --- a/src/main/compile/of_mini_c.ml +++ b/src/main/compile/of_mini_c.ml @@ -3,37 +3,6 @@ open Tezos_utils open Proto_alpha_utils open Trace -let compile_expression_as_function : expression -> Compiler.compiled_program result = fun e -> - let (input , output) = t_unit , e.type_value in - let%bind body = Compiler.Program.translate_expression e Compiler.Environment.empty in - let body = Self_michelson.optimize body in - let body = Michelson.(seq [ i_drop ; body ]) in - let%bind (input , output) = bind_map_pair Compiler.Type.Ty.type_ (input , output) in - let open! Compiler.Program in - ok { input ; output ; body } - -let compile_function : expression -> Compiler.compiled_program result = fun e -> - let%bind (input , output) = get_t_function e.type_value in - let%bind body = get_function e in - let%bind body = Compiler.Program.translate_function_body body [] input in - let body = Self_michelson.optimize body in - let%bind (input , output) = bind_map_pair Compiler.Type.Ty.type_ (input , output) in - let open! Compiler.Program in - ok { input ; output ; body } - -let compile_expression_as_function_entry = fun program name -> - let%bind aggregated = aggregate_entry program name true in - let aggregated = Self_mini_c.all_expression aggregated in - compile_function aggregated - -let compile_function_entry = fun program name -> - let%bind aggregated = aggregate_entry program name false in - let aggregated = Self_mini_c.all_expression aggregated in - compile_function aggregated - -(* new *) - -(*TODO rename to compile_function ; see if can be merge with compile expression ? do the same match as in get_t_function and done. ? *) let compile_function_expression : expression -> Compiler.compiled_expression result = fun e -> let%bind (input_ty , _) = get_t_function e.type_value in let%bind body = get_function e in @@ -50,6 +19,19 @@ let compile_expression : expression -> Compiler.compiled_expression result = fun let open! Compiler.Program in ok { expr_ty ; expr } +(* let compile_function_expression_merged : expression -> Compiler.compiled_expression result = fun e -> + let%bind body = match e.type_value with + | T_function (input_ty, _) -> + let%bind body = get_function e in + Compiler.Program.translate_function_body body [] input_ty + | _ -> + Compiler.Program.translate_expression e Compiler.Environment.empty + in + let expr = Self_michelson.optimize body in + let%bind expr_ty = Compiler.Type.Ty.type_ e.type_value in + let open! Compiler.Program in + ok { expr_ty ; expr } *) + let aggregate_and_compile_function = fun program name -> let%bind aggregated = aggregate_entry program name false in let aggregated = Self_mini_c.all_expression aggregated in diff --git a/src/main/compile/wrapper.ml b/src/main/compile/wrapper.ml index f3e7c8fe6..1c25e883b 100644 --- a/src/main/compile/wrapper.ml +++ b/src/main/compile/wrapper.ml @@ -1,6 +1,5 @@ open Trace -(* will keep *) let source_to_typed syntax source_file = let%bind simplified = Of_source.compile source_file syntax in let%bind typed,state = Of_simplified.compile simplified in @@ -11,44 +10,13 @@ let source_to_typed_expression ~env ~state parameter syntax = let%bind simplified = Of_source.compile_expression syntax parameter in let%bind (typed,_) = Of_simplified.compile_expression ~env ~state simplified in ok typed -(* will keep *) -let typed_to_michelson_program - (typed: Ast_typed.program) (entry_point:string) : Compiler.compiled_program result = - let%bind mini_c = Of_typed.compile typed in - Of_mini_c.compile_function_entry mini_c entry_point - -let typed_to_michelson_value_as_function - (typed: Ast_typed.program) (entry_point:string) : Compiler.compiled_program result = - let%bind mini_c = Of_typed.compile typed in - Of_mini_c.compile_expression_as_function_entry mini_c entry_point - -let typed_expression_to_michelson_value_as_function - (typed: Ast_typed.annotated_expression) : Compiler.compiled_program result = - let%bind mini_c = Of_typed.compile_expression typed in - Of_mini_c.compile_expression_as_function mini_c - -let simplified_to_compiled_program - ~env ~state (exp: Ast_simplified.expression) : Compiler.compiled_program result = - let%bind (typed,_) = Of_simplified.compile_expression ~env ~state exp in - typed_expression_to_michelson_value_as_function typed - -let source_expression_to_michelson_value_as_function ~env ~state parameter syntax = - let%bind typed = source_to_typed_expression ~env ~state parameter syntax in - let%bind mini_c = Of_typed.compile_expression typed in - Of_mini_c.compile_expression_as_function mini_c - -let source_contract_input_to_michelson_value_as_function ~env ~state (storage,parameter) syntax = - let%bind simplified = Of_source.compile_contract_input storage parameter syntax in - let%bind typed,_ = Of_simplified.compile_expression ~env ~state simplified in - typed_expression_to_michelson_value_as_function typed - -(* new *) let typed_to_michelson_fun (typed: Ast_typed.program) (entry_point:string) : Compiler.compiled_expression result = let%bind mini_c = Of_typed.compile typed in Of_mini_c.aggregate_and_compile_function mini_c entry_point +(* fetches entry_point and transform it into a let .. in let .. in expression *) let typed_to_michelson_expression (typed: Ast_typed.program) (entry_point:string) : Compiler.compiled_expression result = let%bind mini_c = Of_typed.compile typed in diff --git a/src/main/run/of_michelson.ml b/src/main/run/of_michelson.ml index 23af1aab4..e619067af 100644 --- a/src/main/run/of_michelson.ml +++ b/src/main/run/of_michelson.ml @@ -1,11 +1,19 @@ open Proto_alpha_utils open Trace -open Compiler.Program open Memory_proto_alpha.Protocol.Script_ir_translator open Memory_proto_alpha.X type options = Memory_proto_alpha.options +type run_function_res = + | Success of ex_typed_value + | Fail of Memory_proto_alpha.Protocol.Script_repr.expr + +type run_failwith_res = + | Failwith_int of int + | Failwith_string of string + | Failwith_bytes of bytes + type dry_run_options = { amount : string ; sender : string option ; @@ -38,83 +46,11 @@ let make_dry_run_options (opts : dry_run_options) : options result = ok (Some source) in ok @@ make_options ~amount ?source:sender ?payer:source () -let run ?options (* ?(is_input_value = false) *) (program:compiled_program) (input_michelson:Michelson.t) : ex_typed_value result = - let Compiler.Program.{input;output;body} : compiled_program = program in - let (Ex_ty input_ty) = input in - let (Ex_ty output_ty) = output in - (* let%bind input_ty_mich = - Trace.trace_tzresult_lwt (simple_error "error unparsing input ty") @@ - Memory_proto_alpha.unparse_michelson_ty input_ty in - let%bind output_ty_mich = - Trace.trace_tzresult_lwt (simple_error "error unparsing output ty") @@ - Memory_proto_alpha.unparse_michelson_ty output_ty in - Format.printf "code: %a\n" Michelson.pp program.body ; - Format.printf "input_ty: %a\n" Michelson.pp input_ty_mich ; - Format.printf "output_ty: %a\n" Michelson.pp output_ty_mich ; - Format.printf "input: %a\n" Michelson.pp input_michelson ; *) - let%bind input = - Trace.trace_tzresult_lwt (simple_error "error parsing input") @@ - Memory_proto_alpha.parse_michelson_data input_michelson input_ty - in - let body = Michelson.strip_annots body in - let open! Memory_proto_alpha.Protocol.Script_ir_translator in - let top_level = Toplevel { storage_type = output_ty ; param_type = input_ty ; - root_name = None ; legacy_create_contract_literal = false } in - let%bind descr = - Trace.trace_tzresult_lwt (simple_error "error parsing program code") @@ - Memory_proto_alpha.parse_michelson ~top_level body - (Item_t (input_ty, Empty_t, None)) (Item_t (output_ty, Empty_t, None)) in - let open! Memory_proto_alpha.Protocol.Script_interpreter in - let%bind (Item(output, Empty)) = - Trace.trace_tzresult_lwt (simple_error "error of execution") @@ - Memory_proto_alpha.interpret ?options descr (Item(input, Empty)) in - ok (Ex_typed_value (output_ty, output)) - -type failwith_res = - | Failwith_int of int - | Failwith_string of string - | Failwith_bytes of bytes - -let get_exec_error_aux ?options (program:compiled_program) (input_michelson:Michelson.t) : Memory_proto_alpha.Protocol.Script_repr.expr result = - let Compiler.Program.{input;output;body} : compiled_program = program in - let (Ex_ty input_ty) = input in - let (Ex_ty output_ty) = output in - let%bind input = - Trace.trace_tzresult_lwt (simple_error "error parsing input") @@ - Memory_proto_alpha.parse_michelson_data input_michelson input_ty - in - let body = Michelson.strip_annots body in - let%bind descr = - Trace.trace_tzresult_lwt (simple_error "error parsing program code") @@ - Memory_proto_alpha.parse_michelson body - (Item_t (input_ty, Empty_t, None)) (Item_t (output_ty, Empty_t, None)) in - let%bind err = - Trace.trace_tzresult_lwt (simple_error "unexpected error of execution") @@ - Memory_proto_alpha.failure_interpret ?options descr (Item(input, Empty)) in - match err with - | Memory_proto_alpha.Succeed _ -> simple_fail "an error of execution was expected" - | Memory_proto_alpha.Fail expr -> - ok expr - -let get_exec_error ?options (program:compiled_program) (input_michelson:Michelson.t) : failwith_res result = - let%bind expr = get_exec_error_aux ?options program input_michelson in - match Tezos_micheline.Micheline.root @@ Memory_proto_alpha.strings_of_prims expr with - | Int (_ , i) -> ok (Failwith_int (Z.to_int i)) - | String (_ , s) -> ok (Failwith_string s) - | Bytes (_,b) -> ok (Failwith_bytes b) - | _ -> simple_fail "Unknown failwith" - -let evaluate ?options program = run ?options program Michelson.d_unit - let ex_value_ty_to_michelson (v : ex_typed_value) : Michelson.t result = let (Ex_typed_value (value , ty)) = v in Trace.trace_tzresult_lwt (simple_error "error unparsing michelson result") @@ Memory_proto_alpha.unparse_michelson_data value ty -let evaluate_michelson ?options program = - let%bind etv = evaluate ?options program in - ex_value_ty_to_michelson etv - let pack_payload (payload:Michelson.t) ty = let%bind payload = Trace.trace_tzresult_lwt (simple_error "error parsing message") @@ @@ -124,14 +60,12 @@ let pack_payload (payload:Michelson.t) ty = Memory_proto_alpha.pack ty payload in ok @@ data -(* new *) let fetch_lambda_types (contract_ty:ex_ty) = match contract_ty with | Ex_ty (Lambda_t (in_ty, out_ty, _)) -> ok (Ex_ty in_ty, Ex_ty out_ty) | _ -> simple_fail "failed to fetch lambda types" -(* type run_res = Failwith of failwith_res | Success of ex_typed_value *) -let run_function ?options (exp:Michelson.t) (exp_type:ex_ty) (input_michelson:Michelson.t) (is_contract:bool) : ex_typed_value result = +let run_function_aux ?options (exp:Michelson.t) (exp_type:ex_ty) (input_michelson:Michelson.t) (is_contract:bool) : run_function_res result = let open! Tezos_raw_protocol_005_PsBabyM1 in let%bind (Ex_ty input_ty, Ex_ty output_ty) = fetch_lambda_types exp_type in let%bind input = @@ -150,12 +84,33 @@ let run_function ?options (exp:Michelson.t) (exp_type:ex_ty) (input_michelson:Mi Trace.trace_tzresult_lwt (simple_error "error parsing program code") @@ Memory_proto_alpha.parse_michelson ~top_level exp ty_stack_before ty_stack_after in let open! Memory_proto_alpha.Protocol.Script_interpreter in - let%bind (Item(output, Empty)) = + let%bind res = Trace.trace_tzresult_lwt (simple_error "error of execution") @@ - Memory_proto_alpha.interpret ?options descr + Memory_proto_alpha.failure_interpret ?options descr (Item(input, Empty)) - in - ok (Ex_typed_value (output_ty, output)) + in + match res with + | Memory_proto_alpha.Succeed stack -> + let (Item(output, Empty)) = stack in + ok @@ Success (Ex_typed_value (output_ty, output)) + | Memory_proto_alpha.Fail expr -> + ok (Fail expr) + +let run_function ?options (exp:Michelson.t) (exp_type:ex_ty) (input_michelson:Michelson.t) (is_contract:bool) : ex_typed_value result = + let%bind expr = run_function_aux ?options exp exp_type input_michelson is_contract in + match expr with + | Success res -> ok res + | _ -> simple_fail "Execution terminated with failwith" + +let run_failwith ?options (exp:Michelson.t) (exp_type:ex_ty) (input_michelson:Michelson.t) (is_contract:bool) : run_failwith_res result = + let%bind expr = run_function_aux ?options exp exp_type input_michelson is_contract in + match expr with + | Fail res -> ( match Tezos_micheline.Micheline.root @@ Memory_proto_alpha.strings_of_prims res with + | Int (_ , i) -> ok (Failwith_int (Z.to_int i)) + | String (_ , s) -> ok (Failwith_string s) + | Bytes (_,b) -> ok (Failwith_bytes b) + | _ -> simple_fail "Unknown failwith type" ) + | _ -> simple_fail "An error of execution was expected" let run_exp ?options (exp:Michelson.t) (exp_type:ex_ty) : ex_typed_value result = let open! Tezos_raw_protocol_005_PsBabyM1 in diff --git a/src/passes/8-compiler/compiler_program.ml b/src/passes/8-compiler/compiler_program.ml index 55c5a88f1..1c370b50a 100644 --- a/src/passes/8-compiler/compiler_program.ml +++ b/src/passes/8-compiler/compiler_program.ml @@ -449,54 +449,7 @@ and translate_function anon env input_ty output_ty : michelson result = i_apply ; ] - -type compiled_program = { - input : ex_ty ; - output : ex_ty ; - body : michelson ; -} - type compiled_expression = { expr_ty : ex_ty ; expr : michelson ; -} - -let get_main : program -> string -> (anon_function * _) result = fun p entry -> - let is_main ((( name , expr), _):toplevel_statement) = - match Combinators.Expression.(get_content expr , get_type expr)with - | (E_closure content , T_function ty) - when Var.equal name (Var.of_name entry) -> - Some (content , ty) - | _ -> None - in - let%bind main = - trace_option (simple_error "no functional entry") @@ - List.find_map is_main p - in - ok main - -let translate_program (p:program) (entry:string) : compiled_program result = - let%bind (main , (input , output)) = get_main p entry in - let%bind body = translate_function_body main [] input in - let%bind input = Compiler_type.Ty.type_ input in - let%bind output = Compiler_type.Ty.type_ output in - ok ({input;output;body}:compiled_program) - -let translate_entry (p:anon_function) ty : compiled_program result = - let (input , output) = ty in - let%bind body = - trace (simple_error "compile entry body") @@ - translate_function_body p [] input in - let%bind input = Compiler_type.Ty.type_ input in - let%bind output = Compiler_type.Ty.type_ output in - ok ({input;output;body}:compiled_program) - -let translate_contract : anon_function -> _ -> michelson result = fun f ty -> - let%bind compiled_program = - trace_strong (corner_case ~loc:__LOC__ "compiling") @@ - translate_entry f ty in - let%bind (param_ty , storage_ty) = Combinators.get_t_pair (fst ty) in - let%bind param_michelson = Compiler_type.type_ param_ty in - let%bind storage_michelson = Compiler_type.type_ storage_ty in - let contract = Michelson.contract param_michelson storage_michelson compiled_program.body in - ok contract +} \ No newline at end of file diff --git a/src/passes/8-compiler/compiler_program.mli b/src/passes/8-compiler/compiler_program.mli index 700c17e46..5573c3d9b 100644 --- a/src/passes/8-compiler/compiler_program.mli +++ b/src/passes/8-compiler/compiler_program.mli @@ -9,12 +9,6 @@ open Operators.Compiler module Contract_types = Meta_michelson.Types module Stack = Meta_michelson.Stack *) -type compiled_program = { - input : ex_ty ; - output : ex_ty ; - body : michelson ; -} - type compiled_expression = { expr_ty : ex_ty ; expr : michelson ; @@ -25,13 +19,6 @@ val translate_expression : expression -> environment -> michelson result val translate_function_body : anon_function -> environment_element list -> type_value -> michelson result val translate_value : value -> type_value -> michelson result -val translate_program : program -> string -> compiled_program result - - -val translate_contract : anon_function -> (type_value * type_value ) -> michelson result - -val translate_entry : anon_function -> type_value * type_value -> compiled_program result - (* open Operators.Compiler diff --git a/src/test/heap_tests.ml b/src/test/heap_tests.ml index 4d4223a32..dfe1d1ef7 100644 --- a/src/test/heap_tests.ml +++ b/src/test/heap_tests.ml @@ -48,10 +48,11 @@ let dummy n = ) let run_typed (entry_point:string) (program:Ast_typed.program) (input:Ast_typed.annotated_expression) = - let%bind program_mich = Compile.Wrapper.typed_to_michelson_program program entry_point in - let%bind input_mich = Compile.Wrapper.typed_expression_to_michelson_value_as_function input in - let%bind input_eval = Run.Of_michelson.evaluate_michelson input_mich in - let%bind res = Run.Of_michelson.run program_mich input_eval in + let%bind program_mich = Compile.Wrapper.typed_to_michelson_fun program entry_point in + let%bind input_mini_c = Compile.Of_typed.compile_expression input in + let%bind input_mich = Compile.Of_mini_c.compile_expression input_mini_c in + let%bind input_eval = Run.Of_michelson.evaluate_expression input_mich.expr input_mich.expr_ty in + let%bind res = Run.Of_michelson.run_function program_mich.expr program_mich.expr_ty input_eval false in let%bind output_type = let%bind entry_expression = Ast_typed.get_entry program entry_point in let%bind (_ , output_type) = Ast_typed.get_t_function entry_expression.type_annotation in diff --git a/src/test/test_helpers.ml b/src/test/test_helpers.ml index c5b2ef77d..e28f464ca 100644 --- a/src/test/test_helpers.ml +++ b/src/test/test_helpers.ml @@ -35,11 +35,13 @@ open Ast_simplified let pack_payload (program:Ast_typed.program) (payload:expression) : bytes result = let%bind code = let env = Ast_typed.program_environment program in - Compile.Wrapper.simplified_to_compiled_program - ~env ~state:(Typer.Solver.initial_state) payload in - let Compiler.Program.{input=_;output=(Ex_ty payload_ty);body=_} = code in + let%bind (typed,_) = Compile.Of_simplified.compile_expression + ~env ~state:(Typer.Solver.initial_state) payload in + let%bind mini_c = Compile.Of_typed.compile_expression typed in + Compile.Of_mini_c.compile_expression mini_c in + let (Ex_ty payload_ty) = code.expr_ty in let%bind (payload: Tezos_utils.Michelson.michelson) = - Ligo.Run.Of_michelson.evaluate_michelson code in + Ligo.Run.Of_michelson.evaluate_expression code.expr code.expr_ty in Ligo.Run.Of_michelson.pack_payload payload payload_ty let sign_message (program:Ast_typed.program) (payload : expression) sk : string result = @@ -76,31 +78,25 @@ let sha_256_hash pl = open Ast_simplified.Combinators +let typed_program_with_simplified_input_to_michelson + (program: Ast_typed.program) (entry_point: string) + (input: Ast_simplified.expression) : (Compiler.compiled_expression * Tezos_utils.Michelson.michelson) result = + let env = Ast_typed.program_environment program in + let%bind (typed_in,_) = Compile.Of_simplified.compile_expression ~env ~state:(Typer.Solver.initial_state) input in + let%bind mini_c_in = Compile.Of_typed.compile_expression typed_in in + let%bind michelson_in = Compile.Of_mini_c.compile_expression mini_c_in in + let%bind evaluated_in = Ligo.Run.Of_michelson.evaluate_expression michelson_in.expr michelson_in.expr_ty in + let%bind michelson_program = Compile.Wrapper.typed_to_michelson_fun program entry_point in + ok (michelson_program, evaluated_in) + let run_typed_program_with_simplified_input ?options (program: Ast_typed.program) (entry_point: string) (input: Ast_simplified.expression) : Ast_simplified.expression result = - let env = Ast_typed.program_environment program in - let%bind michelson_exp = Compile.Wrapper.simplified_to_compiled_program ~env ~state:(Typer.Solver.initial_state) input in - let%bind evaluated_exp = Ligo.Run.Of_michelson.evaluate_michelson michelson_exp in - let%bind michelson_program = Compile.Wrapper.typed_to_michelson_program program entry_point in - let%bind michelson_output = Ligo.Run.Of_michelson.run ?options michelson_program evaluated_exp in + let%bind (michelson_program, evaluated_in) = typed_program_with_simplified_input_to_michelson program entry_point input in + let%bind michelson_output = Ligo.Run.Of_michelson.run_function + ?options michelson_program.expr michelson_program.expr_ty evaluated_in false in Uncompile.uncompile_typed_program_entry_function_result program entry_point michelson_output -let expect_fail_typed_program_with_simplified_input ?options - (program: Ast_typed.program) (entry_point: string) - (input: Ast_simplified.expression) : Ligo.Run.Of_michelson.failwith_res Simple_utils__Trace.result = - let env = Ast_typed.program_environment program in - let%bind michelson_exp = Compile.Wrapper.simplified_to_compiled_program ~env ~state:(Typer.Solver.initial_state) input in - let%bind evaluated_exp = Ligo.Run.Of_michelson.evaluate_michelson michelson_exp in - let%bind michelson_program = Compile.Wrapper.typed_to_michelson_program program entry_point in - Ligo.Run.Of_michelson.get_exec_error ?options michelson_program evaluated_exp - -let run_typed_value_as_function - (program: Ast_typed.program) (entry_point:string) : Ast_simplified.expression result = - let%bind michelson_value_as_f = Compile.Wrapper.typed_to_michelson_expression program entry_point in - let%bind result = Ligo.Run.Of_michelson.run_exp michelson_value_as_f.expr michelson_value_as_f.expr_ty in - Uncompile.uncompile_typed_program_entry_expression_result program entry_point result - let expect ?options program entry_point input expecter = let%bind result = let run_error = @@ -124,7 +120,9 @@ let expect_fail ?options program entry_point input = run_typed_program_with_simplified_input ?options program entry_point input let expect_string_failwith ?options program entry_point input expected_failwith = - let%bind err = expect_fail_typed_program_with_simplified_input ?options program entry_point input in + let%bind (michelson_program, evaluated_in) = typed_program_with_simplified_input_to_michelson program entry_point input in + let%bind err = Ligo.Run.Of_michelson.run_failwith + ?options michelson_program.expr michelson_program.expr_ty evaluated_in false in match err with | Ligo.Run.Of_michelson.Failwith_string s -> Assert.assert_equal_string expected_failwith s | _ -> simple_fail "Expected to fail with a string" @@ -147,8 +145,10 @@ let expect_evaluate program entry_point expecter = let content () = Format.asprintf "Entry_point: %s" entry_point in error title content in trace error @@ - let%bind result = run_typed_value_as_function program entry_point in - expecter result + let%bind michelson_value_as_f = Compile.Wrapper.typed_to_michelson_expression program entry_point in + let%bind res_michelson = Ligo.Run.Of_michelson.run_exp michelson_value_as_f.expr michelson_value_as_f.expr_ty in + let%bind res_simpl = Uncompile.uncompile_typed_program_entry_expression_result program entry_point res_michelson in + expecter res_simpl let expect_eq_evaluate program entry_point expected = let expecter = fun result ->