Skip to main content

Kurumi Atelier Day7

·290 words·2 mins
Table of Contents

上一次封装了 vga 的部分操作,但是调用起来有点麻烦。Rust 提供了 macro 机制。定义 macro 需要使用 macro_rules!,貌似这也是个 macro,不过我没查到定义

macro 定义了一系列的规则,如果匹配到相应的 matcher 则会执行对应的处理逻辑

macro_rules! test {
    (x => $e:expr) => (println!("mode X: {}", $e));
    (y => $e:expr) => (println!("mode Y: {}", $e));
}

fn main() {
    test!(y => 3);
}

// output:
// mode Y: 3

还可以利用 *+ 等进行重复匹配

macro_rules! test {
    (x => ($( $e:expr ),*)) => ($( println!("mode X: {}", $e);)*);
    (y => ($( $e:expr ),*)) => ($( println!("mode Y: {}", $e);)*);
}

fn main() {
    test!(x => (3, 4, 5));
}

// output:
// mode X: 3
// mode X: 4
// mode X: 5

其中 matcher 中可以使用

  • ident: an identifier. Examples: x; foo.
  • path: a qualified name. Example: T::SpecialA.
  • expr: an expression. Examples: 2 + 2; if true { 1 } else { 2 }; f(42).
  • ty: a type. Examples: i32; Vec<(char, String)>; &T.
  • pat: a pattern. Examples: Some(t); (17, 'a'); _.
  • stmt: a single statement. Example: let x = 3.
  • block: a brace-delimited sequence of statements and optionally an expression. Example: { log(error, "hi"); return 12; }.
  • item: an item. Examples: fn foo() { }; struct Bar;.
  • meta: a “meta item”, as found in attributes. Example: cfg(target_os = "windows").
  • tt: a single token tree.

token tree 可以为

  • a sequence of token trees surrounded by matching (), [], or {}, or
  • any other single token.

vga/src/lib.rs 中添加如下 macro

pub fn kprint(args: fmt::Arguments) {
    WRITER.lock().write_fmt(args).unwrap();
}

#[macro_export]
macro_rules! kprint {
    ($($arg:tt)*) => ({
        $crate::kprint(format_args!($($arg)*));
    });
}

#[macro_export]
macro_rules! kprintln {
    ($fmt:expr) => (kprint!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (kprint!(concat!($fmt, "\n"), $($arg)*));
}

src/lib.rs 中添加如下代码

#[macro_use]
extern crate vga;

我们便可以在 kmain 中使用 kprintln!

#[no_mangle]
pub extern fn kmain() -> ! {
  kprintln!("Welcome to Japari Park")j;
  loop {}
}

Reference #

Macros - The Rust Programming Language