0%

Thought about macros

Macro這東西很早就有了,不過各有巧妙不同。
在Assembler的年代就已經有Macro了

1
2
3
4
COPY            macro   Dest, Source
mov ax, Source
mov Dest, ax
endm

而在C語言的時候,Macro的被使用了更頻繁了

1
#define min(a, b) ((a < b) ? a : b)

C語言的Macro也很簡單,就只是作文字的代換而已。Side Effect除外,出錯的話也很難Debug,因此其他語言打算因此作改進。

Define group of functions

1
2
3
4
5
6
7
8
9
10
11
12
13
#define CK_PR_FENCE(T, I)                               \
CK_CC_INLINE static void \
ck_pr_fence_strict_##T(void) \
{ \
__asm__ __volatile__(I ::: "memory"); \
}

CK_PR_FENCE(atomic, "sfence")
CK_PR_FENCE(atomic_store, "sfence")
CK_PR_FENCE(atomic_load, "mfence")
CK_PR_FENCE(store_atomic, "sfence")
CK_PR_FENCE(load_atomic, "mfence")
CK_PR_FENCE(load, "lfence")

在這情況下 Templateˊ無能為力.

Rust

Macro overload

1
2
3
4
5
6
7
8
9
10
11
12
13
macro_rules! sayHello {
() => {
println!("sayHello");
};
($name:ident) => {
println!("sayHello {:?}", stringify!($name));
};
}
fn main() {
sayHello!();
sayHello!(ABC);

}

Pattern Matching

1
2
3
4
5
6
7
8
9
macro_rules! min {
// base case
($x:expr) => ($x);
// `$x` followed by at least one `$y,`
($x:expr, $($y:expr),+) => (
// call min! on the tail `$y`
std::cmp::min($x, min!($($y),+))
)
}

Recursive Macro

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
macro_rules! write_html {
($w:expr, ) => (());

($w:expr, $e:tt) => (write!($w, "{}", $e));

($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{
write!($w, "<{}>", stringify!($tag));
write_html!($w, $($inner)*);
write!($w, "</{}>", stringify!($tag));
write_html!($w, $($rest)*);
}};
}

fn main() {
use std::fmt::Write;
let mut out = String::new();

write_html!(&mut out,
html[
head[title["Macros guide"]]
body[h1["Macros are the best!"]]
]);

assert_eq!(out,
"<html><head><title>Macros guide</title></head>\
<body><h1>Macros are the best!</h1></body></html>");
}

Nim

Reference

Macros - Rust Documentation
A Quick Intro to Rust Macros
Module macros - Nim
Nim Manual