11-module (elixir_bitstring ).
22-export ([expand /5 , format_error /1 , validate_spec /2 ]).
3- -import (elixir_errors , [function_error /4 ,  file_error / 4 ]).
3+ -import (elixir_errors , [function_error /4 ]).
44-include (" elixir.hrl"  ).
55
66expand_match (Expr , {S , OriginalS }, E ) -> 
@@ -13,11 +13,6 @@ expand(Meta, Args, S, E, RequireSize) ->
1313      {EArgs , Alignment , {SA , _ }, EA } = 
1414        expand (Meta , fun  expand_match /3 , Args , [], {S , S }, E , 0 , RequireSize ),
1515
16-       case  find_match (EArgs ) of 
17-         false  -> ok ;
18-         Match  -> file_error (Meta , EA , ? MODULE , {nested_match , Match })
19-       end ,
20- 
2116      {{'<<>>' , [{alignment , Alignment } | Meta ], EArgs }, SA , EA };
2217    _  ->
2318      PairS  =  {elixir_env :prepare_write (S ), S },
@@ -32,6 +27,7 @@ expand(_BitstrMeta, _Fun, [], Acc, S, E, Alignment, _RequireSize) ->
3227  {lists :reverse (Acc ), Alignment , S , E };
3328expand (BitstrMeta , Fun , [{'::' , Meta , [Left , Right ]} | T ], Acc , S , E , Alignment , RequireSize ) -> 
3429  {ELeft , {SL , OriginalS }, EL } =  expand_expr (Left , Fun , S , E ),
30+   validate_expr (ELeft , Meta , E ),
3531
3632  MatchOrRequireSize  =  RequireSize  or  is_match_size (T , EL ),
3733  EType  =  expr_type (ELeft ),
@@ -47,6 +43,7 @@ expand(BitstrMeta, Fun, [{'::', Meta, [Left, Right]} | T], Acc, S, E, Alignment,
4743expand (BitstrMeta , Fun , [H  | T ], Acc , S , E , Alignment , RequireSize ) -> 
4844  Meta  =  extract_meta (H , BitstrMeta ),
4945  {ELeft , {SS , OriginalS }, ES } =  expand_expr (H , Fun , S , E ),
46+   validate_expr (ELeft , Meta , E ),
5047
5148  MatchOrRequireSize  =  RequireSize  or  is_match_size (T , ES ),
5249  EType  =  expr_type (ELeft ),
@@ -145,6 +142,17 @@ expand_expr({{'.', _, [Mod, to_string]}, _, [Arg]} = AST, Fun, S, #{context := C
145142expand_expr (Component , Fun , S , E ) -> 
146143  Fun (Component , S , E ).
147144
145+ validate_expr (Expr , Meta , #{context  :=  match } =  E ) -> 
146+   case  Expr  of 
147+     {Var , _Meta , Ctx } when  is_atom (Var ), is_atom (Ctx ) -> ok ;
148+     {'<<>>' , _ , _ } -> ok ;
149+     {'^' , _ , _ } -> ok ;
150+     _  when  is_number (Expr ); is_binary (Expr ) -> ok ;
151+     _  -> function_error (extract_meta (Expr , Meta ), E , ? MODULE , {unknown_match , Expr })
152+   end ;
153+ validate_expr (_Expr , _Meta , _E ) -> 
154+   ok .
155+ 
148156% % Expands and normalizes types of a bitstring.
149157
150158expand_specs (ExprType , Meta , Info , S , OriginalS , E , ExpectSize ) -> 
@@ -353,18 +361,6 @@ valid_float_size(_) -> false.
353361add_spec (default , Spec ) ->  Spec ;
354362add_spec (Key , Spec ) ->  [{Key , [], nil } | Spec ].
355363
356- find_match ([{'=' , _ , [_Left , _Right ]} =  Expr  | _Rest ]) -> 
357-   Expr ;
358- find_match ([{_ , _ , Args } | Rest ]) when  is_list (Args ) -> 
359-   case  find_match (Args ) of 
360-     false  -> find_match (Rest );
361-     Match  -> Match 
362-   end ;
363- find_match ([_Arg  | Rest ]) -> 
364-   find_match (Rest );
365- find_match ([]) -> 
366-   false .
367- 
368364format_error ({unaligned_binary , Expr }) -> 
369365  Message  =  " expected ~ts  to be a binary but its number of bits is not divisible by 8"  ,
370366  io_lib :format (Message , ['Elixir.Macro' :to_string (Expr )]);
@@ -409,10 +405,9 @@ format_error({bittype_mismatch, Val1, Val2, Where}) ->
409405format_error ({bad_unit_argument , Unit }) -> 
410406  io_lib :format (" unit in bitstring expects an integer as argument, got: ~ts "  ,
411407                ['Elixir.Macro' :to_string (Unit )]);
412- format_error ({nested_match , Expr }) -> 
408+ format_error ({unknown_match , Expr }) -> 
413409  Message  = 
414-     " cannot pattern match inside a bitstring " 
415-       " that is already in match, got: ~ts "  ,
410+     " a bitstring only accepts binaries, numbers, and variables inside a match, got: ~ts "  ,
416411  io_lib :format (Message , ['Elixir.Macro' :to_string (Expr )]);
417412format_error ({undefined_var_in_spec , Var }) -> 
418413  Message  = 
0 commit comments