[Rust] Procedural ๋งคํฌ๋กœ

๋Ÿฌ์ŠคํŠธ๋Š” println! ๊ฐ™์€ ๋‹จ์ˆœํ•œ ๋งคํฌ๋กœ ํ•จ์ˆ˜ ์™ธ์—๋„, ์ฝ”๋“œ์— ๊ฐ„์„ญํ•˜๊ณ  ์ง์ ‘ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ž์œ ๋กœ์šด ๋งคํฌ๋กœ ํ˜•์‹์„ ์ง€์›ํ•œ๋‹ค.

๋จผ์ € ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜•์‹์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

proc..๋งคํฌ๋กœ๋Š” ๋ฌด์กฐ๊ฑด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜•์‹์œผ๋กœ๋งŒ ๋นŒ๋“œ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
ํ„ฐ๋ฏธ๋„์—์„œ cargo new ๋ช…๋ น์–ด๋กœ ์ƒ์„ฑํ•  ๊ฒฝ์šฐ, --bin ํ”Œ๋ž˜๊ทธ ๋Œ€์‹  --lib๋ฅผ ์ค€๋‹ค.


๊ทธ๋Ÿผ ๋ญ ์ด๋ ‡๊ฒŒ ๋˜์–ด์žˆ์„ ๊ฒƒ์ด๋‹ค.

๋งคํฌ๋กœ์˜ ์‚ฌ์šฉ์„ ์œ„ํ•ด ์„ค์ •ํŒŒ์ผ์—์„œ proc-macro ๊ฐ’์„ true๋กœ ์„ค์ •ํ•ด์ค€๋‹ค.

proc_crate๋ฅผ extern crateํ•˜๋ฉด ์ด์ œ procedural ๋งคํฌ๋กœ์˜ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.
ํ•œ๋ฒˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๋งคํฌ๋กœ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ๋‹ค.


ํ•จ์ˆ˜ํ˜•(Function like) ๋งคํฌ๋กœ

proc ๋งคํฌ๋กœ๋„ ํ•จ์ˆ˜์˜ ํ˜•์‹์œผ๋กœ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ•จ์ˆ˜ ์œ„์—๋‹ค #[proc_macro] ๋งคํฌ๋กœ๋ฅผ ๋ถ™์—ฌ์ฃผ๊ณ  ์ธ์žํƒ€์ž…๊ณผ ๋ฐ˜ํ™˜ํƒ€์ž…์„ ์ „๋ถ€ TokenStream์ด๋ผ๋Š” ํƒ€์ž…์œผ๋กœ ๋งž์ถฐ์ค€๋‹ค.
์ฝ”๋“œ๋ฅผ ๋ฐ›๊ณ  ์ฝ”๋“œ๋ฅผ ๋ฐฉ์ถœํ•œ๋‹ค๋Š” ์˜๋ฏธ๋‹ค. TokenStream์€ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํƒ€์ž…์ด๋‹ค.
๊ทธ๋Ÿผ

์ด๋Ÿฐ์‹์œผ๋กœ ์งœ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
์ € ๋งคํฌ๋กœ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๊ทธ ์‹คํ–‰๋œ ์œ„์น˜์—์„œ ๋ฐ”๋กœ ์ € ๋ฐ˜ํ™˜ํ•œ ํ…์ŠคํŠธ๊ฐ€ ์ž๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ๋นŒ๋“œํ•˜๊ณ , ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๊ฒ ๋‹ค.

๋นŒ๋“œ๊ฐ€ ์ด๋ ‡๊ฒŒ ์ž˜ ๋๋‹ค๋ฉด, ์ด ํ”„๋กœ์ ํŠธ ํด๋”์˜ ๊ฒฝ๋กœ๋ฅผ ๋ณต์‚ฌํ•ด๋‘๊ณ , ๋”ฐ๋กœ ํ…Œ์ŠคํŠธ์šฉ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ์—ฐ๋‹ค.


์•„๊นŒ ๊ทธ ํด๋”๋ฅผ ์˜์กด์„ฑ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ 


์ด๋ ‡๊ฒŒ ์งœ์„œ ๋Œ๋ฆฌ๋ฉด, ์ž˜ ๋ˆ๋‹ค.

