diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 4c86a9c..fcb30a2 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -133,6 +133,7 @@ -define(PRINT_TYPES(Fmt, Args), when_option(pp_types, fun () -> io:format(Fmt, Args) end)). +-define(CONSTRUCTOR_MOCK_NAME, "#__constructor__#"). %% -- Environment manipulation ----------------------------------------------- @@ -271,20 +272,25 @@ bind_contract({Contract, Ann, Id, Contents}, Env) Fields = [ {field_t, AnnF, Entrypoint, contract_call_type(Type)} || {fun_decl, AnnF, Entrypoint, Type} <- Contents ] ++ - [ begin - AnnF1 = case {Contract, Name} of - {contract_child, "init"} -> [stateful,payable|AnnF]; %% for create/clone - _ -> AnnF - end, - {field_t, AnnF1, Entrypoint, - contract_call_type( - {fun_t, AnnF1, [], [ArgT || {typed, _, _, ArgT} <- if is_list(Args) -> Args; true -> [Args] end], RetT}) - } - end - || {letfun, AnnF, Entrypoint = {id, _, Name}, Args, _Type, {typed, _, _, RetT}} <- Contents + [ {field_t, AnnF, Entrypoint, + contract_call_type( + {fun_t, AnnF, [], [ArgT || {typed, _, _, ArgT} <- Args], RetT}) + } + || {letfun, AnnF, Entrypoint = {id, _, Name}, Args, _Type, {typed, _, _, RetT}} <- Contents, + Name =/= "init" ] ++ %% Predefined fields - [ {field_t, Sys, {id, Sys, "address"}, {id, Sys, "address"}} ], + [ {field_t, Sys, {id, Sys, "address"}, {id, Sys, "address"}} ] ++ + [ {field_t, Sys, {id, Sys, ?CONSTRUCTOR_MOCK_NAME}, + contract_call_type( + case [ {fun_t, [payable|Sys], [], [ArgT || {typed, _, _, ArgT} <- Args], {id, Sys, "void"}} + || {letfun, _, {id, _, "init"}, Args, _, _} <- Contents] of + [] -> {fun_t, [payable|Sys], [], [], {id, Sys, "void"}}; + [T] -> T + end + ) + } + ], FieldInfo = [ {Entrypoint, #field_info{ ann = FieldAnn, kind = contract, field_t = Type, @@ -1626,7 +1632,7 @@ check_contract_construction(Env, ContractT, Fun, NamedArgsT, ArgTypes, RetT) -> unify(Env, RetT, ContractT, {return_contract, Fun, ContractT}), constrain([ #field_constraint{ record_t = unfold_types_in_type(Env, ContractT), - field = {id, Ann, "init"}, + field = {id, Ann, ?CONSTRUCTOR_MOCK_NAME}, field_t = InitT, kind = project, context = {var_args, Ann, Fun} } @@ -2418,12 +2424,11 @@ unify1(_Env, {fun_t, _, _, var_args, _}, {fun_t, _, _, _, _}, When) -> error({unify_varargs, When}); unify1(Env, {fun_t, _, Named1, Args1, Result1}, {fun_t, _, Named2, Args2, Result2}, When) when length(Args1) == length(Args2) -> - Named1_ = if is_list(Named1) -> lists:keysort(3, Named1); - true -> Named1 - end, - Named2_ = if is_list(Named2) -> lists:keysort(3, Named2); - true -> Named2 - end, + {Named1_, Named2_} = + if is_list(Named1) andalso is_list(Named2) -> + {lists:keysort(3, Named1), lists:keysort(3, Named2)}; + true -> {Named1, Named2} + end, unify(Env, Named1_, Named2_, When) andalso unify(Env, Args1, Args2, When) andalso unify(Env, Result1, Result2, When); unify1(Env, {app_t, _, {Tag, _, F}, Args1}, {app_t, _, {Tag, _, F}, Args2}, When) diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index dc03304..11aa761 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -707,6 +707,7 @@ expr_to_fcode(Env, _Type, {app, _Ann, {Op, _}, [A]}) when is_atom(Op) -> %% Function calls expr_to_fcode(Env, Type, {app, _, Fun = {typed, _, FunE, {fun_t, _, NamedArgsT, ArgsT, _}}, Args}) -> + io:format("Named args: ~p\n", [[N||{named_arg_t, _, {id, _, N}, _, _} <- NamedArgsT]]), Args1 = get_named_args(NamedArgsT, Args), FArgs = [expr_to_fcode(Env, Arg) || Arg <- Args1], case expr_to_fcode(Env, Fun) of @@ -728,7 +729,7 @@ expr_to_fcode(Env, Type, {app, _, Fun = {typed, _, FunE, {fun_t, _, NamedArgsT, end; {builtin_u, B, _Ar} -> builtin_to_fcode(state_layout(Env), B, FArgs); {def_u, F, _Ar} -> {def, F, FArgs}; - {remote_u, ArgsT, RetT, Ct, RFun} -> {remote, ArgsT, RetT, Ct, RFun, FArgs}; + {remote_u, RArgsT, RRetT, Ct, RFun} -> {remote, RArgsT, RRetT, Ct, RFun, FArgs}; FFun -> %% FFun is a closure, with first component the function name and %% second component the environment diff --git a/src/aeso_fcode_to_fate.erl b/src/aeso_fcode_to_fate.erl index ba4ade7..ba548f5 100644 --- a/src/aeso_fcode_to_fate.erl +++ b/src/aeso_fcode_to_fate.erl @@ -328,6 +328,7 @@ to_scode1(Env, {remote, ArgsT, RetT, Ct, Fun, [Gas, Value, Protected | Args]}) - {ArgTypes, RetType0} = typesig_to_scode([{"_", T} || T <- ArgsT], RetT), ArgType = ?i(aeb_fate_data:make_typerep({tuple, ArgTypes})), RetType = ?i(aeb_fate_data:make_typerep(RetType0)), + io:format("GAS: ~p, VALUE: ~p, PROT: ~p\n", [Gas, Value, Protected]), case Protected of {lit, {bool, false}} -> case Gas of diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 19e8630..e7bbd97 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -26,13 +26,14 @@ run_test(Test) -> simple_compile_test_() -> [ {"Testing the " ++ ContractName ++ " contract with the " ++ atom_to_list(Backend) ++ " backend", fun() -> - case compile(Backend, ContractName) of + case compile(Backend, ContractName, [pp_assembler]) of #{byte_code := ByteCode, contract_source := _, type_info := _} when Backend == aevm -> ?assertMatch(Code when is_binary(Code), ByteCode); #{fate_code := Code} when Backend == fate -> Code1 = aeb_fate_code:deserialize(aeb_fate_code:serialize(Code)), + error(xd), ?assertMatch({X, X}, {Code1, Code}); ErrBin -> io:format("\n~s", [ErrBin]), diff --git a/test/contracts/test.aes b/test/contracts/test.aes index e22cfb6..016860d 100644 --- a/test/contracts/test.aes +++ b/test/contracts/test.aes @@ -1,6 +1,14 @@ -// If you need a quick compiler test — this file is for your playground +contract T = + entrypoint f(x, y) = 3 +main contract IntegerAdderFactory = + stateful payable entrypoint calculateSomething(x, t) = +// let t = Chain.create(value = 5555) : T + t.f(protected = true, gas = 999999999, value = 777777, 111, 222) +// t.f() + +/* contract IntegerAdder = - entrypoint init() = unit + entrypoint init() = () entrypoint addIntegers(x, y) = x + y contract IntegerAdderHolder = @@ -17,4 +25,4 @@ main contract EnterpriseContract = entrypoint calculateSomething(x) = let adder = IntegerAdderFactory.new() adder.addIntegers(x, 2137) - \ No newline at end of file +*/ \ No newline at end of file