Parse_transform рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдЕрд╕реНрд╡реАрдХрд░рдг: рд╡рд░реНрдгрд┐рдд рдЯреВрд▓ рдореЗрдВ рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж рдкреНрд░рддрд┐рд╖реНрдард╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЖрдЧреНрд░рд╣ рдирд╣реАрдВ рдХрд░рддрд╛, рдЬрд╣рд╛рдВ рднреА рдореБрдЭреЗ рдорд┐рд▓рддрд╛ рд╣реИ, рдореИрдВ рдХреЗрд╡рд▓ рддрдХрдиреАрдХ рдХреЗ рдХреБрдЫ рд░реЛрдорд╛рдВрдЪ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рд╕реЗ рдЦреБрдж рдХреЛ рдкрд░рд┐рдЪрд┐рдд рдХрд░рддрд╛ рд╣реВрдВред

рд▓рд┐рдЦрд┐рдд рд╕реНрд░реЛрдд рдФрд░ рд╕рд╛рде рд╣реА рд▓реЗрдЦ рдХреА рдПрдХ рдкрд╛рда рдкреНрд░рддрд┐ рдЬреАрдердм рдкрд░ рдорд┐рд▓ рд╕рдХрддреА рд╣реИред

Parse_transform рдХреНрдпрд╛ рд╣реИ


parse_transform - рд╕рдВрдХрд▓рди рд╕реЗ рдкрд╣рд▓реЗ рдПрдПрд╕рдЯреА рдкрд░рд┐рд╡рд░реНрддрди рддрдВрддреНрд░ред рдирд┐рд░реНрдорд╛рдг рдХреЗ рдЕрд░реНрде рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ (рд╢рдмреНрджрд╛рд░реНрде), рдмрд┐рдирд╛ рдПрд░рд▓реИрдВрдЧ рдХреЗ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рд╕реЗ рдкрд░реЗред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╡реЗрдм рдкрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХрдо рдЬрд╛рдирдХрд╛рд░реА рд╣реИ, рдЬреЛ рдЧреИрд░-рдЧреБрд░реБ рдпреБрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рд╕реАрдорд╛ рдХреЛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдмрдирд╛рддрд╛ рд╣реИред

рд╣рдо рдХреНрдпрд╛ рдХрд░реЗрдВрдЧреЗ


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдПрдПрд╕рдЯреА рдПрд░реНрд▓рд╛рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рдмрд╛рдд рдХрд░рддрд╛ рд╣реВрдВ, рд╕рд░рд▓ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реВрдВ, рдФрд░ рдПрдХ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ gen_server рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП parse_transform рд▓рд┐рдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рднреА рджрд┐рдЦрд╛рддрд╛ рд╣реВрдВ (рдХрд╛рд░реНрдп рдмрд╣реБрдд рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧрд╛), рдФрд░ рдЕрдВрдд рдореЗрдВ рдореИрдВ рдПрдХ рд▓рд┐рдВрдХ рджреВрдВрдЧрд╛ред рд╢реБрд░реБрдЖрдд рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рдПрдХ рд╕реЗрдЯ рдкрд░ред


рдПрд░реНрд▓рд╛рдВрдЧ рдореЗрдВ рдПрдПрд╕рдЯреА


рдмрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ: рдПрдПрд╕рдЯреА рдкрд░рд┐рднрд╛рд╖рд╛

рдПрдПрд╕рдЯреА рдХреЛ рдПрдХ рдмрд╛рд░ рджреЗрдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЗрд╕рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЛ рд╕реМ рдмрд╛рд░ рдкрдврд╝рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦреЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреИрд╕реЗ рд░реВрдкрд╛рдВрддрд░рд┐рдд рд╣реЛрддреА рд╣реИред

рддреЛ, astdemo.erl рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб:
-module(astdemo). -export([hello/0, hello/2]). hello() -> hello("world", 1). hello(_What, 0) -> ok; hello(What, Count) -> io:format("Hello, ~s~n", [What]), hello(What, Count - 1). 


