Fix handling of init in create_calldata
This commit is contained in:
parent
e94c1f9d84
commit
95bf0d4b6c
@ -107,12 +107,27 @@ join_errors(Prefix, Errors, Pfun) ->
|
|||||||
-define(DECODE_NAME, "__decode").
|
-define(DECODE_NAME, "__decode").
|
||||||
|
|
||||||
%% Takes a string containing a contract with a declaration/prototype of a
|
%% Takes a string containing a contract with a declaration/prototype of a
|
||||||
%% function (foo, say) and a function __call() = foo(args) calling this
|
%% function (foo, say) and adds function __call() = foo(args) calling this
|
||||||
%% function. Returns the name of the called functions, typereps and Erlang
|
%% function. Returns the name of the called functions, typereps and Erlang
|
||||||
%% terms for the arguments.
|
%% terms for the arguments.
|
||||||
|
%% NOTE: Special treatment for "init" since it might be implicit and has
|
||||||
|
%% a special return type (typerep, T)
|
||||||
-spec check_call(string(), string(), [string()], options()) -> {ok, string(), {[Type], Type | any}, [term()]} | {error, term()}
|
-spec check_call(string(), string(), [string()], options()) -> {ok, string(), {[Type], Type | any}, [term()]} | {error, term()}
|
||||||
when Type :: term().
|
when Type :: term().
|
||||||
check_call(ContractString0, FunName, Args, Options) ->
|
check_call(Source, "init" = FunName, Args, Options) ->
|
||||||
|
PatchFun = fun(T) -> {tuple, [typerep, T]} end,
|
||||||
|
case check_call(Source, FunName, Args, Options, PatchFun) of
|
||||||
|
{error, _} when Args == [] ->
|
||||||
|
%% Try with default init-function
|
||||||
|
check_call(insert_init_function(Source, Options), FunName, Args, Options, PatchFun);
|
||||||
|
Res ->
|
||||||
|
Res
|
||||||
|
end;
|
||||||
|
check_call(Source, FunName, Args, Options) ->
|
||||||
|
PatchFun = fun(T) -> T end,
|
||||||
|
check_call(Source, FunName, Args, Options, PatchFun).
|
||||||
|
|
||||||
|
check_call(ContractString0, FunName, Args, Options, PatchFun) ->
|
||||||
try
|
try
|
||||||
ContractString = insert_call_function(ContractString0, FunName, Args, Options),
|
ContractString = insert_call_function(ContractString0, FunName, Args, Options),
|
||||||
Ast = parse(ContractString, Options),
|
Ast = parse(ContractString, Options),
|
||||||
@ -132,7 +147,7 @@ check_call(ContractString0, FunName, Args, Options) ->
|
|||||||
ArgIcode = get_arg_icode(Funs),
|
ArgIcode = get_arg_icode(Funs),
|
||||||
ArgTerms = [ icode_to_term(T, Arg) ||
|
ArgTerms = [ icode_to_term(T, Arg) ||
|
||||||
{T, Arg} <- lists:zip(ArgVMTypes, ArgIcode) ],
|
{T, Arg} <- lists:zip(ArgVMTypes, ArgIcode) ],
|
||||||
{ok, FunName, {ArgVMTypes, RetVMType}, ArgTerms}
|
{ok, FunName, {ArgVMTypes, PatchFun(RetVMType)}, ArgTerms}
|
||||||
catch
|
catch
|
||||||
error:{parse_errors, Errors} ->
|
error:{parse_errors, Errors} ->
|
||||||
{error, join_errors("Parse errors", Errors, fun (E) -> E end)};
|
{error, join_errors("Parse errors", Errors, fun (E) -> E end)};
|
||||||
@ -158,6 +173,16 @@ insert_call_function(Code, FunName, Args, Options) ->
|
|||||||
"function __call() = ", FunName, "(", string:join(Args, ","), ")\n"
|
"function __call() = ", FunName, "(", string:join(Args, ","), ")\n"
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-spec insert_init_function(string(), options()) -> string().
|
||||||
|
insert_init_function(Code, Options) ->
|
||||||
|
Ast = parse(Code, Options),
|
||||||
|
Ind = last_contract_indent(Ast),
|
||||||
|
lists:flatten(
|
||||||
|
[ Code,
|
||||||
|
"\n\n",
|
||||||
|
lists:duplicate(Ind, " "), "function init() = ()\n"
|
||||||
|
]).
|
||||||
|
|
||||||
last_contract_indent(Decls) ->
|
last_contract_indent(Decls) ->
|
||||||
case lists:last(Decls) of
|
case lists:last(Decls) of
|
||||||
{_, _, _, [Decl | _]} -> aeso_syntax:get_ann(col, Decl, 1) - 1;
|
{_, _, _, [Decl | _]} -> aeso_syntax:get_ann(col, Decl, 1) - 1;
|
||||||
|
@ -93,20 +93,36 @@ encode_decode_sophia_string(SophiaType, String) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
calldata_test() ->
|
calldata_test() ->
|
||||||
[42, <<"foobar">>] = encode_decode_calldata(["int", "string"], ["42", "\"foobar\""]),
|
[42, <<"foobar">>] = encode_decode_calldata("foo", ["int", "string"], ["42", "\"foobar\""]),
|
||||||
Map = #{ <<"a">> => 4 },
|
Map = #{ <<"a">> => 4 },
|
||||||
[{variant, 1, [Map]}, {{<<"b">>, 5}, {variant, 0, []}}] =
|
[{variant, 1, [Map]}, {{<<"b">>, 5}, {variant, 0, []}}] =
|
||||||
encode_decode_calldata(["variant", "r"], ["Blue({[\"a\"] = 4})", "{x = (\"b\", 5), y = Red}"]),
|
encode_decode_calldata("foo", ["variant", "r"], ["Blue({[\"a\"] = 4})", "{x = (\"b\", 5), y = Red}"]),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
encode_decode_calldata(Types, Args) ->
|
calldata_init_test() ->
|
||||||
Code = lists:flatten(
|
encode_decode_calldata("init", ["int"], ["42"], {tuple, [typerep, word]}),
|
||||||
|
|
||||||
|
Code = parameterized_contract("foo", ["int"]),
|
||||||
|
encode_decode_calldata_(Code, "init", [], {tuple, [typerep, {tuple, []}]}).
|
||||||
|
|
||||||
|
parameterized_contract(FunName, Types) ->
|
||||||
|
lists:flatten(
|
||||||
["contract Dummy =\n",
|
["contract Dummy =\n",
|
||||||
" type an_alias('a) = (string, 'a)\n"
|
" type an_alias('a) = (string, 'a)\n"
|
||||||
" record r = {x : an_alias(int), y : variant}\n"
|
" record r = {x : an_alias(int), y : variant}\n"
|
||||||
" datatype variant = Red | Blue(map(string, int))\n"
|
" datatype variant = Red | Blue(map(string, int))\n"
|
||||||
" function foo : (", string:join(Types, ", "), ") => int\n" ]),
|
" function ", FunName, " : (", string:join(Types, ", "), ") => int\n" ]).
|
||||||
{ok, Calldata, CalldataType, word} = aeso_compiler:create_calldata(Code, "foo", Args),
|
|
||||||
|
encode_decode_calldata(FunName, Types, Args) ->
|
||||||
|
encode_decode_calldata(FunName, Types, Args, word).
|
||||||
|
|
||||||
|
encode_decode_calldata(FunName, Types, Args, RetType) ->
|
||||||
|
Code = parameterized_contract(FunName, Types),
|
||||||
|
encode_decode_calldata_(Code, FunName, Args, RetType).
|
||||||
|
|
||||||
|
encode_decode_calldata_(Code, FunName, Args, RetVMType) ->
|
||||||
|
{ok, Calldata, CalldataType, RetVMType1} = aeso_compiler:create_calldata(Code, FunName, Args),
|
||||||
|
?assertEqual(RetVMType1, RetVMType),
|
||||||
{ok, {_Hash, ArgTuple}} = aeso_heap:from_binary(CalldataType, Calldata),
|
{ok, {_Hash, ArgTuple}} = aeso_heap:from_binary(CalldataType, Calldata),
|
||||||
tuple_to_list(ArgTuple).
|
tuple_to_list(ArgTuple).
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user