目次

Rustの勉強[マクロ その4]

(更新: )ぎじゅつ

はじめに

#

NO IMAGEマクロ - The Rust Programming Language 日本語版

を読んでいる。

お勉強

#

NO IMAGEマクロ - The Rust Programming Language 日本語版

  • TokenStreamをパースする役割を持つ
  • まあ今日は分割かな
  • どこから読んだか探してたらだいじそうなところあった

手続き的マクロを定義する関数はTokenStreamを入力として受け取り、TokenStreamを出力として生成します。 TokenStream型はRustに内蔵されているproc_macroクレートで定義されており、トークンの列を表します。

  • 概念が2つあることが分かった

これを執筆している時点では、手続き的マクロは、独自のクレートに存在する必要があります。

  • なるほろね
  • crateのcargoに以下を書かなきゃいけない
[lib]
proc-macro = true

[dependencies]
syn = "1.0"
quote = "1.0"
extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn;

#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    // 操作可能な構文木としてのRustコードの表現を構築する
    // Construct a representation of Rust code as a syntax tree
    // that we can manipulate
    let ast = syn::parse(input).unwrap();

    // トレイトの実装内容を構築
    // Build the trait implementation
    impl_hello_macro(&ast)
}

TokenStreamをパースする役割を持つhello_macro_derive関数と、構文木を変換する役割を持つimpl_hello_macro関数にコードを分割したことに注目してください

  • おーなるほどね
    • ガチでパースするわけね
    • 危険な匂いがしてきた

proc_macroクレートはコンパイラのAPIで、私達のコードからRustのコードを読んだり操作したりすることを可能にします。

synクレートは、文字列からRustコードを構文解析し、処理を行えるデータ構造にします。quoteクレートは、synデータ構造を取り、Rustコードに変換し直します。

  • うおーーー
    • マジで駄目な処理そう
    • これが黒魔術

まとめ

#
  • 結局、メタプログラミングの具体を聞いているだけだなーという感覚

次はこの場所から:

まもなくimpl_hello_macro関数を定義し、そこにインクルードしたい新しいRustコードを構築します。