์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค! ์•„๊นŒ ๋งคํฌ๋กœ ์ •์˜์˜ item ์ธ์ž๊ฐ€ ๊ทธ๊ฑธ ๋ฐ›์•„์˜ค๋Š” ๋…€์„์ด๋‹ค.

ํ„ฐ๋ฏธ๋„์— ๋‚ด์šฉ์„ ์ถœ๋ ฅํ•˜๋„๋ก ๋ฐ”๊ฟ”์ฃผ๊ณ 

๋Œ๋ฆฌ๋ฉด

์ž˜ ๋ˆ๋‹ค.

์ด์™ธ์—๋„ ๋ช‡๊ฐ€์ง€ ํ˜•์‹์ด ๋” ์žˆ๋‹ค.



์†์„ฑ(attribute) ๋งคํฌ๋กœ

์ด๊ฑด ํ•จ์ˆ˜ ๋“ฑ์˜ ์ •์˜ ์œ„์— ๋ถ™์—ฌ์„œ ํ•ด๋‹น ์ •์˜๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋งคํฌ๋กœ๋‹ค.
๋˜, ์†์„ฑ์— ์ธ์ž๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
์ด๋Ÿฐ์‹์œผ๋กœ ์ •์˜ํ•˜๊ณ 

์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด,

์ € attribute๋ผ๋Š” ์ธ์ž๋กœ๋Š” "์œผ์•„์•…"์ด๋ผ๋Š” ํ…์ŠคํŠธ๊ฐ€,
item์—๋Š” ์ € ํ•จ์ˆ˜ ์ •์˜ ์ „์ฒด๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค.

์ด๋ ‡๊ฒŒ ๋ง์ด๋‹ค.

์—ฌ๊ธฐ์„  ๊ทธ๋ƒฅ ๋‚ด์šฉ๋ฌผ์„ ๋ณด๊ธฐ๋งŒ ํ–ˆ์ง€๋งŒ, TokenStream ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด ๊ทธ๊ฒŒ ๊ธฐ์กด์˜ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ๋Œ€์ฒดํ•œ๋‹ค.




ํŒŒ์ƒ(derive) ๋งคํฌ๋กœ

์ด๊ฑด ๊ตฌ์กฐ์ฒด ์œ„์— ๋ถ™์—ฌ์„œ ํŠธ๋ ˆ์ž‡ ๋“ฑ์„ ์ž๋™์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ๋” ํ•ด์ค„ ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋œ๋‹ค.

proc_macro_derive๋ผ๋Š” ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„๋˜๋Š”๋ฐ, ํ˜•ํƒœ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

์ด ์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” ํ…์ŠคํŠธ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•  ๋งคํฌ๋กœ์˜ ์ด๋ฆ„์ด ๋œ๋‹ค. ์—ฌ๊ธฐ์„  Boom์ด ์ด ๋งคํฌ๋กœ์˜ ์ด๋ฆ„์ธ ๊ฒƒ์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด ๋งคํฌ๋กœ์—์„œ ๋ฐ˜ํ™˜ํ•  TokenStream ์ฝ”๋“œ๋Š” ์ „์—ญ ๊ณต๊ฐ„์— ๋“ค์–ด๊ฐ„๋‹ค.
๋”ฐ๋ผ์„œ ์ € ์ฝ”๋“œ๋Š” ๊ทธ๋ƒฅ ์ „์—ญ ํ•จ์ˆ˜ boom ํ•˜๋‚˜๋งŒ ๋ฐฉ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค...
์ผ๋‹จ ๊ฐ„๊ฒฐํ•จ์„ ์œ„ํ•ด์„œ ๋Œ€์ถฉ ์จ์„œ ๊ทธ๋Ÿฐ๋ฐ, ์ง„์งœ ํŒŒ์ƒ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด item์œผ๋กœ ๋“ค์–ด์˜จ ๊ตฌ์กฐ์ฒด ์ด๋ฆ„์„ ์–ป์–ด์„œ, impl ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์—ฌํŠผ ์ €๊ฑธ ๋Œ๋ฆฌ๋ฉด

์ด๋ ‡๊ฒŒ ์ž˜ ๋Œ์•„๊ฐ„๋‹ค.


์ฐธ์กฐ
https://doc.rust-lang.org/proc_macro/
https://doc.rust-lang.org/reference/procedural-macros.html