@@ -61,9 +61,7 @@ defmodule Gradient.ElixirExpr do
6161 inspect ( l )
6262
6363 :error ->
64- items =
65- pp_cons ( cons )
66- |> Enum . join ( ", " )
64+ items = pp_cons ( cons )
6765
6866 "[" <> items <> "]"
6967 end
@@ -73,9 +71,9 @@ defmodule Gradient.ElixirExpr do
7371 "&#{ name } /#{ arity } "
7472 end
7573
76- def pp_expr ( { :fun , _ , { :function , module , name , arity } } ) do
74+ def pp_expr ( { :fun , _ , { :function , { :atom , _ , module } , { :atom , _ , name } , arity } } ) do
7775 module = ElixirFmt . parse_module ( module )
78- name = pp_expr ( name )
76+ name = Atom . to_string ( name )
7977 arity = pp_expr ( arity )
8078 "&#{ module } #{ name } /#{ arity } "
8179 end
@@ -90,14 +88,28 @@ defmodule Gradient.ElixirExpr do
9088 "throw " <> pp_expr ( arg )
9189 end
9290
91+ def pp_expr (
92+ { :call , _ , { :remote , _ , { :atom , _ , :erlang } , { :atom , _ , :error } } ,
93+ [
94+ { :call , _ , { :remote , _ , { :atom , _ , :erlang } , { :atom , _ , :raise } } ,
95+ [
96+ { :atom , _ , :error } ,
97+ { :call , _ , { :remote , _ , { :atom , _ , Kernel.Utils } , { :atom , _ , :raise } } , [ var ] } ,
98+ var_stacktrace
99+ ] }
100+ ] }
101+ ) do
102+ "reraise " <> pp_expr ( var ) <> ", " <> pp_expr ( var_stacktrace )
103+ end
104+
93105 def pp_expr ( { :call , _ , { :remote , _ , { :atom , _ , :erlang } , { :atom , _ , :error } } , [ arg ] } ) do
94106 "raise " <> pp_raise_args ( arg )
95107 end
96108
97109 def pp_expr ( { :call , _ , name , args } ) do
98110 args =
99111 Enum . map ( args , & pp_expr / 1 )
100- |> Enum . join ( " , " )
112+ |> Enum . join ( ", " )
101113
102114 pp_name ( name ) <> "(" <> args <> ")"
103115 end
@@ -166,12 +178,16 @@ defmodule Gradient.ElixirExpr do
166178
167179 def pp_expr ( { t , _ , expr0 , quantifiers } ) when t in [ :bc , :lc ] do
168180 expr0 = pp_expr ( expr0 )
169- "for #{ quantifiers } , do: #{ expr0 } "
181+ pquantifiers = pp_expr ( quantifiers )
182+ "for #{ pquantifiers } , do: #{ expr0 } "
170183 end
171184
172185 # Quantifiers
173- def pp_expr ( { type , _ , pattern , expr } ) when type in [ :generate , :b_generate ] do
174- pp_expr ( pattern ) <> " <- " <> pp_expr ( expr )
186+ def pp_expr ( { :b_generate , _ , pattern , expr } ) do
187+ # drop >> to insert quantifier before
188+ ppatern = String . slice ( pp_expr ( pattern ) , 0 .. - 3 )
189+ # add a space before >> for a case whan expr is a bin
190+ ppatern <> " <- " <> pp_expr ( expr ) <> " >>"
175191 end
176192
177193 def pp_expr ( { :case , _ , condition , clauses } = case_expr ) do
@@ -190,13 +206,14 @@ defmodule Gradient.ElixirExpr do
190206 end
191207
192208 def pp_expr ( { :receive , _ , clauses } ) do
193- "receive" <> pp_clauses ( clauses ) <> "end"
209+ "receive do " <> pp_clauses ( clauses ) <> " end"
194210 end
195211
196- def pp_expr ( { :receive , _ , clauses , after_value , _after_body } ) do
212+ def pp_expr ( { :receive , _ , clauses , after_value , after_body } ) do
197213 pclauses = pp_clauses ( clauses )
198214 pvalue = pp_expr ( after_value )
199- "receive " <> pclauses <> "after " <> pvalue <> " -> ... end"
215+ pafter_body = pp_expr ( after_body )
216+ "receive do " <> pclauses <> " after " <> pvalue <> " -> " <> pafter_body <> " end"
200217 end
201218
202219 def pp_expr ( { :try , _ , body , else_block , catchers , after_block } ) do
@@ -254,26 +271,30 @@ defmodule Gradient.ElixirExpr do
254271
255272 defp pp_catch_clause ( { :clause , _ , [ { :tuple , _ , [ type , var , _stacktrace ] } ] , guards , body } ) do
256273 # rescue/catch clause
257- # FIXME support guards, support stacktrace?
258-
259- case get_error_type ( guards ) do
260- { :ok , error_type } ->
261- # rescue
274+ case { elem ( type , 2 ) , get_error_struct ( guards ) } do
275+ { :error , { :ok , error_struct } } ->
276+ # rescue when error is struct
262277 { var2 , body2 } = get_error_var ( var , body )
263278
264279 pp_expr ( type ) <>
265280 ", %" <>
266- pp_expr ( error_type ) <>
281+ pp_expr ( error_struct ) <>
267282 "{} = " <> pp_expr ( var2 ) <> " -> " <> pp_expr ( body2 )
268283
269- :not_found ->
284+ { :error , :not_found } ->
285+ # rescue
286+ { var2 , body2 } = get_error_var ( var , body )
287+
288+ pp_expr ( type ) <>
289+ ", " <> pp_expr ( var2 ) <> " -> " <> pp_expr ( body2 )
290+
291+ { :throw , :not_found } ->
270292 # throw
271293 pp_expr ( type ) <> ", " <> pp_expr ( var ) <> " -> " <> pp_expr ( body )
272294 end
273295 end
274296
275297 defp pp_case_clause ( { :clause , _ , patterns , guards , body } ) do
276- # FIXME support guards
277298 patterns =
278299 patterns
279300 |> Enum . map ( & pp_expr / 1 )
@@ -339,21 +360,28 @@ defmodule Gradient.ElixirExpr do
339360 end
340361
341362 defp maybe_try_after ( res , else_block ) do
342- res <> "; after " <> pp_clauses ( else_block )
363+ res <> "; after " <> pp_expr ( else_block )
343364 end
344365
345- def get_error_type ( [ [ { :op , _ , :andalso , { :op , _ , :== , _ , error_type } , _ } ] ] ) do
346- { :ok , error_type }
366+ def get_error_struct ( [ [ { :op , _ , :andalso , { :op , _ , :== , _ , error_struct } , _ } ] ] ) do
367+ { :ok , error_struct }
347368 end
348369
349- def get_error_type ( _ ) do
370+ def get_error_struct ( _ ) do
350371 :not_found
351372 end
352373
353374 def get_error_var ( { :var , _ , v } , [ { :match , _ , user_var , { :var , _ , v } } | body_tail ] ) do
354375 { user_var , body_tail }
355376 end
356377
378+ def get_error_var ( { :var , _ , v } , [
379+ { :match , _ , user_var , { :call , _ , _ , [ _ , { :var , _ , v } | _ ] } } | body_tail
380+ ] ) do
381+ # Extract variable from Exception.normalize (used in reraise)
382+ { user_var , body_tail }
383+ end
384+
357385 def get_error_var ( var , body ) do
358386 { var , body }
359387 end
@@ -380,7 +408,6 @@ defmodule Gradient.ElixirExpr do
380408 defp bin_set_tsl ( :default ) , do: ""
381409 defp bin_set_tsl ( [ :integer ] ) , do: ""
382410 defp bin_set_tsl ( [ tsl ] ) , do: Atom . to_string ( tsl )
383- defp bin_set_tsl ( tsl ) , do: Atom . to_string ( tsl )
384411
385412 def format_map_elements ( elems ) do
386413 atom_keys = all_keys_atoms? ( elems )
@@ -429,6 +456,10 @@ defmodule Gradient.ElixirExpr do
429456 end
430457 end
431458
459+ defp pp_raise_args ( { :call , _ , { :remote , _ , error_type , { :atom , _ , :exception } } , [ { nil , _ } ] } ) do
460+ pp_expr ( error_type )
461+ end
462+
432463 defp pp_raise_args (
433464 { :call , _ , { :remote , _ , { :atom , _ , RuntimeError } , { :atom , _ , :exception } } , [ arg ] }
434465 ) do
@@ -439,17 +470,13 @@ defmodule Gradient.ElixirExpr do
439470 pp_expr ( error_type ) <> ", " <> pp_expr ( arg )
440471 end
441472
442- defp pp_raise_args ( arg ) do
443- pp_expr ( arg )
444- end
445-
446473 defp try_int_list_ ( { nil , _ } ) , do: [ ]
447474 defp try_int_list_ ( { :cons , _ , { :integer , _ , val } , t } ) , do: [ val | try_int_list_ ( t ) ]
448475 defp try_int_list_ ( _ ) , do: throw ( nil )
449476
450- defp pp_cons ( { nil , _ } ) , do: [ ]
451- defp pp_cons ( { :var , _ , _ } = v ) , do: [ pp_expr ( v ) ]
452- defp pp_cons ( { :cons , _ , h , t } ) , do: [ pp_expr ( h ) | pp_cons ( t ) ]
477+ defp pp_cons ( { :cons , _ , h , { nil , _ } } ) , do: pp_expr ( h )
478+ defp pp_cons ( { :cons , _ , h , { : var, _ , _ } = v } ) , do: pp_expr ( h ) <> " | " <> pp_expr ( v )
479+ defp pp_cons ( { :cons , _ , h , t } ) , do: pp_expr ( h ) <> ", " <> pp_cons ( t )
453480
454481 defp pp_name ( { :remote , _ , { :atom , _ , m } , { :atom , _ , n } } ) ,
455482 do: ElixirFmt . parse_module ( m ) <> to_string ( n )
0 commit comments