Refactor string_to_code

This commit is contained in:
Thomas Arts 2019-06-18 13:47:35 +02:00
parent d3ce5010d0
commit 46c746da1c

View File

@ -99,7 +99,7 @@ from_string(Backend, ContractString, Options) ->
end. end.
from_string1(aevm, ContractString, Options) -> from_string1(aevm, ContractString, Options) ->
#{icode := Icode} = string_to_icode(ContractString, Options), #{icode := Icode} = string_to_code(ContractString, Options),
TypeInfo = extract_type_info(Icode), TypeInfo = extract_type_info(Icode),
Assembler = assemble(Icode, Options), Assembler = assemble(Icode, Options),
pp_assembler(Assembler, Options), pp_assembler(Assembler, Options),
@ -113,9 +113,7 @@ from_string1(aevm, ContractString, Options) ->
type_info => TypeInfo type_info => TypeInfo
}}; }};
from_string1(fate, ContractString, Options) -> from_string1(fate, ContractString, Options) ->
Ast = parse(ContractString, Options), #{fcode := FCode} = string_to_code(ContractString, Options),
TypedAst = aeso_ast_infer_types:infer(Ast, Options),
FCode = aeso_ast_to_fcode:ast_to_fcode(TypedAst, Options),
FateCode = aeso_fcode_to_fate:compile(FCode, Options), FateCode = aeso_fcode_to_fate:compile(FCode, Options),
ByteCode = aeb_fate_code:serialize(FateCode, []), ByteCode = aeb_fate_code:serialize(FateCode, []),
{ok, Version} = version(), {ok, Version} = version(),
@ -126,30 +124,26 @@ from_string1(fate, ContractString, Options) ->
fate_code => FateCode fate_code => FateCode
}}. }}.
-spec string_to_icode(string(), [option()]) -> map(). -spec string_to_code(string(), [option()]) -> map().
string_to_icode(ContractString, Options) -> string_to_code(ContractString, Options) ->
Ast = parse(ContractString, Options), Ast = parse(ContractString, Options),
pp_sophia_code(Ast, Options), pp_sophia_code(Ast, Options),
pp_ast(Ast, Options), pp_ast(Ast, Options),
{TypeEnv, TypedAst} = aeso_ast_infer_types:infer(Ast, [return_env]), {TypeEnv, TypedAst} = aeso_ast_infer_types:infer(Ast, [return_env]),
pp_typed_ast(TypedAst, Options), pp_typed_ast(TypedAst, Options),
Icode = ast_to_icode(TypedAst, Options), case proplists:get_value(backend, Options, aevm) of
pp_icode(Icode, Options), aevm ->
#{ typed_ast => TypedAst, Icode = ast_to_icode(TypedAst, Options),
type_env => TypeEnv, pp_icode(Icode, Options),
icode => Icode }. #{ icode => Icode,
typed_ast => TypedAst,
-spec string_to_fcode(string(), [option()]) -> map(). type_env => TypeEnv};
string_to_fcode(ContractString, Options) -> fate ->
Ast = parse(ContractString, Options), Fcode = aeso_ast_to_fcode:ast_to_fcode(TypedAst, Options),
pp_sophia_code(Ast, Options), #{ fcode => Fcode,
pp_ast(Ast, Options), typed_ast => TypedAst,
{TypeEnv, TypedAst} = aeso_ast_infer_types:infer(Ast, [return_env]), type_env => TypeEnv}
pp_typed_ast(TypedAst, Options), end.
Fcode = aeso_ast_to_fcode:ast_to_fcode(TypedAst, Options),
#{ typed_ast => TypedAst,
type_env => TypeEnv,
fcode => Fcode }.
join_errors(Prefix, Errors, Pfun) -> join_errors(Prefix, Errors, Pfun) ->
Ess = [ Pfun(E) || E <- Errors ], Ess = [ Pfun(E) || E <- Errors ],
@ -187,10 +181,10 @@ check_call1(ContractString0, FunName, Args, Options) ->
case proplists:get_value(backend, Options, aevm) of case proplists:get_value(backend, Options, aevm) of
aevm -> aevm ->
%% First check the contract without the __call function %% First check the contract without the __call function
#{} = string_to_icode(ContractString0, Options), #{} = string_to_code(ContractString0, Options),
ContractString = insert_call_function(ContractString0, ?CALL_NAME, FunName, Args, Options), ContractString = insert_call_function(ContractString0, ?CALL_NAME, FunName, Args, Options),
#{typed_ast := TypedAst, #{typed_ast := TypedAst,
icode := Icode} = string_to_icode(ContractString, Options), icode := Icode} = string_to_code(ContractString, Options),
{ok, {FunName, {fun_t, _, _, ArgTypes, RetType}}} = get_call_type(TypedAst), {ok, {FunName, {fun_t, _, _, ArgTypes, RetType}}} = get_call_type(TypedAst),
ArgVMTypes = [ aeso_ast_to_icode:ast_typerep(T, Icode) || T <- ArgTypes ], ArgVMTypes = [ aeso_ast_to_icode:ast_typerep(T, Icode) || T <- ArgTypes ],
RetVMType = case RetType of RetVMType = case RetType of
@ -209,14 +203,14 @@ check_call1(ContractString0, FunName, Args, Options) ->
{ok, FunName, {ArgVMTypes, RetVMType1}, ArgTerms}; {ok, FunName, {ArgVMTypes, RetVMType1}, ArgTerms};
fate -> fate ->
%% First check the contract without the __call function %% First check the contract without the __call function
#{fcode := OrgFcode} = string_to_fcode(ContractString0, Options), #{fcode := OrgFcode} = string_to_code(ContractString0, Options),
FateCode = aeso_fcode_to_fate:compile(OrgFcode, []), FateCode = aeso_fcode_to_fate:compile(OrgFcode, []),
%% collect all hashes and compute the first name without hash collision to %% collect all hashes and compute the first name without hash collision to
SymbolHashes = maps:keys(aeb_fate_code:symbols(FateCode)), SymbolHashes = maps:keys(aeb_fate_code:symbols(FateCode)),
CallName = first_none_match(?CALL_NAME, SymbolHashes, CallName = first_none_match(?CALL_NAME, SymbolHashes,
lists:seq($1, $9) ++ lists:seq($A, $Z) ++ lists:seq($a, $z)), lists:seq($1, $9) ++ lists:seq($A, $Z) ++ lists:seq($a, $z)),
ContractString = insert_call_function(ContractString0, CallName, FunName, Args, Options), ContractString = insert_call_function(ContractString0, CallName, FunName, Args, Options),
#{fcode := Fcode} = string_to_fcode(ContractString, Options), #{fcode := Fcode} = string_to_code(ContractString, Options),
CallArgs = arguments_of_body(CallName, FunName, Fcode), CallArgs = arguments_of_body(CallName, FunName, Fcode),
{ok, FunName, CallArgs} {ok, FunName, CallArgs}
end end
@ -295,7 +289,7 @@ to_sophia_value(ContractString, FunName, ok, Data, Options) ->
try try
#{ typed_ast := TypedAst, #{ typed_ast := TypedAst,
type_env := TypeEnv, type_env := TypeEnv,
icode := Icode } = string_to_icode(ContractString, Options), icode := Icode } = string_to_code(ContractString, Options),
{ok, _, Type0} = get_decode_type(FunName, TypedAst), {ok, _, Type0} = get_decode_type(FunName, TypedAst),
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]), Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
VmType = aeso_ast_to_icode:ast_typerep(Type, Icode), VmType = aeso_ast_to_icode:ast_typerep(Type, Icode),