diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index a916d4f..512e2ab 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -226,6 +226,9 @@ init_type_env() -> ["Chain", "ttl"] => ?type({variant, [[integer], [integer]]}) }. +is_no_code(Env) -> + proplists:get_value(no_code, maps:get(options, Env, []), false). + %% -- Compilation ------------------------------------------------------------ -spec to_fcode(env(), aeso_syntax:ast()) -> fcode(). @@ -244,7 +247,7 @@ to_fcode(Env, [{contract, Attrs, {con, _, Main}, Decls}]) -> state_type => StateType, event_type => EventType, payable => Payable, - functions => add_init_function(Env1, + functions => add_init_function(Env1, StateType, add_event_function(Env1, EventType, Funs)) }; to_fcode(Env, [{contract, _, {con, _, Con}, Decls} | Code]) -> Env1 = decls_to_fcode(Env#{ context => {abstract_contract, Con} }, Decls), @@ -268,7 +271,7 @@ decls_to_fcode(Env, Decls) -> -spec decl_to_fcode(env(), aeso_syntax:decl()) -> env(). decl_to_fcode(Env, {type_decl, _, _, _}) -> Env; decl_to_fcode(Env = #{context := {main_contract, _}}, {fun_decl, Ann, {id, _, Name}, _}) -> - case proplists:get_value(no_code, maps:get(options, Env, []), false) of + case is_no_code(Env) of false -> fcode_error({missing_definition, Name, lists:keydelete(entrypoint, 1, Ann)}); true -> Env end; @@ -852,16 +855,30 @@ builtin_to_fcode(Builtin, Args) -> %% -- Init function -- -add_init_function(_Env, Funs) -> +add_init_function(Env, StateType, Funs0) -> + case is_no_code(Env) of + true -> Funs0; + false -> + Funs = add_default_init_function(Env, StateType, Funs0), + InitName = {entrypoint, <<"init">>}, + InitFun = #{ args := InitArgs } = maps:get(InitName, Funs, none), + Vars = [ {var, X} || {X, _} <- InitArgs ], + Funs#{ init => InitFun#{ return => {tuple, []}, + body => {builtin, set_state, [{def, InitName, Vars}]} } } + end. + +add_default_init_function(_Env, StateType, Funs) -> InitName = {entrypoint, <<"init">>}, - InitFun = #{ args := InitArgs } = - case maps:get(InitName, Funs, none) of - none -> #{ attrs => [], args => [], return => {tuple, []}, body => {tuple, []} }; - Info -> Info - end, - Vars = [ {var, X} || {X, _} <- InitArgs ], - Funs#{ init => InitFun#{ return => {tuple, []}, - body => {builtin, set_state, [{def, InitName, Vars}]} } }. + case maps:get(InitName, Funs, none) of + %% Only add default init function if state is unit. + none when StateType == {tuple, []} -> + Funs#{ InitName => #{attrs => [], + args => [], + return => {tuple, []}, + body => {tuple, []}} }; + none -> fcode_error(missing_init_function); + _ -> Funs + end. %% -- Event function -- diff --git a/src/aeso_fcode_to_fate.erl b/src/aeso_fcode_to_fate.erl index ef75237..2c44090 100644 --- a/src/aeso_fcode_to_fate.erl +++ b/src/aeso_fcode_to_fate.erl @@ -130,12 +130,10 @@ debug(Tag, Options, Fmt, Args) -> %% @doc Main entry point. compile(FCode, Options) -> #{ contract_name := ContractName, - state_type := StateType, functions := Functions } = FCode, SFuns = functions_to_scode(ContractName, Functions, Options), SFuns1 = optimize_scode(SFuns, Options), - SFuns2 = add_default_init_function(SFuns1, StateType), - FateCode = to_basic_blocks(SFuns2), + FateCode = to_basic_blocks(SFuns1), debug(compile, Options, "~s\n", [aeb_fate_asm:pp(FateCode)]), FateCode. @@ -196,21 +194,6 @@ type_to_scode({tvar, X}) -> J -> {tvar, J} end. -add_default_init_function(SFuns, StateType) when StateType /= {tuple, []} -> - %% Only add default if the type is unit. - SFuns; -add_default_init_function(SFuns, {tuple, []}) -> - %% Only add default if the init function is not present - InitName = make_function_name({entrypoint, <<"init">>}), - case maps:find(InitName, SFuns) of - {ok, _} -> - SFuns; - error -> - Sig = {[], {tuple, []}}, - Body = [tuple(0)], - SFuns#{ InitName => {[], Sig, Body} } - end. - %% -- Phase I ---------------------------------------------------------------- %% Icode to structured assembly