@@ -274,6 +274,8 @@ expr({lc,_,E,Qs}, Bs, Lf, Ef, RBs, FUVs) ->
274
274
eval_lc (E , Qs , Bs , Lf , Ef , RBs , FUVs );
275
275
expr ({bc ,_ ,E ,Qs }, Bs , Lf , Ef , RBs , FUVs ) ->
276
276
eval_bc (E , Qs , Bs , Lf , Ef , RBs , FUVs );
277
+ expr ({mc ,_ ,E ,Qs }, Bs , Lf , Ef , RBs , FUVs ) ->
278
+ eval_mc (E , Qs , Bs , Lf , Ef , RBs , FUVs );
277
279
expr ({tuple ,_ ,Es }, Bs0 , Lf , Ef , RBs , FUVs ) ->
278
280
{Vs ,Bs } = expr_list (Es , Bs0 , Lf , Ef , FUVs ),
279
281
ret_expr (list_to_tuple (Vs ), Bs , RBs );
@@ -523,6 +525,9 @@ expr({bin,_,Fs}, Bs0, Lf, Ef, RBs, FUVs) ->
523
525
expr ({remote ,_ ,_ ,_ }, _Bs , _Lf , _Ef , _RBs , _FUVs ) ->
524
526
erlang :raise (error , {badexpr ,':' }, ? STACKTRACE ).
525
527
528
+ apply_error (Reason , Stack , _Anno , Bs0 , Ef , RBs ) ->
529
+ do_apply (erlang , raise , [error , Reason , Stack ], Bs0 , Ef , RBs ).
530
+
526
531
find_maxline (LC ) ->
527
532
put ('$erl_eval_max_line' , 0 ),
528
533
F = fun (A ) ->
@@ -737,17 +742,15 @@ do_apply(Mod, Func, As, Bs0, Ef, RBs) ->
737
742
eval_lc (E , Qs , Bs , Lf , Ef , RBs , FUVs ) ->
738
743
ret_expr (lists :reverse (eval_lc1 (E , Qs , Bs , Lf , Ef , FUVs , [])), Bs , RBs ).
739
744
740
- eval_lc1 (E , [{generate ,_ ,P ,L0 }|Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
741
- {value ,L1 ,_Bs1 } = expr (L0 , Bs0 , Lf , Ef , none , FUVs ),
742
- CompFun = fun (Bs , Acc ) -> eval_lc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
743
- eval_generate (L1 , P , Bs0 , Lf , Ef , CompFun , Acc0 );
744
- eval_lc1 (E , [{b_generate ,_ ,P ,L0 }|Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
745
- {value ,Bin ,_Bs1 } = expr (L0 , Bs0 , Lf , Ef , none , FUVs ),
746
- CompFun = fun (Bs , Acc ) -> eval_lc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
747
- eval_b_generate (Bin , P , Bs0 , Lf , Ef , CompFun , Acc0 );
748
- eval_lc1 (E , [F |Qs ], Bs0 , Lf , Ef , FUVs , Acc ) ->
749
- CompFun = fun (Bs ) -> eval_lc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
750
- eval_filter (F , Bs0 , Lf , Ef , CompFun , FUVs , Acc );
745
+ eval_lc1 (E , [Q |Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
746
+ case is_generator (Q ) of
747
+ true ->
748
+ CF = fun (Bs , Acc ) -> eval_lc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
749
+ eval_generator (Q , Bs0 , Lf , Ef , FUVs , Acc0 , CF );
750
+ false ->
751
+ CF = fun (Bs ) -> eval_lc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc0 ) end ,
752
+ eval_filter (Q , Bs0 , Lf , Ef , CF , FUVs , Acc0 )
753
+ end ;
751
754
eval_lc1 (E , [], Bs , Lf , Ef , FUVs , Acc ) ->
752
755
{value ,V ,_ } = expr (E , Bs , Lf , Ef , none , FUVs ),
753
756
[V |Acc ].
@@ -759,21 +762,67 @@ eval_lc1(E, [], Bs, Lf, Ef, FUVs, Acc) ->
759
762
eval_bc (E , Qs , Bs , Lf , Ef , RBs , FUVs ) ->
760
763
ret_expr (eval_bc1 (E , Qs , Bs , Lf , Ef , FUVs , <<>>), Bs , RBs ).
761
764
762
- eval_bc1 (E , [{b_generate ,_ ,P ,L0 }|Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
763
- {value ,Bin ,_Bs1 } = expr (L0 , Bs0 , Lf , Ef , none , FUVs ),
764
- CompFun = fun (Bs , Acc ) -> eval_bc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
765
- eval_b_generate (Bin , P , Bs0 , Lf , Ef , CompFun , Acc0 );
766
- eval_bc1 (E , [{generate ,_ ,P ,L0 }|Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
767
- {value ,List ,_Bs1 } = expr (L0 , Bs0 , Lf , Ef , none , FUVs ),
768
- CompFun = fun (Bs , Acc ) -> eval_bc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
769
- eval_generate (List , P , Bs0 , Lf , Ef , CompFun , Acc0 );
770
- eval_bc1 (E , [F |Qs ], Bs0 , Lf , Ef , FUVs , Acc ) ->
771
- CompFun = fun (Bs ) -> eval_bc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
772
- eval_filter (F , Bs0 , Lf , Ef , CompFun , FUVs , Acc );
765
+ eval_bc1 (E , [Q |Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
766
+ case is_generator (Q ) of
767
+ true ->
768
+ CF = fun (Bs , Acc ) -> eval_bc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
769
+ eval_generator (Q , Bs0 , Lf , Ef , FUVs , Acc0 , CF );
770
+ false ->
771
+ CF = fun (Bs ) -> eval_bc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc0 ) end ,
772
+ eval_filter (Q , Bs0 , Lf , Ef , CF , FUVs , Acc0 )
773
+ end ;
773
774
eval_bc1 (E , [], Bs , Lf , Ef , FUVs , Acc ) ->
774
775
{value ,V ,_ } = expr (E , Bs , Lf , Ef , none , FUVs ),
775
776
<<Acc /bitstring ,V /bitstring >>.
776
777
778
+
779
+ % % eval_mc(Expr, [Qualifier], Bindings, LocalFunctionHandler,
780
+ % % ExternalFuncHandler, RetBindings) ->
781
+ % % {value,Value,Bindings} | Value
782
+
783
+ eval_mc (E , Qs , Bs , Lf , Ef , RBs , FUVs ) ->
784
+ L = eval_mc1 (E , Qs , Bs , Lf , Ef , FUVs , []),
785
+ Map = maps :from_list (L ),
786
+ ret_expr (Map , Bs , RBs ).
787
+
788
+ eval_mc1 (E , [Q |Qs ], Bs0 , Lf , Ef , FUVs , Acc0 ) ->
789
+ case is_generator (Q ) of
790
+ true ->
791
+ CF = fun (Bs , Acc ) -> eval_mc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc ) end ,
792
+ eval_generator (Q , Bs0 , Lf , Ef , FUVs , Acc0 , CF );
793
+ false ->
794
+ CF = fun (Bs ) -> eval_mc1 (E , Qs , Bs , Lf , Ef , FUVs , Acc0 ) end ,
795
+ eval_filter (Q , Bs0 , Lf , Ef , CF , FUVs , Acc0 )
796
+ end ;
797
+ eval_mc1 ({map_field_assoc ,Lfa ,K0 ,V0 }, [], Bs , Lf , Ef , FUVs , Acc ) ->
798
+ {value ,KV ,_ } = expr ({tuple ,Lfa ,[K0 ,V0 ]}, Bs , Lf , Ef , none , FUVs ),
799
+ [KV |Acc ].
800
+
801
+ eval_generator ({generate ,_Anno ,P ,L0 }, Bs0 , Lf , Ef , FUVs , Acc0 , CompFun ) ->
802
+ {value ,L1 ,_Bs1 } = expr (L0 , Bs0 , Lf , Ef , none , FUVs ),
803
+ eval_generate (L1 , P , Bs0 , Lf , Ef , CompFun , Acc0 );
804
+ eval_generator ({b_generate ,_Anno ,P ,Bin0 }, Bs0 , Lf , Ef , FUVs , Acc0 , CompFun ) ->
805
+ {value ,Bin ,_Bs1 } = expr (Bin0 , Bs0 , Lf , Ef , none , FUVs ),
806
+ eval_b_generate (Bin , P , Bs0 , Lf , Ef , CompFun , Acc0 );
807
+ eval_generator ({m_generate ,Anno ,P ,Map0 }, Bs0 , Lf , Ef , FUVs , Acc0 , CompFun ) ->
808
+ {map_field_exact ,_ ,K ,V } = P ,
809
+ {value ,Map ,_Bs1 } = expr (Map0 , Bs0 , Lf , Ef , none , FUVs ),
810
+ Iter = case is_map (Map ) of
811
+ true ->
812
+ maps :iterator (Map );
813
+ false ->
814
+ % % Validate iterator.
815
+ try maps :foreach (fun (_ , _ ) -> ok end , Map ) of
816
+ _ ->
817
+ Map
818
+ catch
819
+ _ :_ ->
820
+ apply_error ({bad_generator ,Map }, ? STACKTRACE ,
821
+ Anno , Bs0 , Ef , none )
822
+ end
823
+ end ,
824
+ eval_m_generate (Iter , {tuple ,Anno ,[K ,V ]}, Anno , Bs0 , Lf , Ef , CompFun , Acc0 ).
825
+
777
826
eval_generate ([V |Rest ], P , Bs0 , Lf , Ef , CompFun , Acc ) ->
778
827
case match (P , V , new_bindings (Bs0 ), Bs0 ) of
779
828
{match ,Bsn } ->
@@ -804,6 +853,22 @@ eval_b_generate(<<_/bitstring>>=Bin, P, Bs0, Lf, Ef, CompFun, Acc) ->
804
853
eval_b_generate (Term , _P , _Bs0 , _Lf , _Ef , _CompFun , _Acc ) ->
805
854
erlang :raise (error , {bad_generator ,Term }, ? STACKTRACE ).
806
855
856
+
857
+ eval_m_generate (Iter0 , P , Anno , Bs0 , Lf , Ef , CompFun , Acc0 ) ->
858
+ case maps :next (Iter0 ) of
859
+ {K ,V ,Iter } ->
860
+ case match (P , {K ,V }, new_bindings (Bs0 ), Bs0 ) of
861
+ {match ,Bsn } ->
862
+ Bs2 = add_bindings (Bsn , Bs0 ),
863
+ Acc = CompFun (Bs2 , Acc0 ),
864
+ eval_m_generate (Iter , P , Anno , Bs0 , Lf , Ef , CompFun , Acc );
865
+ nomatch ->
866
+ eval_m_generate (Iter , P , Anno , Bs0 , Lf , Ef , CompFun , Acc0 )
867
+ end ;
868
+ none ->
869
+ Acc0
870
+ end .
871
+
807
872
eval_filter (F , Bs0 , Lf , Ef , CompFun , FUVs , Acc ) ->
808
873
case erl_lint :is_guard_test (F ) of
809
874
true ->
@@ -820,6 +885,11 @@ eval_filter(F, Bs0, Lf, Ef, CompFun, FUVs, Acc) ->
820
885
end
821
886
end .
822
887
888
+ is_generator ({generate ,_ ,_ ,_ }) -> true ;
889
+ is_generator ({b_generate ,_ ,_ ,_ }) -> true ;
890
+ is_generator ({m_generate ,_ ,_ ,_ }) -> true ;
891
+ is_generator (_ ) -> false .
892
+
823
893
% % eval_map_fields([Field], Bindings, LocalFunctionHandler,
824
894
% % ExternalFuncHandler) ->
825
895
% % {[{map_assoc | map_exact,Key,Value}],Bindings}
@@ -1692,4 +1762,4 @@ merge_with_1({K, V2, Iterator}, Map1, Map2, Combiner) ->
1692
1762
merge_with_1 (maps :next (Iterator ), maps :put (K , V2 , Map1 ), Map2 , Combiner )
1693
1763
end ;
1694
1764
merge_with_1 (none , Result , _ , _ ) ->
1695
- Result .
1765
+ Result .
0 commit comments