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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#[allow(unused_macros)]
#[macro_export]
macro_rules! lisp {


    // Embed a Rust expression with { }
    ( { $e:expr } ) => {
        $e
    };


    // Lists
    ( ( $($val:tt)* ) ) => {
        Value::List([ $(lisp!{ $val }),* ].iter().collect::<List>())
    };


    // Symbols
    ($sym:ident) => {
        Value::Symbol(String::from(stringify!( $sym )))
    };
    // these aren't valid Rust identifiers
    ( + ) =>  { Value::Symbol(String::from("+")) };
    ( - ) =>  { Value::Symbol(String::from("-")) };
    ( * ) =>  { Value::Symbol(String::from("*")) };
    ( / ) =>  { Value::Symbol(String::from("/")) };
    ( == ) => { Value::Symbol(String::from("==")) };
    ( != ) => { Value::Symbol(String::from("!=")) };
    ( < ) =>  { Value::Symbol(String::from("<")) };
    ( <= ) => { Value::Symbol(String::from("<=")) };
    ( > ) =>  { Value::Symbol(String::from(">")) };
    ( >= ) => { Value::Symbol(String::from(">=")) };


    // Literals
    ($e:literal) => {
        // HACK: Macros don't have a good way to
        // distinguish different kinds of literals,
        // so we just kick those out to be parsed
        // at runtime.
        parse(stringify!($e)).next().unwrap().unwrap()
    };


    // 🦀 Very special!
    // Special atoms
    (Nil) => { Value::NIL };
    (T) =>   { Value::T   };
    (F) =>   { Value::F   };
}