@@ -27,70 +27,70 @@ defmodule ElixirScript.Translator do
2727 @ doc """
2828 Translates Elixir AST to JavaScript AST
2929 """
30- def translate ( ast ) do
31- do_translate ( ast )
30+ def translate ( ast , env \\ __ENV__ ) do
31+ do_translate ( ast , env )
3232 end
3333
34- defp do_translate ( ast ) when is_number ( ast ) or is_binary ( ast ) or is_boolean ( ast ) or is_nil ( ast ) do
34+ defp do_translate ( ast , env ) when is_number ( ast ) or is_binary ( ast ) or is_boolean ( ast ) or is_nil ( ast ) do
3535 Primitive . make_literal ( ast )
3636 end
3737
38- defp do_translate ( ast ) when is_atom ( ast ) do
38+ defp do_translate ( ast , env ) when is_atom ( ast ) do
3939 Primitive . make_atom ( ast )
4040 end
4141
42- defp do_translate ( ast ) when is_list ( ast ) do
43- Primitive . make_list ( ast )
42+ defp do_translate ( ast , env ) when is_list ( ast ) do
43+ Primitive . make_list ( ast , env )
4444 end
4545
46- defp do_translate ( { one , two } ) do
47- Primitive . make_tuple ( { one , two } )
46+ defp do_translate ( { one , two } , env ) do
47+ Primitive . make_tuple ( { one , two } , env )
4848 end
4949
50- defp do_translate ( { :& , [ ] , [ number ] } ) when is_number ( number ) do
50+ defp do_translate ( { :& , [ ] , [ number ] } , env ) when is_number ( number ) do
5151 Primitive . make_identifier ( String . to_atom ( "__#{ number } " ) )
5252 end
5353
54- defp do_translate ( { :& , _ , [ { :/ , _ , [ { { :. , _ , [ { :__aliases__ , _ , module_name } , function_name ] } , _ , [ ] } , arity ] } ] } ) do
54+ defp do_translate ( { :& , _ , [ { :/ , _ , [ { { :. , _ , [ { :__aliases__ , _ , module_name } , function_name ] } , _ , [ ] } , arity ] } ] } , env ) do
5555 function_name = Utils . filter_name ( function_name )
56- Capture . make_capture ( List . last ( module_name ) , function_name , arity )
56+ Capture . make_capture ( List . last ( module_name ) , function_name , arity , env )
5757 end
5858
59- defp do_translate ( { :& , _ , [ { :/ , _ , [ { function_name , _ , _ } , arity ] } ] } ) do
59+ defp do_translate ( { :& , _ , [ { :/ , _ , [ { function_name , _ , _ } , arity ] } ] } , env ) do
6060 function_name = Utils . filter_name ( function_name )
61- Capture . make_capture ( function_name , arity )
61+ Capture . make_capture ( function_name , arity , env )
6262 end
6363
64- defp do_translate ( { :& , _ , body } ) do
64+ defp do_translate ( { :& , _ , body } , env ) do
6565 params = Capture . find_value_placeholders ( body ) |> List . flatten
66- Function . make_anonymous_function ( [ { :-> , [ ] , [ params , body ] } ] )
66+ Function . make_anonymous_function ( [ { :-> , [ ] , [ params , body ] } ] , env )
6767 end
6868
69- defp do_translate ( { :@ , _ , [ { name , _ , [ value ] } ] } ) do
69+ defp do_translate ( { :@ , _ , [ { name , _ , [ value ] } ] } , env ) do
7070 name = Utils . filter_name ( name )
71- Module . make_attribute ( name , value )
71+ Module . make_attribute ( name , value , env )
7272 end
7373
74- defp do_translate ( { :@ , _ , [ { name , _ , _ } ] } ) do
74+ defp do_translate ( { :@ , _ , [ { name , _ , _ } ] } , env ) do
7575 name = Utils . filter_name ( name )
7676 Primitive . make_identifier ( name )
7777 end
7878
79- defp do_translate ( { :% , _ , [ alias_info , data ] } ) do
79+ defp do_translate ( { :% , _ , [ alias_info , data ] } , env ) do
8080 { _ , _ , name } = alias_info
8181 { _ , _ , data } = data
8282 Struct . make_struct ( name , data )
8383 end
8484
85- defp do_translate ( { :%{} , _ , [ { :| , _ , [ map , data ] } ] } ) do
85+ defp do_translate ( { :%{} , _ , [ { :| , _ , [ map , data ] } ] } , env ) do
8686 Map . make_map_update ( map , data ) ;
8787 end
8888
89- defp do_translate ( { :%{} , _ , properties } ) do
89+ defp do_translate ( { :%{} , _ , properties } , env ) do
9090 Map . make_object ( properties )
9191 end
9292
93- defp do_translate ( { :<<>> , _ , elements } ) do
93+ defp do_translate ( { :<<>> , _ , elements } , env ) do
9494 is_interpolated_string = Enum . all? ( elements , fn ( x ) ->
9595 case x do
9696 b when is_binary ( b ) ->
@@ -110,181 +110,202 @@ defmodule ElixirScript.Translator do
110110 end
111111 end
112112
113- defp do_translate ( { { :. , _ , [ Access , :get ] } , _ , [ target , property ] } ) do
113+ defp do_translate ( { { :. , _ , [ Access , :get ] } , _ , [ target , property ] } , env ) do
114114 Map . make_get_property ( target , property )
115115 end
116116
117- defp do_translate ( { :. , _ , [ module_name , function_name ] } ) do
118- Function . make_function_or_property_call ( module_name , function_name )
117+ defp do_translate ( { :. , _ , [ module_name , function_name ] } = ast , env ) do
118+ expanded_ast = Macro . expand ( ast , env )
119+ if expanded_ast == ast do
120+ Function . make_function_or_property_call ( module_name , function_name , env )
121+ else
122+ translate ( expanded_ast , env )
123+ end
119124 end
120125
121- defp do_translate ( { { :. , _ , [ module_name , function_name ] } , _ , [ ] } ) do
122- Function . make_function_or_property_call ( module_name , function_name )
126+ defp do_translate ( { { :. , _ , [ module_name , function_name ] } , _ , [ ] } = ast , env ) do
127+ expanded_ast = Macro . expand ( ast , env )
128+ if expanded_ast == ast do
129+ Function . make_function_or_property_call ( module_name , function_name , env )
130+ else
131+ translate ( expanded_ast , env )
132+ end
123133 end
124134
125- defp do_translate ( { { :. , _ , [ { :__aliases__ , _ , module_name } ] } , _ , params } ) do
126- Function . make_function_call ( hd ( module_name ) , params )
135+ defp do_translate ( { { :. , _ , [ { :__aliases__ , _ , module_name } ] } , _ , params } = ast , env ) do
136+ expanded_ast = Macro . expand ( ast , env )
137+ if expanded_ast == ast do
138+ Function . make_function_call ( hd ( module_name ) , params , env )
139+ else
140+ translate ( expanded_ast , env )
141+ end
127142 end
128143
129- defp do_translate ( { { :. , _ , [ module_name , function_name ] } , _ , params } ) do
130- Function . make_function_call ( module_name , function_name , params )
144+ defp do_translate ( { { :. , _ , [ module_name , function_name ] } , _ , params } = ast , env ) do
145+ expanded_ast = Macro . expand ( ast , env )
146+ if expanded_ast == ast do
147+ Function . make_function_call ( module_name , function_name , params , env )
148+ else
149+ translate ( expanded_ast , env )
150+ end
131151 end
132152
133- defp do_translate ( { :_ , _ , _ } ) do
153+ defp do_translate ( { :_ , _ , _ } , env ) do
134154 Primitive . make_identifier ( :undefined )
135155 end
136156
137- defp do_translate ( { :__aliases__ , _ , aliases } ) do
157+ defp do_translate ( { :__aliases__ , _ , aliases } , env ) do
138158 Primitive . make_identifier ( aliases )
139159 end
140160
141- defp do_translate ( { :__block__ , _ , expressions } ) do
161+ defp do_translate ( { :__block__ , _ , expressions } , env ) do
142162 Block . make_block ( expressions )
143163 end
144164
145- defp do_translate ( { :__DIR__ , _ , _expressions } ) do
165+ defp do_translate ( { :__DIR__ , _ , _expressions } , env ) do
146166 ExKernel . make___DIR__ ( )
147167 end
148168
149- defp do_translate ( { :try , _ , [ blocks ] } ) do
150- Try . make_try ( blocks )
169+ defp do_translate ( { :try , _ , [ blocks ] } , env ) do
170+ Try . make_try ( blocks , env )
151171 end
152172
153- defp do_translate ( { :receive , _ , [ expressions ] } ) do
154- Receive . make_receive ( expressions ) ;
173+ defp do_translate ( { :receive , _ , [ expressions ] } , env ) do
174+ Receive . make_receive ( expressions , env ) ;
155175 end
156176
157- defp do_translate ( { :super , _ , _expressions } ) do
177+ defp do_translate ( { :super , _ , _expressions } , env ) do
158178 raise ElixirScript.UnsupportedError , :super
159179 end
160180
161- defp do_translate ( { :__CALLER__ , _ , _expressions } ) do
181+ defp do_translate ( { :__CALLER__ , _ , _expressions } , env ) do
162182 raise ElixirScript.UnsupportedError , :__CALLER__
163183 end
164184
165- defp do_translate ( { :__ENV__ , _ , _expressions } ) do
185+ defp do_translate ( { :__ENV__ , _ , _expressions } , env ) do
166186 raise ElixirScript.UnsupportedError , :__ENV__
167187 end
168188
169- defp do_translate ( { :quote , _ , [ [ do: expr ] ] } ) do
189+ defp do_translate ( { :quote , _ , [ [ do: expr ] ] } , env ) do
170190 Quote . make_quote ( [ ] , expr )
171191 end
172192
173- defp do_translate ( { :quote , _ , [ opts , [ do: expr ] ] } ) do
193+ defp do_translate ( { :quote , _ , [ opts , [ do: expr ] ] } , env ) do
174194 Quote . make_quote ( opts , expr )
175195 end
176196
177- defp do_translate ( { :import , _ , [ { :__aliases__ , _ , module_name_list } ] } ) do
197+ defp do_translate ( { :import , _ , [ { :__aliases__ , _ , module_name_list } ] } , env ) do
178198 Import . make_import ( module_name_list , [ ] )
179199 end
180200
181- defp do_translate ( { :import , _ , [ { :__aliases__ , _ , module_name_list } , options ] } ) do
201+ defp do_translate ( { :import , _ , [ { :__aliases__ , _ , module_name_list } , options ] } , env ) do
182202 Import . make_import ( module_name_list , options )
183203 end
184204
185- defp do_translate ( { :alias , _ , [ alias_info , options ] } ) do
205+ defp do_translate ( { :alias , _ , [ alias_info , options ] } , env ) do
186206 Import . make_alias_import ( alias_info , options )
187207 end
188208
189- defp do_translate ( { :alias , _ , [ alias_info ] } ) do
209+ defp do_translate ( { :alias , _ , [ alias_info ] } , env ) do
190210 Import . make_alias_import ( alias_info , [ ] )
191211 end
192212
193- defp do_translate ( { :require , _ , [ alias_info , options ] } ) do
213+ defp do_translate ( { :require , _ , [ alias_info , options ] } , env ) do
194214 Import . make_alias_import ( alias_info , options )
195215 end
196216
197- defp do_translate ( { :require , _ , [ alias_info ] } ) do
217+ defp do_translate ( { :require , _ , [ alias_info ] } , env ) do
198218 Import . make_alias_import ( alias_info , [ ] )
199219 end
200220
201- defp do_translate ( { :case , _ , [ condition , [ do: clauses ] ] } ) do
202- Case . make_case ( condition , clauses )
221+ defp do_translate ( { :case , _ , [ condition , [ do: clauses ] ] } , env ) do
222+ Case . make_case ( condition , clauses , env )
203223 end
204224
205- defp do_translate ( { :cond , _ , [ [ do: clauses ] ] } ) do
225+ defp do_translate ( { :cond , _ , [ [ do: clauses ] ] } , env ) do
206226 Cond . make_cond ( clauses )
207227 end
208228
209- defp do_translate ( { :for , _ , generators } ) do
210- For . make_for ( generators )
229+ defp do_translate ( { :for , _ , generators } , env ) do
230+ For . make_for ( generators , env )
211231 end
212232
213- defp do_translate ( { :fn , _ , clauses } ) do
214- Function . make_anonymous_function ( clauses )
233+ defp do_translate ( { :fn , _ , clauses } , env ) do
234+ Function . make_anonymous_function ( clauses , env )
215235 end
216236
217- defp do_translate ( { :.. , _ , [ first , last ] } ) do
237+ defp do_translate ( { :.. , _ , [ first , last ] } , env ) do
218238 ExKernel . make_range ( first , last )
219239 end
220240
221- defp do_translate ( { :{} , _ , elements } ) do
222- Primitive . make_tuple ( elements )
241+ defp do_translate ( { :{} , _ , elements } , env ) do
242+ Primitive . make_tuple ( elements , env )
223243 end
224244
225- defp do_translate ( { operator , _ , [ value ] } ) when operator in [ :- , :! ] do
226- Expression . make_unary_expression ( operator , value )
245+ defp do_translate ( { operator , _ , [ value ] } , env ) when operator in [ :- , :! ] do
246+ Expression . make_unary_expression ( operator , value , env )
227247 end
228248
229- defp do_translate ( { := , _ , [ left , right ] } ) do
230- Assignment . make_assignment ( left , right )
249+ defp do_translate ( { := , _ , [ left , right ] } , env ) do
250+ Assignment . make_assignment ( left , right , env )
231251 end
232252
233- defp do_translate ( { :<> , _ , [ left , right ] } ) do
234- Expression . make_binary_expression ( :+ , left , right )
253+ defp do_translate ( { :<> , _ , [ left , right ] } , env ) do
254+ Expression . make_binary_expression ( :+ , left , right , env )
235255 end
236256
237- defp do_translate ( { :++ , _ , [ left , right ] } ) do
257+ defp do_translate ( { :++ , _ , [ left , right ] } , env ) do
238258 ExKernel . concat_lists ( left , right )
239259 end
240260
241- defp do_translate ( { operator , _ , [ left , right ] } ) when operator in [ :+ , :- , :/ , :* , :== , :!= , :&& , :|| , :> , :< , :>= , :<= , :=== ] do
242- Expression . make_binary_expression ( operator , left , right )
261+ defp do_translate ( { operator , _ , [ left , right ] } , env ) when operator in [ :+ , :- , :/ , :* , :== , :!= , :&& , :|| , :> , :< , :>= , :<= , :=== ] do
262+ Expression . make_binary_expression ( operator , left , right , env )
243263 end
244264
245- defp do_translate ( { :and , _ , [ left , right ] } ) do
246- Expression . make_binary_expression ( :&& , left , right )
265+ defp do_translate ( { :and , _ , [ left , right ] } , env ) do
266+ Expression . make_binary_expression ( :&& , left , right , env )
247267 end
248268
249- defp do_translate ( { :or , _ , [ left , right ] } ) do
250- Expression . make_binary_expression ( :|| , left , right )
269+ defp do_translate ( { :or , _ , [ left , right ] } , env ) do
270+ Expression . make_binary_expression ( :|| , left , right , env )
251271 end
252272
253- defp do_translate ( { function , _ , [ { :when , _ , [ { name , _ , _params } | _guards ] } , [ do: _body ] ] } = ast ) when function in [ :def , :defp ] do
254- Function . process_function ( Utils . filter_name ( name ) , [ ast ] )
273+ defp do_translate ( { function , _ , [ { :when , _ , [ { name , _ , _params } | _guards ] } , [ do: _body ] ] } = ast , env ) when function in [ :def , :defp ] do
274+ Function . process_function ( Utils . filter_name ( name ) , [ ast ] , env )
255275 end
256276
257- defp do_translate ( { function , _ , [ { name , _ , _params } , [ do: _body ] ] } = ast ) when function in [ :def , :defp ] do
258- Function . process_function ( Utils . filter_name ( name ) , [ ast ] )
277+ defp do_translate ( { function , _ , [ { name , _ , _params } , [ do: _body ] ] } = ast , env ) when function in [ :def , :defp ] do
278+ Function . process_function ( Utils . filter_name ( name ) , [ ast ] , env )
259279 end
260280
261- defp do_translate ( { :defstruct , _ , attributes } ) do
281+ defp do_translate ( { :defstruct , _ , attributes } , env ) do
262282 Struct . make_defstruct ( attributes )
263283 end
264284
265- defp do_translate ( { :defexception , _ , attributes } ) do
285+ defp do_translate ( { :defexception , _ , attributes } , env ) do
266286 Struct . make_defexception ( attributes )
267287 end
268288
269- defp do_translate ( { :raise , _ , [ alias_info , attributes ] } ) do
289+ defp do_translate ( { :raise , _ , [ alias_info , attributes ] } , env ) do
270290 { _ , _ , name } = alias_info
271291
272292 Raise . throw_error ( name , attributes )
273293 end
274294
275- defp do_translate ( { :raise , _ , [ message ] } ) do
295+ defp do_translate ( { :raise , _ , [ message ] } , env ) do
276296 Raise . throw_error ( message )
277297 end
278298
279- defp do_translate ( { :if , _ , [ test , blocks ] } ) do
280- If . make_if ( test , blocks )
299+ defp do_translate ( { :if , _ , _ } = ast , env ) do
300+ Macro . expand ( ast , env )
301+ |> translate
281302 end
282303
283- defp do_translate ( { :defmodule , _ , [ { :__aliases__ , _ , module_name_list } , [ do: body ] ] } ) do
284- Module . make_module ( module_name_list , body )
304+ defp do_translate ( { :defmodule , _ , [ { :__aliases__ , _ , module_name_list } , [ do: body ] ] } , env ) do
305+ Module . make_module ( module_name_list , body , env )
285306 end
286307
287- defp do_translate ( { :|> , _ , [ left , right ] } ) do
308+ defp do_translate ( { :|> , _ , [ left , right ] } , env ) do
288309 case right do
289310 { { :. , meta , [ module , fun ] } , meta2 , params } ->
290311 translate ( { { :. , meta , [ module , fun ] } , meta2 , [ left ] ++ params } )
@@ -293,18 +314,23 @@ defmodule ElixirScript.Translator do
293314 end
294315 end
295316
296- defp do_translate ( { name , metadata , params } ) when is_list ( params ) do
297- name = Utils . filter_name ( name )
317+ defp do_translate ( { name , metadata , params } = ast , env ) when is_list ( params ) do
318+ expanded_ast = Macro . expand ( ast , env )
319+ if expanded_ast == ast do
320+ name = Utils . filter_name ( name )
298321
299- case metadata [ :import ] do
300- Kernel ->
301- Function . make_function_call ( :Kernel , name , params )
302- _ ->
303- Function . make_function_call ( name , params )
322+ case metadata [ :import ] do
323+ Kernel ->
324+ Function . make_function_call ( :Kernel , name , params , env )
325+ _ ->
326+ Function . make_function_call ( name , params , env )
327+ end
328+ else
329+ translate ( expanded_ast )
304330 end
305331 end
306332
307- defp do_translate ( { name , _ , _ } ) do
333+ defp do_translate ( { name , _ , _ } , env ) do
308334 name = Utils . filter_name ( name )
309335 Primitive . make_identifier ( name )
310336 end
0 commit comments