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/compiler/test/bs_bincomp_SUITE.erl | |
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/compiler/test/bs_bincomp_SUITE.erl')
-rw-r--r-- | lib/compiler/test/bs_bincomp_SUITE.erl | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/lib/compiler/test/bs_bincomp_SUITE.erl b/lib/compiler/test/bs_bincomp_SUITE.erl index 93bce5c1f6..5e5f6e2169 100644 --- a/lib/compiler/test/bs_bincomp_SUITE.erl +++ b/lib/compiler/test/bs_bincomp_SUITE.erl @@ -26,7 +26,7 @@ init_per_group/2,end_per_group/2, byte_aligned/1,bit_aligned/1,extended_byte_aligned/1, extended_bit_aligned/1,mixed/1,filters/1,trim_coverage/1, - nomatch/1,sizes/1]). + nomatch/1,sizes/1,general_expressions/1]). -include_lib("common_test/include/ct.hrl"). @@ -36,7 +36,7 @@ all() -> test_lib:recompile(?MODULE), [byte_aligned, bit_aligned, extended_byte_aligned, extended_bit_aligned, mixed, filters, trim_coverage, - nomatch, sizes]. + nomatch, sizes, general_expressions]. groups() -> []. @@ -295,6 +295,48 @@ sizes(Config) when is_list(Config) -> cs_end(), ok. +-define(BAD(E), {'EXIT',{badarg,_}} = (catch << (E) || _ <- [1,2,3] >>)). +-define(BAD_V(E), {'EXIT',{badarg,_}} = (catch << (E) || I <- [1,2,3] >>)). + +general_expressions(_) -> + <<1,2,3>> = << begin <<1,2,3>> end || _ <- [1] >>, + <<"abc">> = << begin <<"abc">> end || _ <- [1] >>, + <<1,2,3>> = << begin + I = <<(I0+1)>>, + id(I) + end || <<I0>> <= <<0,1,2>> >>, + <<1,2,3>> = << I || I <- [<<1,2>>,<<3>>] >>, + <<1,2,3>> = << (id(<<I>>)) || I <- [1,2,3] >>, + <<2,4>> = << case I rem 2 of + 0 -> <<I>>; + 1 -> <<>> + end || I <- [1,2,3,4,5] >>, + <<2,3,4,5,6,7>> = << << (id(<<J>>)) || J <- [2*I,2*I+1] >> || + I <- [1,2,3] >>, + <<1,2,2,3,4,4>> = << if + I rem 2 =:= 0 -> <<I,I>>; + true -> <<I>> + end || I <- [1,2,3,4] >>, + self() ! <<42>>, + <<42>> = << receive B -> B end || _ <- [1] >>, + <<10,5,3>> = << try + <<(10 div I)>> + catch _:_ -> + <<>> + end || I <- [0,1,2,3] >>, + + %% Failing expressions. + ?BAD(bad_atom), + ?BAD(42), + ?BAD(42.0), + ?BAD_V({ok,I}), + ?BAD_V([I]), + ?BAD_V(fun() -> I end), + + ok. + +-undef(BAD). + cs_init() -> erts_debug:set_internal_state(available_internal_state, true), ok. |