Merge branch 'feature/get-entrypoint' into 'dev'
Add `get_entrypoint`... See merge request ligolang/ligo!184
This commit is contained in:
commit
863dfbb39d
@ -51,8 +51,7 @@ let compile_contract_entry = fun program name ->
|
|||||||
in
|
in
|
||||||
let%bind param_michelson = Compiler.Type.type_ param_ty in
|
let%bind param_michelson = Compiler.Type.type_ param_ty in
|
||||||
let%bind storage_michelson = Compiler.Type.type_ storage_ty in
|
let%bind storage_michelson = Compiler.Type.type_ storage_ty in
|
||||||
let body = Michelson.strip_annots compiled.body in
|
let contract = Michelson.contract param_michelson storage_michelson compiled.body in
|
||||||
let contract = Michelson.contract param_michelson storage_michelson body in
|
|
||||||
ok contract
|
ok contract
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ let run ?options (* ?(is_input_value = false) *) (program:compiled_program) (inp
|
|||||||
Trace.trace_tzresult_lwt (simple_error "error parsing input") @@
|
Trace.trace_tzresult_lwt (simple_error "error parsing input") @@
|
||||||
Memory_proto_alpha.parse_michelson_data input_michelson input_ty
|
Memory_proto_alpha.parse_michelson_data input_michelson input_ty
|
||||||
in
|
in
|
||||||
let body = Michelson.strip_annots body in
|
|
||||||
let%bind descr =
|
let%bind descr =
|
||||||
Trace.trace_tzresult_lwt (simple_error "error parsing program code") @@
|
Trace.trace_tzresult_lwt (simple_error "error parsing program code") @@
|
||||||
Memory_proto_alpha.parse_michelson body
|
Memory_proto_alpha.parse_michelson body
|
||||||
|
@ -4,6 +4,28 @@ open Michelson
|
|||||||
open Memory_proto_alpha.Protocol.Script_ir_translator
|
open Memory_proto_alpha.Protocol.Script_ir_translator
|
||||||
open Operators.Compiler
|
open Operators.Compiler
|
||||||
|
|
||||||
|
module Errors = struct
|
||||||
|
let corner_case ~loc message =
|
||||||
|
let title () = "corner case" in
|
||||||
|
let content () = "we don't have a good error message for this case. we are
|
||||||
|
striving find ways to better report them and find the use-cases that generate
|
||||||
|
them. please report this to the developers." in
|
||||||
|
let data = [
|
||||||
|
("location" , fun () -> loc) ;
|
||||||
|
("message" , fun () -> message) ;
|
||||||
|
] in
|
||||||
|
error ~data title content
|
||||||
|
|
||||||
|
let contract_entrypoint_must_be_literal ~loc =
|
||||||
|
let title () = "contract entrypoint must be literal" in
|
||||||
|
let content () = "For get_entrypoint, entrypoint must be given as a literal string" in
|
||||||
|
let data =
|
||||||
|
[ ("location", fun () -> loc) ;
|
||||||
|
] in
|
||||||
|
error ~data title content
|
||||||
|
end
|
||||||
|
open Errors
|
||||||
|
|
||||||
let get_operator : string -> type_value -> expression list -> predicate result = fun s ty lst ->
|
let get_operator : string -> type_value -> expression list -> predicate result = fun s ty lst ->
|
||||||
match Map.String.find_opt s Operators.Compiler.operators with
|
match Map.String.find_opt s Operators.Compiler.operators with
|
||||||
| Some x -> ok x
|
| Some x -> ok x
|
||||||
@ -50,14 +72,26 @@ let get_operator : string -> type_value -> expression list -> predicate result =
|
|||||||
let%bind l_ty = Compiler_type.type_ l in
|
let%bind l_ty = Compiler_type.type_ l in
|
||||||
ok @@ simple_unary @@ prim ~children:[l_ty] I_RIGHT
|
ok @@ simple_unary @@ prim ~children:[l_ty] I_RIGHT
|
||||||
| "CONTRACT" ->
|
| "CONTRACT" ->
|
||||||
let%bind r = match lst with
|
let%bind r = get_t_contract ty in
|
||||||
| [ _ ] -> get_t_contract ty
|
|
||||||
| _ -> simple_fail "mini_c . CONTRACT" in
|
|
||||||
let%bind r_ty = Compiler_type.type_ r in
|
let%bind r_ty = Compiler_type.type_ r in
|
||||||
ok @@ simple_unary @@ seq [
|
ok @@ simple_unary @@ seq [
|
||||||
prim ~children:[r_ty] I_CONTRACT ;
|
prim ~children:[r_ty] I_CONTRACT ;
|
||||||
i_assert_some_msg (i_push_string "bad address for get_contract") ;
|
i_assert_some_msg (i_push_string "bad address for get_contract") ;
|
||||||
]
|
]
|
||||||
|
| "CONTRACT_ENTRYPOINT" ->
|
||||||
|
let%bind r = get_t_contract ty in
|
||||||
|
let%bind r_ty = Compiler_type.type_ r in
|
||||||
|
let%bind entry = match lst with
|
||||||
|
| [ { content = E_literal (D_string entry); type_value = _ } ; _addr ] -> ok entry
|
||||||
|
| [ _entry ; _addr ] ->
|
||||||
|
fail @@ contract_entrypoint_must_be_literal ~loc:__LOC__
|
||||||
|
| _ ->
|
||||||
|
fail @@ corner_case ~loc:__LOC__ "mini_c . CONTRACT_ENTRYPOINT" in
|
||||||
|
ok @@ simple_binary @@ seq [
|
||||||
|
i_drop ; (* drop the entrypoint... *)
|
||||||
|
prim ~annot:[entry] ~children:[r_ty] I_CONTRACT ;
|
||||||
|
i_assert_some_msg (i_push_string @@ Format.sprintf "bad address for get_entrypoint (%s)" entry) ;
|
||||||
|
]
|
||||||
| x -> simple_fail ("predicate \"" ^ x ^ "\" doesn't exist")
|
| x -> simple_fail ("predicate \"" ^ x ^ "\" doesn't exist")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -193,7 +227,7 @@ and translate_expression (expr:expression) (env:environment) : michelson result
|
|||||||
pre_code ;
|
pre_code ;
|
||||||
f ;
|
f ;
|
||||||
]
|
]
|
||||||
| _ -> simple_fail "bad arity"
|
| _ -> simple_fail ("bad arity for " ^ str)
|
||||||
in
|
in
|
||||||
let error =
|
let error =
|
||||||
let title () = "error compiling constant" in
|
let title () = "error compiling constant" in
|
||||||
@ -446,20 +480,6 @@ let translate_entry (p:anon_function) ty : compiled_program result =
|
|||||||
let%bind output = Compiler_type.Ty.type_ output in
|
let%bind output = Compiler_type.Ty.type_ output in
|
||||||
ok ({input;output;body}:compiled_program)
|
ok ({input;output;body}:compiled_program)
|
||||||
|
|
||||||
module Errors = struct
|
|
||||||
let corner_case ~loc message =
|
|
||||||
let title () = "corner case" in
|
|
||||||
let content () = "we don't have a good error message for this case. we are
|
|
||||||
striving find ways to better report them and find the use-cases that generate
|
|
||||||
them. please report this to the developers." in
|
|
||||||
let data = [
|
|
||||||
("location" , fun () -> loc) ;
|
|
||||||
("message" , fun () -> message) ;
|
|
||||||
] in
|
|
||||||
error ~data title content
|
|
||||||
end
|
|
||||||
open Errors
|
|
||||||
|
|
||||||
let translate_contract : anon_function -> _ -> michelson result = fun f ty ->
|
let translate_contract : anon_function -> _ -> michelson result = fun f ty ->
|
||||||
let%bind compiled_program =
|
let%bind compiled_program =
|
||||||
trace_strong (corner_case ~loc:__LOC__ "compiling") @@
|
trace_strong (corner_case ~loc:__LOC__ "compiling") @@
|
||||||
|
@ -61,6 +61,15 @@ module Typer = struct
|
|||||||
| _ -> fail @@ wrong_param_number s 2 lst
|
| _ -> fail @@ wrong_param_number s 2 lst
|
||||||
let typer_2 name f : typer = (name , typer'_2 name f)
|
let typer_2 name f : typer = (name , typer'_2 name f)
|
||||||
|
|
||||||
|
let typer'_2_opt : name -> (type_value -> type_value -> type_value option -> type_value result) -> typer' = fun s f lst tv_opt ->
|
||||||
|
match lst with
|
||||||
|
| [ a ; b ] -> (
|
||||||
|
let%bind tv' = f a b tv_opt in
|
||||||
|
ok (s , tv')
|
||||||
|
)
|
||||||
|
| _ -> fail @@ wrong_param_number s 2 lst
|
||||||
|
let typer_2_opt name f : typer = (name , typer'_2_opt name f)
|
||||||
|
|
||||||
let typer'_3 : name -> (type_value -> type_value -> type_value -> type_value result) -> typer' = fun s f lst _ ->
|
let typer'_3 : name -> (type_value -> type_value -> type_value -> type_value result) -> typer' = fun s f lst _ ->
|
||||||
match lst with
|
match lst with
|
||||||
| [ a ; b ; c ] -> (
|
| [ a ; b ; c ] -> (
|
||||||
|
@ -27,6 +27,7 @@ module Typer : sig
|
|||||||
val typer'_2 : name -> (type_value -> type_value -> type_value result) -> typer'
|
val typer'_2 : name -> (type_value -> type_value -> type_value result) -> typer'
|
||||||
*)
|
*)
|
||||||
val typer_2 : name -> (type_value -> type_value -> type_value result) -> typer
|
val typer_2 : name -> (type_value -> type_value -> type_value result) -> typer
|
||||||
|
val typer_2_opt : name -> (type_value -> type_value -> type_value option -> type_value result) -> typer
|
||||||
(*
|
(*
|
||||||
val typer'_3 : name -> (type_value -> type_value -> type_value -> type_value result) -> typer'
|
val typer'_3 : name -> (type_value -> type_value -> type_value -> type_value result) -> typer'
|
||||||
*)
|
*)
|
||||||
|
@ -60,6 +60,7 @@ module Simplify = struct
|
|||||||
("get_force" , "MAP_GET_FORCE") ;
|
("get_force" , "MAP_GET_FORCE") ;
|
||||||
("transaction" , "CALL") ;
|
("transaction" , "CALL") ;
|
||||||
("get_contract" , "CONTRACT") ;
|
("get_contract" , "CONTRACT") ;
|
||||||
|
("get_entrypoint" , "CONTRACT_ENTRYPOINT") ;
|
||||||
("size" , "SIZE") ;
|
("size" , "SIZE") ;
|
||||||
("int" , "INT") ;
|
("int" , "INT") ;
|
||||||
("abs" , "ABS") ;
|
("abs" , "ABS") ;
|
||||||
@ -201,6 +202,7 @@ module Simplify = struct
|
|||||||
|
|
||||||
("Operation.transaction" , "CALL") ;
|
("Operation.transaction" , "CALL") ;
|
||||||
("Operation.get_contract" , "CONTRACT") ;
|
("Operation.get_contract" , "CONTRACT") ;
|
||||||
|
("Operation.get_entrypoint" , "CONTRACT_ENTRYPOINT") ;
|
||||||
("int" , "INT") ;
|
("int" , "INT") ;
|
||||||
("abs" , "ABS") ;
|
("abs" , "ABS") ;
|
||||||
("unit" , "UNIT") ;
|
("unit" , "UNIT") ;
|
||||||
@ -487,6 +489,20 @@ module Typer = struct
|
|||||||
get_t_contract tv in
|
get_t_contract tv in
|
||||||
ok @@ t_contract tv' ()
|
ok @@ t_contract tv' ()
|
||||||
|
|
||||||
|
let get_entrypoint = typer_2_opt "CONTRACT_ENTRYPOINT" @@ fun entry_tv addr_tv tv_opt ->
|
||||||
|
if not (type_value_eq (entry_tv, t_string ()))
|
||||||
|
then fail @@ simple_error (Format.asprintf "get_entrypoint expects a string entrypoint label for first argument, got %a" PP.type_value entry_tv)
|
||||||
|
else
|
||||||
|
if not (type_value_eq (addr_tv, t_address ()))
|
||||||
|
then fail @@ simple_error (Format.asprintf "get_entrypoint expects an address for second argument, got %a" PP.type_value addr_tv)
|
||||||
|
else
|
||||||
|
let%bind tv =
|
||||||
|
trace_option (simple_error "get_entrypoint needs a type annotation") tv_opt in
|
||||||
|
let%bind tv' =
|
||||||
|
trace_strong (simple_error "get_entrypoint has a not-contract annotation") @@
|
||||||
|
get_t_contract tv in
|
||||||
|
ok @@ t_contract tv' ()
|
||||||
|
|
||||||
let set_delegate = typer_1 "SET_DELEGATE" @@ fun delegate_opt ->
|
let set_delegate = typer_1 "SET_DELEGATE" @@ fun delegate_opt ->
|
||||||
let%bind () = assert_eq_1 delegate_opt (t_option (t_key_hash ()) ()) in
|
let%bind () = assert_eq_1 delegate_opt (t_option (t_key_hash ()) ()) in
|
||||||
ok @@ t_operation ()
|
ok @@ t_operation ()
|
||||||
@ -756,6 +772,7 @@ module Typer = struct
|
|||||||
amount ;
|
amount ;
|
||||||
transaction ;
|
transaction ;
|
||||||
get_contract ;
|
get_contract ;
|
||||||
|
get_entrypoint ;
|
||||||
neg ;
|
neg ;
|
||||||
abs ;
|
abs ;
|
||||||
cons ;
|
cons ;
|
||||||
|
4
src/test/contracts/entrypoints.ligo
Normal file
4
src/test/contracts/entrypoints.ligo
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
function cb(const a : address; const s : unit) : list(operation) * unit is
|
||||||
|
const c : contract(unit) = get_entrypoint("%cb", a) ;
|
||||||
|
block { skip }
|
||||||
|
with (list transaction(unit, 0mutez, c) end, s)
|
@ -1218,6 +1218,11 @@ let deep_access_ligo () : unit result =
|
|||||||
let make_expected = e_int 2 in
|
let make_expected = e_int 2 in
|
||||||
expect_eq program "main" make_input make_expected
|
expect_eq program "main" make_input make_expected
|
||||||
|
|
||||||
|
let entrypoints_ligo () : unit result =
|
||||||
|
let%bind _program = type_file "./contracts/entrypoints.ligo" in
|
||||||
|
(* hmm... *)
|
||||||
|
ok ()
|
||||||
|
|
||||||
let main = test_suite "Integration (End to End)" [
|
let main = test_suite "Integration (End to End)" [
|
||||||
test "type alias" type_alias ;
|
test "type alias" type_alias ;
|
||||||
test "function" function_ ;
|
test "function" function_ ;
|
||||||
@ -1305,4 +1310,5 @@ let main = test_suite "Integration (End to End)" [
|
|||||||
test "balance constant (mligo)" balance_constant_mligo ;
|
test "balance constant (mligo)" balance_constant_mligo ;
|
||||||
test "simple_access (ligo)" simple_access_ligo;
|
test "simple_access (ligo)" simple_access_ligo;
|
||||||
test "deep_access (ligo)" deep_access_ligo;
|
test "deep_access (ligo)" deep_access_ligo;
|
||||||
|
test "entrypoints (ligo)" entrypoints_ligo ;
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user