рдПрдПрд╕рдЯреА рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдкрд░ epp рдореЙрдбреНрдпреВрд▓ рд╕реЗ parse_file рдлрд╝рдВрдХреНрд╢рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
  Eshell V5.8.5 (^ G рдХреЗ рд╕рд╛рде рдЧрд░реНрднрдкрд╛рдд)
 1> {рдареАрдХ рд╣реИ, рдкреНрд░рдкрддреНрд░} = epp: parse_file ("astdemo.erl", [], []], io: рдкреНрд░рд╛рд░реВрдк ("~ p ~ n", [рдкреНрд░рдкрддреНрд░])ред
 [{рд╡рд┐рд╢реЗрд╖рддрд╛, 1, рдлрд╝рд╛рдЗрд▓, {"astdemo.erl", 1}},
  {рд╡рд┐рд╢реЗрд╖рддрд╛, 1, рдореЙрдбреНрдпреВрд▓, рдПрд╕реНрдЯреЗрдореЛ},
  {рд╡рд┐рд╢реЗрд╖рддрд╛, 2, рдирд┐рд░реНрдпрд╛рдд, [{рд╣реИрд▓реЛ, 0}, {рд╣реИрд▓реЛ, 2}]},
  {рдлрд╝рдВрдХреНрд╢рди, 4, рд╣реИрд▓реЛ, 0,
            [{рдЦрдВрдб, рек, [], [],
                     [{рдХреЙрд▓, рел,
                            {рдкрд░рдорд╛рдгреБ, рел, рдирдорд╕реНрддреЗ},
                            [{рд╕реНрдЯреНрд░рд┐рдВрдЧ, 5, "рджреБрдирд┐рдпрд╛"}, {рдкреВрд░реНрдгрд╛рдВрдХ, 5.1}]}]}]}}
  {рдлрд╝рдВрдХреНрд╢рди, 7, рд╣реИрд▓реЛ, 2,
            [{рдЦрдВрдб, 7, [{var, 7, '_ What'}, {рдкреВрд░реНрдгрд╛рдВрдХ, 7.0}], [], [{atom, 8, ok}]},
             {рдЦрдВрдб, реп,
                     [{var, 9, 'What'}, {var, 9, 'Count'}],
                     []
                     [{рдХреЙрд▓, резреж,
                            {рджреВрд░рд╕реНрде, резреж, {рдкрд░рдорд╛рдгреБ, резреж, io}, {рдкрд░рдорд╛рдгреБ, резреж, рдкреНрд░рд╛рд░реВрдк}},
                            [{рд╕реНрдЯреНрд░рд┐рдВрдЧ, резреж, "рд╣реЗрд▓реЛ, ~ рдПрд╕ ~ рдПрди"},
                             {рд╡рд┐рдкрдХреНрд╖, резреж, {рд╡рд░, резреж, 'рдХреНрдпрд╛'}, {рд╢реВрдиреНрдп, резреж}}]},
                      {рдХреЙрд▓, резрез,
                            {рдкрд░рдорд╛рдгреБ, резрез, рдирдорд╕реНрддреЗ},
                            [{var, 11, 'рдХреНрдпрд╛'},
                             {op, 11, '-', {var, 11, 'Count'}, {рдкреВрд░реНрдгрд╛рдВрдХ, 11,1}}}}]]]}},
  {рдИрдУрдПрдл, 12}]
 рдареАрдХ


рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдХрдо рд╕реЗ рдХрдо 3 рдХреА рд▓рдВрдмрд╛рдИ рд╡рд╛рд▓реА рдЯреНрдпреВрдм рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдкрд╣рд▓реЗ рджреЛ рддрддреНрд╡ рд╣рдореЗрд╢рд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдФрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рдмрд╛рдж рдЗрд╕рдХрд╛ рд╡рд┐рд╡рд░рдг рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╕реНрдерд╛рди рдкрд░ рдХреНрдпрд╛ рд╣реИ, рддреЛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдЖрдкрдХреА рд╕реЗрд╡рд╛ рдореЗрдВ рд╣реИред

Parse_transform / 2 рдлрд╝рдВрдХреНрд╢рди


