Add new encode function interface
This commit is contained in:
parent
931f2d3dcb
commit
6f582af83e
@ -85,7 +85,7 @@ json_string() = binary()
|
|||||||
|
|
||||||
### Exports
|
### Exports
|
||||||
|
|
||||||
#### encode(ContractString) -> JSONstring
|
#### encode(ContractString) -> {ok,JSONstring} | {error,ErrorString}
|
||||||
|
|
||||||
Types
|
Types
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ This is an example of using the ACI generator from an Erlang shell. The file cal
|
|||||||
``` erlang
|
``` erlang
|
||||||
1> {ok,Contract} = file:read_file("aci_test.aes").
|
1> {ok,Contract} = file:read_file("aci_test.aes").
|
||||||
{ok,<<"contract Answers =\n record state = { a : answers }\n type answers() = map(string, int)\n\n stateful function"...>>}
|
{ok,<<"contract Answers =\n record state = { a : answers }\n type answers() = map(string, int)\n\n stateful function"...>>}
|
||||||
2> Encoding = aeso_aci:encode(Contract).
|
2> {ok,Encoding} = aeso_aci:encode(Contract).
|
||||||
<<"{\"contract\":{\"name\":\"Answers\",\"type_defs\":[{\"name\":\"state\",\"vars\":[],\"typedef\":\"{a : map(string,int)}\"},{\"name\":\"ans"...>>
|
<<"{\"contract\":{\"name\":\"Answers\",\"type_defs\":[{\"name\":\"state\",\"vars\":[],\"typedef\":\"{a : map(string,int)}\"},{\"name\":\"ans"...>>
|
||||||
3> file:write_file("aci_test.aci", Encoding).
|
3> file:write_file("aci_test.aci", Encoding).
|
||||||
ok
|
ok
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
%% the code easier but don't seem to exist elsewhere.
|
%% the code easier but don't seem to exist elsewhere.
|
||||||
|
|
||||||
-record(contract, {ann,con,decls}).
|
-record(contract, {ann,con,decls}).
|
||||||
|
-record(namespace, {ann,con,decls}).
|
||||||
-record(letfun, {ann,id,args,type,body}).
|
-record(letfun, {ann,id,args,type,body}).
|
||||||
-record(type_def, {ann,id,vars,typedef}).
|
-record(type_def, {ann,id,vars,typedef}).
|
||||||
|
|
||||||
@ -29,9 +30,12 @@
|
|||||||
-record(arg, {ann,id,type}).
|
-record(arg, {ann,id,type}).
|
||||||
-record(id, {ann,name}).
|
-record(id, {ann,name}).
|
||||||
-record(con, {ann,name}).
|
-record(con, {ann,name}).
|
||||||
|
-record(qid, {ann,names}).
|
||||||
|
-record(qcon, {ann,names}).
|
||||||
-record(tvar, {ann,name}).
|
-record(tvar, {ann,name}).
|
||||||
|
|
||||||
%% encode(ContractString) -> JSON.
|
%% encode(ContractString) -> {ok,JSON} | {error,String}.
|
||||||
|
%% encode(ContractString, Options) -> {ok,JSON} | {error,String}.
|
||||||
%% Build a JSON structure with lists and tuples, not maps, as this
|
%% Build a JSON structure with lists and tuples, not maps, as this
|
||||||
%% allows us to order the fields in the contructed JSON string.
|
%% allows us to order the fields in the contructed JSON string.
|
||||||
|
|
||||||
@ -39,23 +43,40 @@ encode(ContractString) when is_binary(ContractString) ->
|
|||||||
encode(binary_to_list(ContractString));
|
encode(binary_to_list(ContractString));
|
||||||
encode(ContractString) ->
|
encode(ContractString) ->
|
||||||
Options = [], %No options yet
|
Options = [], %No options yet
|
||||||
|
try
|
||||||
Ast = parse_string(ContractString),
|
Ast = parse_string(ContractString),
|
||||||
TypedAst = aeso_ast_infer_types:infer(Ast, Options),
|
TypedAst = aeso_ast_infer_types:infer(Ast, Options),
|
||||||
%% io:format("~p\n", [Ast]),
|
%% io:format("~p\n", [Ast]),
|
||||||
%% io:format("~p\n", [TypedAst]),
|
%% io:format("~p\n", [TypedAst]),
|
||||||
%% aeso_ast:pp(Ast),
|
%% aeso_ast:pp(Ast),
|
||||||
%% aeso_ast:pp_typed(TypedAst),
|
%% aeso_ast:pp_typed(TypedAst),
|
||||||
%% We look at the first contract.
|
%% We find and look at the last contract.
|
||||||
Contract = hd(TypedAst),
|
Contract = lists:last(TypedAst),
|
||||||
Cname = contract_name(Contract),
|
Cname = contract_name(Contract),
|
||||||
Tdefs = [ encode_typedef(T) || T <- sort_decls(contract_types(Contract)) ],
|
Tdefs = [ encode_typedef(T) ||
|
||||||
|
T <- sort_decls(contract_types(Contract)) ],
|
||||||
Fdefs = [ encode_func(F) || F <- sort_decls(contract_funcs(Contract)),
|
Fdefs = [ encode_func(F) || F <- sort_decls(contract_funcs(Contract)),
|
||||||
not is_private_func(F) ],
|
not is_private_func(F) ],
|
||||||
Jmap = [{<<"contract">>, [{<<"name">>, list_to_binary(Cname)},
|
Jmap = [{<<"contract">>, [{<<"name">>, list_to_binary(Cname)},
|
||||||
{<<"type_defs">>, Tdefs},
|
{<<"type_defs">>, Tdefs},
|
||||||
{<<"functions">>, Fdefs}]}],
|
{<<"functions">>, Fdefs}]}],
|
||||||
%% io:format("~p\n", [Jmap]),
|
%% io:format("~p\n", [Jmap]),
|
||||||
jsx:encode(Jmap).
|
{ok,jsx:encode(Jmap)}
|
||||||
|
catch
|
||||||
|
%% The compiler errors.
|
||||||
|
error:{parse_errors, Errors} ->
|
||||||
|
{error, join_errors("Parse errors", Errors, fun(E) -> E end)};
|
||||||
|
error:{type_errors, Errors} ->
|
||||||
|
{error, join_errors("Type errors", Errors, fun(E) -> E end)};
|
||||||
|
error:{code_errors, Errors} ->
|
||||||
|
{error, join_errors("Code errors", Errors,
|
||||||
|
fun (E) -> io_lib:format("~p", [E]) end)}
|
||||||
|
%% General programming errors in the compiler just signal error.
|
||||||
|
end.
|
||||||
|
|
||||||
|
join_errors(Prefix, Errors, Pfun) ->
|
||||||
|
Ess = [ Pfun(E) || E <- Errors ],
|
||||||
|
list_to_binary(string:join([Prefix|Ess], "\n")).
|
||||||
|
|
||||||
encode_func(Fdef) ->
|
encode_func(Fdef) ->
|
||||||
Name = function_name(Fdef),
|
Name = function_name(Fdef),
|
||||||
@ -79,6 +100,10 @@ encode_types(Types) ->
|
|||||||
encode_type(#tvar{name=N}) -> N;
|
encode_type(#tvar{name=N}) -> N;
|
||||||
encode_type(#id{name=N}) -> N;
|
encode_type(#id{name=N}) -> N;
|
||||||
encode_type(#con{name=N}) -> N;
|
encode_type(#con{name=N}) -> N;
|
||||||
|
encode_type(#qid{names=Ns}) ->
|
||||||
|
lists:join(".", Ns);
|
||||||
|
encode_type(#qcon{names=Ns}) ->
|
||||||
|
lists:join(".", Ns); %?
|
||||||
encode_type(#tuple_t{args=As}) ->
|
encode_type(#tuple_t{args=As}) ->
|
||||||
Eas = encode_types(As),
|
Eas = encode_types(As),
|
||||||
[$(,lists:join(",", Eas),$)];
|
[$(,lists:join(",", Eas),$)];
|
||||||
@ -175,6 +200,14 @@ contract_funcs(#contract{decls=Decls}) ->
|
|||||||
contract_types(#contract{decls=Decls}) ->
|
contract_types(#contract{decls=Decls}) ->
|
||||||
[ D || D <- Decls, is_record(D, type_def) ].
|
[ D || D <- Decls, is_record(D, type_def) ].
|
||||||
|
|
||||||
|
namespace_name(#namespace{con=#con{name=N}}) -> N.
|
||||||
|
|
||||||
|
namespace_funcs(#namespace{decls=Decls}) ->
|
||||||
|
[ D || D <- Decls, is_record(D, letfun) ].
|
||||||
|
|
||||||
|
namespace_types(#namespace{decls=Decls}) ->
|
||||||
|
[ D || D <- Decls, is_record(D, type_def) ].
|
||||||
|
|
||||||
sort_decls(Ds) ->
|
sort_decls(Ds) ->
|
||||||
Sort = fun (D1, D2) ->
|
Sort = fun (D1, D2) ->
|
||||||
aeso_syntax:get_ann(line, D1, 0) =<
|
aeso_syntax:get_ann(line, D1, 0) =<
|
||||||
|
Loading…
x
Reference in New Issue
Block a user