神刀安全网

Procedural Macros vs. Macros

11 June 2016

Starting not one , but two projects revolving around procedural macros is a great way to learn a thing or two about them. One thing that bugged me was that they didn’t work easily when the code that should be manipulated involved macros. Luckily, stackoverflow user ker helped me out , and I wanted to share the technique here.

The idea is that we don’t care about macros – we do care about the expanded code coming out of it. Macros we care about can appear in Item position and in Expr position. For both, we want to expand the macros and apply whatever transformation we implement on the resulting Expr s or Item s.

Without further ado, here’s the code:

impl<'a, 'cx> Folder for Overflower<'a, 'cx> {     fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {         if let ItemKind::Mac(_) = item.node {             let expanded = expand_item(item, &mut self.cx.expander());             expanded.into_iter()                     .flat_map(|i| fold::noop_fold_item(i, self).into_iter())                     .collect()         } else {             fold::noop_fold_item(item, self)         }     }          fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {         if self.mode == Mode::DontCare { return expr; }         if let ExprKind::Mac(_) = expr.node {             let expanded = expand_expr(expr.unwrap(), &mut self.cx.expander());             self.fold_expr(expanded)         } else {             ..         }     }     .. } 

Of course, if we’d like to change items, we’d use our own code instead of fold::noop_fold_item(..) . In other news, overflower is now beginning to be somewhat usable – I’ll need to add a bit of documentation, but the code itself seems to work pretty well.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Procedural Macros vs. Macros

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址