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