рдЪрд▓рд┐рдП рдЕрдм рдПрдХ рдбрдореА-рдкрд╛рд░рд╕реЗ_рдЯреНрд░реЗрдирдлреЙрд░реНрдо рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдореЗрдВ рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдПрдВ рдЬреЛ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдирд┐рдкрдЯреЗрдЧрд╛, рдФрд░ рдПрдПрд╕рдЯреА рдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдмрд╕ рдЗрд╕реЗ рдкреНрд░рд┐рдВрдЯ рдХрд░реЗрдВред

рддреЛ Demo_pt.erl :
 -module(demo_pt). -export([parse_transform/2]). parse_transform(Forms, _Options) -> io:format("~p~n", [Forms]), Forms. 


Astdemo.erl рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдирд┐рд░реНрджреЗрд╢ рдбрд╛рд▓реЗрдВ:
 -module(astdemo). -compile({parse_transform, demo_pt}). -export([hello/0, hello/2]). ........... 


рд╣рдо рд╕рдВрдХрд▓рди рдХрд░рддреЗ рд╣реИрдВ:
  Eshell V5.8.5 (^ G рдХреЗ рд╕рд╛рде рдЧрд░реНрднрдкрд╛рдд)
 1> c (astdemo)ред
 [{рд╡рд┐рд╢реЗрд╖рддрд╛, 1, рдлрд╝рд╛рдЗрд▓, {"./ astdemo.erl", 1}},
  {рд╡рд┐рд╢реЗрд╖рддрд╛, 1, рдореЙрдбреНрдпреВрд▓, рдПрд╕реНрдЯреЗрдореЛ},
  {рд╡рд┐рд╢реЗрд╖рддрд╛, 3, рдирд┐рд░реНрдпрд╛рдд, [{рд╣реИрд▓реЛ, 0}, {рд╣реИрд▓реЛ, 2}]},
  {рдлрд╝рдВрдХреНрд╢рди, 5, рд╣реИрд▓реЛ, 0,
            [{рдЦрдВрдб, рел, [], [],
                     [{рдХреЙрд▓, рем,
                            {рдкрд░рдорд╛рдгреБ, рем, рдирдорд╕реНрддреЗ},
                            [{рд╕реНрдЯреНрд░рд┐рдВрдЧ, 6, "рджреБрдирд┐рдпрд╛"}, {рдкреВрд░реНрдгрд╛рдВрдХ, 6.1}]}}]]}}
  {рдлрд╝рдВрдХреНрд╢рди, 8, рд╣реИрд▓реЛ, 2,
            [{рдЦрдВрдб, 8, [{рд╡рд░, cl, '_ рдХреНрдпрд╛ тАЩ}, {рдкреВрд░реНрдгрд╛рдВрдХ, },реж}], [], [{рдкрд░рдорд╛рдгреБ, реп, рдареАрдХ}]},
             {рдЦрдВрдб, резреж,
                     [{var, 10, 'What'}, {var, 10, 'Count'}],
                     []
                     [{рдХреЙрд▓, резрез,
                            {рджреВрд░рд╕реНрде, 11, {рдкрд░рдорд╛рдгреБ, 11, io}, {рдкрд░рдорд╛рдгреБ, 11, рдкреНрд░рд╛рд░реВрдк}},
                            [{рд╕реНрдЯреНрд░рд┐рдВрдЧ, резрез, "рд╣реЗрд▓реЛ, ~ рдПрд╕ ~ рдПрди"},
                             {cons, резрез, {var, резрез, 'рдХреНрдпрд╛'}, {nil, резрез}}}],
                      {рдХреЙрд▓, резреи,
                            {рдкрд░рдорд╛рдгреБ, резреи, рдирдорд╕реНрддреЗ},
                            [{var, 12, 'рдХреНрдпрд╛'},
                             {op, 12, '-', {var, 12, 'Count'}, {рдкреВрд░реНрдгрд╛рдВрдХ, 12,1}}}}]]]}},
  {рдИрдУрдПрдл, 13}]
 {рдареАрдХ рд╣реИ, рдПрд╕реНрдЯрдбреЗрдореЛ} 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдПрд╕рдЯреА рдПрдХ рд╣реА рд╣реИ (рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рддрдХ), рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд╛рд░ рдпрд╣ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдореБрджреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕рдВрдХрд▓рдХ рдирд┐рд░реНрджреЗрд╢рди рдПрдПрд╕рдЯреА рдореЗрдВ рдкрд╣рд▓реЗ рд╣реА рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдЖрдпрд╛ рдерд╛ред

рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рдХреНрдпрд╛ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рдЬреНрдЮрд╛рд╕реБ рдкрд╛рдардХ рд╢рд╛рдпрдж рдЕрдкрдиреЗ рджрдо рдкрд░ рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛ред рдпрд╣ рд▓реЗрдЦ рдПрдПрд╕рдЯреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред

рдкрд╣рд▓реЗ рдкрд░рд┐рд╡рд░реНрддрди


рдЖрдЗрдП рдПрдХ рдРрд╕рд╛ рдХрд╛рд░реНрдп рдХрд░реЗрдВ рдЬреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЕрднреНрдпрд╛рд╕ рдореЗрдВ рдмреЗрдХрд╛рд░ рд╣реИ - рдлрд╝рдВрдХреНрд╢рди рдХреЛ "рдирдорд╕реНрддреЗ / 0" "рд╣рд╛рдп / 0" рдирд╛рдо рджреЗрдВред рдпрд╣ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣реЗрд▓реЛ / 0 рдХреЛ рдореЙрдбреНрдпреВрд▓ рдХреЗ рднреАрддрд░ рд╕реЗ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдмрд╛рд╣рд░ рд╕реЗ рдмреБрд▓рд╛рдП рдЬрд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрд╣ рдирд┐рд░реНрдпрд╛рдд рдХреА рд╕реВрдЪреА рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╢реАрд░реНрд╖рдХ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

рдПрдХрд▓ рд░реВрдк рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░


рдЪреВрдВрдХрд┐ рдПрдПрд╕рдЯреА (рдлреЙрд░реНрдо рдмрд╛рдЗрдВрдбрд┐рдВрдЧ) рдПрдХ рд╕реВрдЪреА рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдПрдХ рдмрд╣реБрдд рдЫреЛрдЯреА рд╕реВрдЪреА рдХрд╛ рдПрдХ рд░реВрдк рд╣реИ, рдпрд╣ рдПрдХ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддреА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рднреА рдкреНрд░рдкрддреНрд░реЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИред рдЪреВрдВрдХрд┐ рдХрд╛рд░реНрдп рд╕рд░рд▓ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдмрд╛рдХреА рд╕рд╛рдордЧреНрд░реА рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╕реВрдЪреА: рдорд╛рдирдЪрд┐рддреНрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИред
рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдирд┐рд░реНрдпрд╛рдд рдХреЛ рдмрджрд▓ рджреЗрдЧрд╛ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рд╣реЗрдбрд░ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:
 % hello_to_hi replaces occurences of hello/0 with hi/0 hello_to_hi({attribute, Line, export, Exports}) -> % export attribute. Replace {hello, 0} with {hi, 0} HiExports = lists:map( fun ({hello, 0}) -> {hi, 0}; (E) -> E end, Exports), {attribute, Line, export, HiExports}; hello_to_hi({function, Line, hello, 0, Clauses}) -> % Header of hello/0. Just replace hello with hi {function, Line, hi, 0, Clauses}; hello_to_hi(Form) -> % Default: do not modify form Form. 


рдЕрдм рд╕рдм рдПрдХ рд╕рд╛рде


рд╣рдо рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ parse_transform рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХреЛрдб рдмрджрд▓рдХрд░ рд╕рдХреНрд╖рдо рдХрд░рддреЗ рд╣реИрдВ:
 parse_transform(Forms, _Options) -> HiForms = lists:map(fun hello_to_hi/1, Forms), io:format("~p~n", [HiForms]), HiForms. 


рд╣рдо Demo_pt рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ , рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдЧрдбрд╝рдмрдбрд╝ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

рдЪреЗрдХ


рд╣рдо рдирдП рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рд╕рд╛рде astdemo рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ:

  Eshell V5.8.5 (^ G рдХреЗ рд╕рд╛рде рдЧрд░реНрднрдкрд╛рдд)
 1> c (astdemo)ред
 [{рд╡рд┐рд╢реЗрд╖рддрд╛, 1, рдлрд╝рд╛рдЗрд▓, {"./ astdemo.erl", 1}},
  {рд╡рд┐рд╢реЗрд╖рддрд╛, 1, рдореЙрдбреНрдпреВрд▓, рдПрд╕реНрдЯреЗрдореЛ},
  {рд╡рд┐рд╢реЗрд╖рддрд╛, 3, рдирд┐рд░реНрдпрд╛рдд, [{hi, 0}, {рд╣реИрд▓реЛ, 2}]},
  {рдлрд╝рдВрдХреНрд╢рди, 5, рд╣рд╛рдп, 0,
            [{рдЦрдВрдб, рел, [], [],
                     [{рдХреЙрд▓, рем,
                            {рдкрд░рдорд╛рдгреБ, рем, рдирдорд╕реНрддреЗ},
                            [{рд╕реНрдЯреНрд░рд┐рдВрдЧ, 6, "рджреБрдирд┐рдпрд╛"}, {рдкреВрд░реНрдгрд╛рдВрдХ, 6.1}]}}]]}}
  {рдлрд╝рдВрдХреНрд╢рди, 8, рд╣реИрд▓реЛ, 2,
            [{рдЦрдВрдб, 8, [{рд╡рд░, cl, '_ рдХреНрдпрд╛ тАЩ}, {рдкреВрд░реНрдгрд╛рдВрдХ, },реж}], [], [{рдкрд░рдорд╛рдгреБ, реп, рдареАрдХ}]},
             {рдЦрдВрдб, резреж,
                     [{var, 10, 'What'}, {var, 10, 'Count'}],
                     []
                     [{рдХреЙрд▓, резрез,
                            {рджреВрд░рд╕реНрде, 11, {рдкрд░рдорд╛рдгреБ, 11, io}, {рдкрд░рдорд╛рдгреБ, 11, рдкреНрд░рд╛рд░реВрдк}},
                            [{рд╕реНрдЯреНрд░рд┐рдВрдЧ, резрез, "рд╣реЗрд▓реЛ, ~ рдПрд╕ ~ рдПрди"},
                             {cons, резрез, {var, резрез, 'рдХреНрдпрд╛'}, {nil, резрез}}}],
                      {рдХреЙрд▓, резреи,
                            {рдкрд░рдорд╛рдгреБ, резреи, рдирдорд╕реНрддреЗ},
                            [{var, 12, 'рдХреНрдпрд╛'},
                             {op, 12, '-', {var, 12, 'Count'}, {рдкреВрд░реНрдгрд╛рдВрдХ, 12,1}}}}]]]}},
  {рдИрдУрдПрдл, 13}]
 {рдареАрдХ рд╣реИ, рдПрд╕реНрдЯрдбреЗрдореЛ}
 2> рдЕрд╕реНрдЯреЗрдбреЗрдореЛ: рд╣рд╛рдп ()ред
 рдирдорд╕реНрддреЗ рджреБрдирд┐рдпрд╛
 рдареАрдХ 


рд╡рд╛рд╣! рдЬреИрд╕рд╛ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЪрд╛рд╣рд╛, рд╡реИрд╕рд╛ рдХрд╛рдо рдХрд┐рдпрд╛ред рдХреБрдЫ рдФрд░ рдЙрдкрдпреЛрдЧреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордпред

рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдЬреАрди_рд╕рд░реНрд╡рд░ parse_transform


рдХрднреА-рдХрднреА gen_server рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦрддреЗ рд╕рдордп, рдЗрд╕рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд░рд╛рдЬреНрдп рдХреЛ рдЦреАрдВрдЪрдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рд░рд╛рдЬреНрдп рд╕реЗ handle_anything рдХреЛ рдЕрдВрддрд┐рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдЦреАрдВрдЪрдиреЗ рд╕реЗ рдХреЛрдб рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдЗрдП рдПрдХ parse_transform рдХрд░реЗрдВ рдЬреЛ рд╣рдореЗрдВ handle_call / 2, handle_cast / 1, handle_info / 1 рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╛ рдирд╣реАрдВред рд▓реЗрдЦ рдХреЛ рдереЛрдбрд╝рд╛ рдЫреЛрдЯрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХреЗрд╡рд▓ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рд╣реИрдВрдбрд▓_call / 2 -> рд╣реИрдВрдбрд▓_call / 3 , рдФрд░ рдЬреЛ рд▓реЛрдЧ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рд╡реЗ рд╕рдм рдХреБрдЫ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВрдЧреЗред

рд╕рдВрдХрд▓реНрдкрдирд╛


Gen_server рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ handle_call (рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП) рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЗрд╕ рддрд░рд╣ ( рдкреНрд░рд▓реЗрдЦрди ):
 handle_call(Request, From, State) -> ..... {reply,Reply,NewState}. 

рдЪреВрдВрдХрд┐ рд╣рдореЗрдВ рд░рд╛рдЬреНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░рд╛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:
 handle_call(Request, From) -> ..... Reply. 


рдкрд░рд┐рд╡рд░реНрддрди рдпреЛрдЬрдирд╛




рдмрд┐рд▓реНрд▓реА


рд╣рдо рдЗрд╕ рдкрд░ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рджреЗрдВрдЧреЗред рдПрдХ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░ рдХреА рддреБрд▓рдирд╛ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдФрд░ рдЗрд╕рдХреЗ рдПрдирд╛рд▓реЙрдЧ рдореЗрдВ рд╡рд┐рд╣рд┐рдд рд░реВрдк рдореЗрдВ рд╣реИрдВрдбрд▓_call ред
 -module(sl_gs_demo). -behavior(gen_server). -compile({parse_transform, sl_gs}). -export([handle_call/2, ref_handle_call/3]). -export([handle_cast/2, handle_info/2]). -export([init/1, terminate/2, code_change/3]). % This will be transformed handle_call(Req, From) -> {Req, From}. % That's what handle_call should finally look like ref_handle_call(Req, From, State) -> {reply, {Req, From}, State}. % Dummy functions to make gen_server happy % Exercise: Try to insert them automatically during transformations :) handle_cast(_, State) -> {noreply, State}. handle_info(_, State) -> {noreply, State}. init(_) -> {ok, none}. terminate(_, _) -> ok. code_change(_, State, _) -> {ok, State}. 


рдХреЛрдб


рд╕рдм рдХреБрдЫ рдЬреИрд╕рд╛ рдХрд┐ рдкрд┐рдЫрд▓реА рдмрд╛рд░ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ - рдИрдкреАрдкреА рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рджреЗрдЦ рд░рд╣рд╛ рдерд╛: parse_file рдФрд░ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рд╡рд╣реА рд╣реИ рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

 -module(sl_gs). -export([parse_transform/2]). parse_transform(Forms, _Options) -> lists:map(fun add_missing_state/1, Forms). add_missing_state({attribute, Line, export, Exports}) -> % export attribute. Replace {handle_call, 2} with {handle_call, 3} NewExports = lists:map( fun ({handle_call, 2}) -> {handle_call, 3}; % You can add more clauses here for other function mutations (E) -> E end, Exports), {attribute, Line, export, NewExports}; add_missing_state({function, Line, handle_call, 2, Clauses}) -> % Mutate clauses NewClauses = lists:map(fun change_call_clause/1, Clauses), % Finally, change arity in header {function, Line, handle_call, 3, NewClauses}; add_missing_state(Form) -> % Default Form. change_call_clause({clause, Line, Arguments, Guards, Body}) -> % Change arity in clauses. NewArgs = Arguments ++ [{var, Line, 'State'}], % Add State argument % Then replace last statement of each clause with corresponding tuple NewBody = change_call_body(Body), {clause, Line, NewArgs, Guards, NewBody}. change_call_body([Statement | Rest=[_|_] ]) -> % Rest has to be non-empty list for this % Recurse to change only last statement [Statement|change_call_body(Rest)]; change_call_body([LastStatement]) -> % Put it into tuple. Lines are zero to omit parsing LastStatement [{tuple,0, [{atom,0,reply}, LastStatement, {var,0,'State'}] }]. 


рд╕реНрд╡рд╛рд╕реНрдереНрдп рдЬрд╛рдБрдЪ


  Eshell V5.8.5 (^ G рдХреЗ рд╕рд╛рде рдЧрд░реНрднрдкрд╛рдд)
 1> c (sl_gs_demo)ред
 {рдареАрдХ рд╣реИ, sl_gs_demo}
 2> {ok, D} = gen_server: start_link (sl_gs_demo, [], [])ред
 {рдареАрдХ рд╣реИ, <0.39.0>}
 3> gen_server: call (D, hello)ред
 {рд╣реИрд▓реЛ, {<0.32.0>, # рд░реЗрдл <0.0.0.83>}}

рд╕рдлрд▓рддрд╛! рдпрд╣ рдЙрд▓реНрд▓реВ рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдФрд░ рдЧреАрдереВрдм рдкрд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред

рдкрд░рд┐рдгрд╛рдо


рдПрдХ рдЗрдЪреНрдЫреБрдХ рдкрд╛рдардХ, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ, рдПрд░реНрд▓рд╛рдВрдЧ рдореЗрдВ рдПрдПрд╕рдЯреА рд╕реЗ рдореБрд▓рд╛рдХрд╛рдд рдХреА, рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдПрдХ рдЕрдиреБрдорд╛рдирд┐рдд рд╡рд┐рдЪрд╛рд░ рднреА рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ред рд╢рд╛рдпрдж рдХрд┐рд╕реА рдиреЗ рдкрд╣рд▓реЗ parse_transform рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрд╛ред
рд▓реЗрдЦ рдореЗрдВ рдРрд╕реА рдЬрд╛рдирдХрд╛рд░реА рд╣реИ рдЬреЛ рдЖрдкрдХреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдереЛрдбрд╝рд╛ рдХрдо рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд▓рд┐рдВрдХ рд╣реЛрдЧрд╛ред

рд╡рд┐рдзрд┐ рдХреА рдЖрд▓реЛрдЪрдирд╛


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, parse_transform рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ (рдпрджрд┐ рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд╣реИ) рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рд░рд┐рдмрд╛рд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЧреИрд░-рдШрд╛рддрдХ рд╣реИред
рджреВрд╕рд░реЗ, рдРрд╕реЗ рдХреЛрдб рдХреЛ рдкрдврд╝рдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧ (рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдВрдкрд╛рджрди) рддреБрд░рдВрдд рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдирд╣реАрдВ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рди рдХреЗрд╡рд▓ рдЕрдЪреНрдЫреЗ рдкреНрд░рд▓реЗрдЦрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рд╕реНрд░реЛрдд рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЗрд╕реЗ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд▓рд┐рдВрдХ рднреА рдЪрд╛рд╣рд┐рдПред
рддреАрд╕рд░рд╛, рдЖрдкрдХреА рдЕрдкрдиреА рдмреЛрд▓рд┐рдпреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдмрд╣реБрдд рд╕реАрдорд┐рдд рд╣реИред рдПрдПрд╕рдЯреА рдЖрдкрдХреЗ рд╕реНрдХреЗрд▓рдкреЗрд▓ рдХреЗ рдиреАрдЪреЗ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдПрдХ рдирд┐рдпрдорд┐рдд рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдкреЗрдЪреАрджрд╛ рдХреАрд╡рд░реНрдб рдФрд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рд╢реБрд░реВрдЖрдд рдкрд╛рд░реНрд╕рд░ рдХреЛ рддреЛрдбрд╝ рд╕рдХрддреА рд╣реИ, рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдп рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░ рд╕рдХрддреА рд╣реИред

Parse_trans рд▓рд╛рдЗрдмреНрд░реЗрд░реА


parse_transform parse_transforms рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧреА рдЪреАрдЬ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдПрдХ рдкреЗрдбрд╝ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдирдХреНрд╢рд╛ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдЪрд░ рдЧрд╣рд░рд╛рдИ рдкрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╕рдордп рдмреЗрд╣рдж рдЙрдкрдпреЛрдЧреА рд╣реИред рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдкреБрдирд░реНрд▓реЗрдЦрди рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рдВрдХреНрд╖рд┐рдкреНрдд рддрд░реАрдХрд╛ рд╣реИ "!" рдСрдкрд░реЗрдЯрд░ рдХреЙрд▓ рдкрд░ gproc: рднреЗрдЬреЗрдВ ред

Source: https://habr.com/ru/post/In140374/


All Articles