diff options
author | Björn Gustavsson <[email protected]> | 2016-03-01 06:23:36 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-03-01 13:59:22 +0100 |
commit | 205405f0bf1d2fa37d4c8170c11689a2937f5d9c (patch) | |
tree | a55b2a94a43ecf521db5c06a41be2af0a0eda44b /lib/tools | |
parent | 156aea75186fe9de64b87c2c6919db9abf4a0d60 (diff) | |
download | otp-205405f0bf1d2fa37d4c8170c11689a2937f5d9c.tar.gz otp-205405f0bf1d2fa37d4c8170c11689a2937f5d9c.tar.bz2 otp-205405f0bf1d2fa37d4c8170c11689a2937f5d9c.zip |
Generalize bit string comprehensions
The expression in a bit string comprehension is limited to a
literal bit string expression. That is, the following code
is legal:
<< <<X>> || X <- List >>
but not this code:
<< foo(X) || X <- List >>
The limitation is annoying. For one thing, tools that transform
the abstract format must be careful not to produce code such as:
<< begin
%% Some instrumentation code.
<<X>>
end || X <- List >>
One reason for the limitation could be that we'll get
reduce/reduce conflicts if we try to allow an arbitrary
expression in a bit string comprehension:
binary_comprehension -> '<<' expr '||' lc_exprs '>>' :
{bc,?anno('$1'),'$2','$4'}.
Unfortunately, there does not seem to be an easy way to work
around that problem. The best we can do is to allow 'expr_max'
expressions (as in the binary syntax):
binary_comprehension -> '<<' expr_max '||' lc_exprs '>>' :
{bc,?anno('$1'),'$2','$4'}.
That will work, but functions calls must be enclosed in
parentheses:
<< (foo(X)) || X <- List >>
Diffstat (limited to 'lib/tools')
-rw-r--r-- | lib/tools/src/cover.erl | 4 | ||||
-rw-r--r-- | lib/tools/test/cover_SUITE.erl | 29 |
2 files changed, 22 insertions, 11 deletions
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 3732b0fc85..87de31919f 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -2002,9 +2002,7 @@ munge_expr({lc,Line,Expr,Qs}, Vars) -> {MungedQs, Vars3} = munge_qualifiers(Qs, Vars2), {{lc,Line,MungedExpr,MungedQs}, Vars3}; munge_expr({bc,Line,Expr,Qs}, Vars) -> - {bin,BLine,[{bin_element,EL,Val,Sz,TSL}|Es]} = Expr, - Expr2 = {bin,BLine,[{bin_element,EL,Val,Sz,TSL}|Es]}, - {MungedExpr,Vars2} = munge_expr(Expr2, Vars), + {MungedExpr,Vars2} = munge_expr(?BLOCK1(Expr), Vars), {MungedQs, Vars3} = munge_qualifiers(Qs, Vars2), {{bc,Line,MungedExpr,MungedQs}, Vars3}; munge_expr({block,Line,Body}, Vars) -> diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index b9a9cd5be4..d4b346c407 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -29,7 +29,7 @@ all() -> NoStartStop = [eif,otp_5305,otp_5418,otp_7095,otp_8273, otp_8340,otp_8188,compile_beam_opts,eep37, analyse_no_beam, line_0, compile_beam_no_file, - otp_13277], + otp_13277, otp_13289], StartStop = [start, compile, analyse, misc, stop, distribution, reconnect, die_and_reconnect, dont_reconnect_after_stop, stop_node_after_disconnect, @@ -1253,7 +1253,7 @@ otp_8340(doc) -> ["OTP-8340. Bug."]; otp_8340(suite) -> []; otp_8340(Config) when is_list(Config) -> - ?line [{{t,1},1},{{t,4},1}] = + [{{t,1},1},{{t,2},1},{{t,4},1}] = analyse_expr(<<"<< \n" " <<3:2, \n" " SeqId:62>> \n" @@ -1547,10 +1547,8 @@ comprehension_8188(Cf) -> " true]. \n" % 2 " two() -> 2">>, Cf), % 1 - %% The template cannot have a counter since it is not allowed to - %% be a block. ?line [{{t,1},1}, - %% {{t,2},2}, + {{t,2},2}, {{t,3},1}, {{t,4},1}, {{t,5},0}, @@ -1560,7 +1558,7 @@ comprehension_8188(Cf) -> {{t,13},2}, {{t,14},2}] = analyse_expr(<<"<< \n" % 1 - " << (X*2) >> || \n" % 2 (now: 0) + " << (X*2) >> || \n" % 2 " <<X>> <= << (case two() of\n" " 2 -> 1;\n" % 1 " _ -> 2\n" % 0 @@ -1575,7 +1573,7 @@ comprehension_8188(Cf) -> "two() -> 2">>, Cf), ?line [{{t,1},1}, - %% {{t,2},4}, + {{t,2},4}, {{t,4},1}, {{t,6},1}, {{t,7},0}, @@ -1584,7 +1582,7 @@ comprehension_8188(Cf) -> {{t,12},4}, {{t,13},1}] = analyse_expr(<<"<< \n" % 1 - " << (2)\n" % 4 (now: 0) + " << (2)\n" % 4 " :(8) >> || \n" " <<X>> <= << 1,\n" % 1 " (case two() of \n" @@ -1766,6 +1764,21 @@ otp_13277(Config) -> ?line ok = file:delete(File), ok. +%% Test general expressions in a binary comprehension. +otp_13289(Config) -> + Test = <<"-module(t). + -export([t/0]). + + t() -> + << (id(<<I>>)) || I <- [1,2,3] >>. + + id(I) -> I. + ">>, + File = cc_mod(t, Test, Config), + <<1,2,3>> = t:t(), + ok = file:delete(File), + ok. + %%--Auxiliary------------------------------------------------------------ analyse_expr(Expr, Config) -> |