Fixed cyclic includes
This commit is contained in:
parent
d64f41dc13
commit
d170dd00eb
@ -36,6 +36,7 @@
|
||||
| pp_assembler
|
||||
| pp_bytecode
|
||||
| no_code
|
||||
| no_implicit_stdlib
|
||||
| {backend, aevm | fate}
|
||||
| {include, {file_system, [string()]} |
|
||||
{explicit_files, #{string() => binary()}}}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
-export([string/1,
|
||||
string/2,
|
||||
string/3,
|
||||
type/1]).
|
||||
|
||||
-include("aeso_parse_lib.hrl").
|
||||
@ -16,13 +17,25 @@
|
||||
|
||||
-spec string(string()) -> parse_result().
|
||||
string(String) ->
|
||||
string(String, []).
|
||||
string(String, sets:new(), []).
|
||||
|
||||
-spec string(string(), aeso_compiler:options()) -> parse_result().
|
||||
|
||||
-spec string(string(), compiler:options()) -> parse_result().
|
||||
string(String, Opts) ->
|
||||
string(String, sets:new(), Opts).
|
||||
|
||||
-spec string(string(), sets:set(string()), aeso_compiler:options()) -> parse_result().
|
||||
string(String, Included, Opts) ->
|
||||
case parse_and_scan(file(), String, Opts) of
|
||||
{ok, AST} ->
|
||||
expand_includes(AST, Opts);
|
||||
STD = case lists:member(no_implicit_stdlib, Opts) of
|
||||
false -> [{ include, [{src_file, File}, {origin, system}]
|
||||
, {string, [{src_file, File}, {origin, system}], File}}
|
||||
|| {File, _} <- aeso_stdlib:stdlib_list()
|
||||
];
|
||||
true -> []
|
||||
end,
|
||||
expand_includes(STD ++ AST, Included, Opts);
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
end.
|
||||
@ -230,7 +243,7 @@ exprAtom() ->
|
||||
, {bool, keyword(false), false}
|
||||
, ?LET_P(Fs, brace_list(?LAZY_P(field_assignment())), record(Fs))
|
||||
, {list, [], bracket_list(Expr)}
|
||||
, ?RULE(keyword('['), Expr, tok('|'), comma_sep(?LAZY_P(comprehension_bind())), tok(']'), list_comp_e(_1, _2, _4))
|
||||
, ?RULE(keyword('['), Expr, token('|'), comma_sep(?LAZY_P(comprehension_bind())), tok(']'), list_comp_e(_1, _2, _4))
|
||||
, ?RULE(tok('['), Expr, binop('..'), Expr, tok(']'), _3(_2, _4))
|
||||
, ?RULE(keyword('('), comma_sep(Expr), tok(')'), tuple_e(_1, _2))
|
||||
])
|
||||
@ -527,35 +540,40 @@ bad_expr_err(Reason, E) ->
|
||||
prettypr:nest(2, aeso_pretty:expr(E))])).
|
||||
|
||||
%% -- Helper functions -------------------------------------------------------
|
||||
expand_includes(AST, Opts) ->
|
||||
expand_includes(AST, [], Opts).
|
||||
expand_includes(AST, Included, Opts) ->
|
||||
expand_includes(AST, Included, [], Opts).
|
||||
|
||||
expand_includes([], Acc, _Opts) ->
|
||||
expand_includes([], _Included, Acc, _Opts) ->
|
||||
{ok, lists:reverse(Acc)};
|
||||
expand_includes([{include, Ann, S = {string, _, File}} | AST], Acc, Opts) ->
|
||||
case {read_file(File, Opts), maps:find(File, aeso_stdlib:stdlib())} of
|
||||
{{ok, _}, {ok,_ }} ->
|
||||
return_error(ann_pos(Ann), "Illegal redefinition of standard library " ++ File);
|
||||
{_, {ok, Lib}} ->
|
||||
case string(Lib) of
|
||||
{ok, AST1} ->
|
||||
expand_includes(AST1 ++ AST, Acc, Opts);
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
end;
|
||||
{{ok, Bin}, _} ->
|
||||
expand_includes([{include, Ann, S = {string, _, File}} | AST], Included, Acc, Opts) ->
|
||||
case sets:is_element(File, Included) of
|
||||
false ->
|
||||
Opts1 = lists:keystore(src_file, 1, Opts, {src_file, File}),
|
||||
case string(binary_to_list(Bin), Opts1) of
|
||||
{ok, AST1} ->
|
||||
expand_includes(AST1 ++ AST, Acc, Opts);
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
Included1 = sets:add_element(File, Included),
|
||||
case {read_file(File, Opts), maps:find(File, aeso_stdlib:stdlib())} of
|
||||
{{ok, _}, {ok,_ }} ->
|
||||
return_error(ann_pos(Ann), "Illegal redefinition of standard library " ++ File);
|
||||
{_, {ok, Lib}} ->
|
||||
case string(Lib, Included1, Opts1) of
|
||||
{ok, AST1} ->
|
||||
expand_includes(AST1 ++ AST, Included1, Acc, Opts);
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
end;
|
||||
{{ok, Bin}, _} ->
|
||||
case string(binary_to_list(Bin), Included1, Opts1) of
|
||||
{ok, AST1} ->
|
||||
expand_includes(AST1 ++ AST, Included1, Acc, Opts);
|
||||
Err = {error, _} ->
|
||||
Err
|
||||
end;
|
||||
{_, _} ->
|
||||
{error, {get_pos(S), include_error, File}}
|
||||
end;
|
||||
{{error, _}, _} ->
|
||||
{error, {get_pos(S), include_error, File}}
|
||||
true -> expand_includes(AST, Included, Acc, Opts)
|
||||
end;
|
||||
expand_includes([E | AST], Acc, Opts) ->
|
||||
expand_includes(AST, [E | Acc], Opts).
|
||||
expand_includes([E | AST], Included, Acc, Opts) ->
|
||||
expand_includes(AST, Included, [E | Acc], Opts).
|
||||
|
||||
read_file(File, Opts) ->
|
||||
case proplists:get_value(include, Opts, {explicit_files, #{}}) of
|
||||
|
@ -10,14 +10,15 @@
|
||||
|
||||
-module(aeso_stdlib).
|
||||
|
||||
-export([stdlib/0]).
|
||||
-export([stdlib/0, stdlib_list/0]).
|
||||
|
||||
stdlib() ->
|
||||
maps:from_list(
|
||||
[ {<<"List.aes">>, std_list()}
|
||||
%% , {<<"Func.aes">>, std_function()}
|
||||
]
|
||||
).
|
||||
maps:from_list(stdlib_list()).
|
||||
|
||||
stdlib_list() ->
|
||||
[ {<<"List.aes">>, std_list()}
|
||||
%% , {<<"Func.aes">>, std_function()}
|
||||
].
|
||||
|
||||
std_function() ->
|
||||
"
|
||||
@ -51,7 +52,8 @@ namespace Func =
|
||||
".
|
||||
|
||||
std_list() ->
|
||||
"
|
||||
"namespace List =\n function flat_map() = 3\n".
|
||||
x() ->"
|
||||
namespace List =
|
||||
|
||||
function empty(l) = switch(l)
|
||||
|
@ -9,7 +9,7 @@ simple_aci_test_() ->
|
||||
|
||||
test_contract(N) ->
|
||||
{Contract,MapACI,DecACI} = test_cases(N),
|
||||
{ok,JSON} = aeso_aci:contract_interface(json, Contract),
|
||||
{ok,JSON} = aeso_aci:contract_interface(json, Contract, [no_implicit_stdlib]),
|
||||
?assertEqual([MapACI], JSON),
|
||||
?assertEqual({ok, DecACI}, aeso_aci:render_aci_json(JSON)).
|
||||
|
||||
@ -98,7 +98,7 @@ aci_test_contract(Name) ->
|
||||
{ok, ContractStub} = aeso_aci:render_aci_json(JSON),
|
||||
|
||||
io:format("STUB:\n~s\n", [ContractStub]),
|
||||
check_stub(ContractStub, [{src_file, Name}]),
|
||||
check_stub(ContractStub, [{src_file, Name}, no_implicit_stdlib]),
|
||||
|
||||
ok.
|
||||
|
||||
|
@ -15,7 +15,7 @@ simple_contracts_test_() ->
|
||||
?assertMatch(
|
||||
[{contract, _, {con, _, "Identity"},
|
||||
[{letfun, _, {id, _, "id"}, [{arg, _, {id, _, "x"}, {id, _, "_"}}], {id, _, "_"},
|
||||
{id, _, "x"}}]}], parse_string(Text)),
|
||||
{id, _, "x"}}]}], parse_string(Text, [no_implicit_stdlib])),
|
||||
ok
|
||||
end},
|
||||
{"Operator precedence test.",
|
||||
@ -71,21 +71,23 @@ parse_contract(Name) ->
|
||||
roundtrip_contract(Name) ->
|
||||
round_trip(aeso_test_utils:read_contract(Name)).
|
||||
|
||||
parse_string(Text) ->
|
||||
case aeso_parser:string(Text) of
|
||||
parse_string(Text) -> parse_string(Text, []).
|
||||
|
||||
parse_string(Text, Opts) ->
|
||||
case aeso_parser:string(Text, Opts) of
|
||||
{ok, Contract} -> Contract;
|
||||
Err -> error(Err)
|
||||
end.
|
||||
|
||||
parse_expr(Text) ->
|
||||
[{letval, _, _, _, Expr}] =
|
||||
parse_string("let _ = " ++ Text),
|
||||
parse_string("let _ = " ++ Text, [no_implicit_stdlib]),
|
||||
Expr.
|
||||
|
||||
round_trip(Text) ->
|
||||
Contract = parse_string(Text),
|
||||
Contract = parse_string(Text, [no_implicit_stdlib]),
|
||||
Text1 = prettypr:format(aeso_pretty:decls(Contract)),
|
||||
Contract1 = parse_string(Text1),
|
||||
Contract1 = parse_string(Text1, [no_implicit_stdlib]),
|
||||
NoSrcLoc = remove_line_numbers(Contract),
|
||||
NoSrcLoc1 = remove_line_numbers(Contract1),
|
||||
?assertMatch(NoSrcLoc, diff(NoSrcLoc, NoSrcLoc1)).
|
||||
|
Loading…
x
Reference in New Issue
Block a user