@@ -7,6 +7,53 @@ defmodule ElixirScript.Translate.Forms.Match do
77 alias ElixirScript.Translate.Forms.Pattern
88
99 def compile ( { := , _ , [ left , right ] } , state ) do
10+ build_matches ( left , right , % { patterns: [ ] } )
11+ |> compile_match ( state )
12+ end
13+
14+ defp make_list_ref ( array_pattern , params ) do
15+ { ref , params } = make_params ( params )
16+ ref_declaration = Helpers . declare ( ref , J . array_expression ( params ) )
17+
18+ [ array_pattern , ref_declaration ]
19+ end
20+
21+ defp make_tuple_ref ( array_pattern , params ) do
22+ { ref , params } = make_params ( params )
23+
24+ ref_declaration = Helpers . declare ( ref , Helpers . new (
25+ Helpers . tuple ( ) ,
26+ params
27+ ) )
28+ [ array_pattern , ref_declaration ]
29+ end
30+
31+
32+ defp make_params ( params ) do
33+ ref = J . identifier ( "_ref#{ :rand . uniform ( 10000000 ) } " )
34+
35+ params = Enum . map ( params , fn
36+ ( nil ) -> J . identifier ( :undefined )
37+ ( x ) -> x
38+ end )
39+
40+ { ref , params }
41+ end
42+
43+ defp build_matches ( pattern , { := , _ , [ left , right ] } , parts ) do
44+ parts = parts
45+ |> Map . update! ( :patterns , fn ( x ) -> x ++ [ pattern ] end )
46+
47+ build_matches ( left , right , parts )
48+ end
49+
50+ defp build_matches ( left , right , parts ) do
51+ parts
52+ |> Map . update! ( :patterns , fn ( x ) -> x ++ [ left ] end )
53+ |> Map . put ( :expression , right )
54+ end
55+
56+ defp compile_match ( % { patterns: [ left ] , expression: right } , state ) do
1057 { right_ast , state } = Form . compile ( right , state )
1158
1259 { var_dec , right_ast } = case right_ast do
@@ -47,34 +94,56 @@ defmodule ElixirScript.Translate.Forms.Match do
4794 { js_ast , state }
4895 end
4996
97+ defp compile_match ( % { patterns: lefts , expression: right } , state ) do
98+ { right_ast , state } = Form . compile ( right , state )
5099
51- defp make_list_ref ( array_pattern , params ) do
52- { ref , params } = make_params ( params )
53- ref_declaration = Helpers . declare ( ref , J . array_expression ( params ) )
54-
55- [ array_pattern , ref_declaration ]
56- end
57-
58- defp make_tuple_ref ( array_pattern , params ) do
59- { ref , params } = make_params ( params )
60-
61- ref_declaration = Helpers . declare ( ref , Helpers . new (
62- Helpers . tuple ( ) ,
63- params
64- ) )
65- [ array_pattern , ref_declaration ]
66- end
67-
68-
69- defp make_params ( params ) do
70- ref = J . identifier ( "_ref#{ :rand . uniform ( 10000000 ) } " )
100+ { var_dec , right_ast } = case right_ast do
101+ [ variable_declaration , x ] ->
102+ { variable_declaration , x }
103+ x ->
104+ { nil , x }
105+ end
71106
72- params = Enum . map ( params , fn
73- ( nil ) -> J . identifier ( :undefined )
74- ( x ) -> x
107+ intermediate_assign = Helpers . assign (
108+ J . identifier ( "__intermediate__" ) ,
109+ right_ast
110+ )
111+
112+ { js_ast , state } = Enum . map_reduce ( lefts , state , fn ( left , state ) ->
113+ { patterns , params , state } = Pattern . compile ( [ left ] , state )
114+
115+ array_pattern = Helpers . declare ( params , Helpers . call (
116+ J . member_expression (
117+ Helpers . patterns ( ) ,
118+ J . identifier ( "match" )
119+ ) ,
120+ [ hd ( patterns ) , J . identifier ( "__intermediate__" ) ]
121+ ) )
122+
123+ js_ast = case left do
124+ list when is_list ( list ) ->
125+ make_list_ref ( array_pattern , params )
126+ { _ , _ } ->
127+ make_tuple_ref ( array_pattern , params )
128+ { :{} , _ , _ } ->
129+ make_tuple_ref ( array_pattern , params )
130+ _ ->
131+ List . wrap ( array_pattern )
132+ end
133+
134+ js_ast = case var_dec do
135+ nil ->
136+ js_ast
137+ x ->
138+ [ x ] ++ js_ast
139+ end
140+
141+ { js_ast , state }
75142 end )
76143
77- { ref , params }
144+ js_ast = [ intermediate_assign ] ++ List . flatten ( js_ast )
145+
146+ { js_ast , state }
78147 end
79148
80149end
0 commit comments