my_ast/
expression.rs

1
2#[derive(Clone, Debug, PartialEq)]
3pub enum Expression {
4    Bin {
5        left: Box<Self>,
6        op: BinOP,
7        right: Box<Self>
8    },
9    Number(f64),
10    Ident(String),
11}
12
13#[derive(Clone, Debug, PartialEq)]
14pub enum BinOP {
15    Add,
16    Minus
17}
18
19#[macro_export]
20macro_rules! expr {
21    ((add $left:tt $right:tt)) => {
22        $crate::Expression::Bin {
23            left: Box::new(expr!($left)),
24            op: $crate::BinOP::Add,
25            right: Box::new(expr!($right)),
26        }
27    };
28    ((minus $left:tt $right:tt)) => {
29        $crate::Expression::Bin {
30            left: Box::new(expr!($left)),
31            op: $crate::BinOP::Minus,
32            right: Box::new(expr!($right)),
33        }
34    };
35    ($t:ident) => {
36        $crate::Expression::from(stringify!($ident))
37    };
38    ($e:expr) => {
39        $crate::Expression::from($e)
40    };
41}
42
43macro_rules! impl_number {
44    ($t: ident) => {
45        impl From<$t> for crate::Expression {
46            fn from(v: $t) -> Self {
47                Expression::Number(v as f64)
48            }
49        } 
50    }
51}
52
53macro_rules! impl_numbers {
54    ($($t:ident)*) => {
55        $(
56            impl_number!($t);
57        )*
58    }
59}
60
61impl_numbers!(u8 u16 u32 u64 i8 i16 i32 i64 usize f32 f64);
62
63impl From<String> for Expression {
64    fn from(s: String) -> Self {
65        Expression::Ident(s)
66    }
67}
68
69impl<'a> From<&'a str> for Expression {
70    fn from(s: &'a str) -> Self {
71        Expression::Ident(s.to_string())
72    }
73}
74
75#[test]
76fn expr() {
77    expr!(aaa);
78    expr!((add 1 2));
79    expr!((minus 1 2));
80    expr!((minus (add 1.0 2) 2));
81    expr!(1);
82}