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}