open_pql/pql_parser/ast/
expr.rs

1use derive_more::derive::From;
2
3use super::*;
4
5#[derive(Debug, Clone, Copy, Eq, PartialEq, From)]
6pub enum BinOp {
7    Add,
8    Sub,
9    Mul,
10    Div,
11    Eq,
12    Ge,
13    Gt,
14    Le,
15    Lt,
16}
17
18#[derive(Debug, Eq, PartialEq, From)]
19pub enum Expr<'i> {
20    Ident(Ident<'i>),
21    Str(Str<'i>),
22    FnCall(FnCall<'i>),
23    Int(Num<'i>),
24    BinOp(BinOp, Box<Expr<'i>>, Box<Expr<'i>>),
25}
26
27impl Expr<'_> {
28    pub(crate) const fn loc(&self) -> LocInfo {
29        match self {
30            Expr::Ident(id) => id.loc,
31            Expr::Str(s) => s.loc,
32            Expr::FnCall(fncall) => fncall.loc,
33            Expr::Int(int) => int.loc,
34            Expr::BinOp(_, l, r) => (l.loc().0, r.loc().1),
35        }
36    }
37
38    pub(crate) fn binop(op: BinOp, l: Self, r: Self) -> Self {
39        Self::BinOp(op, Box::new(l), Box::new(r))
40    }
41}
42
43#[cfg_attr(coverage_nightly, coverage(off))]
44#[cfg(test)]
45mod tests {
46    use super::{super::super::parser::*, *};
47
48    fn e(s: &str) -> Expr {
49        ExprParser::new().parse(s).unwrap()
50    }
51
52    #[test]
53    fn test_cmp() {
54        assert![matches!(e("1 = 1"), Expr::BinOp(BinOp::Eq, _, _))];
55        assert![matches!(e("1 > 1"), Expr::BinOp(BinOp::Gt, _, _))];
56        assert![matches!(e("1 >= 1"), Expr::BinOp(BinOp::Ge, _, _))];
57        assert![matches!(e("1 < 1"), Expr::BinOp(BinOp::Lt, _, _))];
58        assert![matches!(e("1 <= 1"), Expr::BinOp(BinOp::Le, _, _))];
59    }
60
61    #[test]
62    fn test_expr() {
63        assert![matches!(e("a"), Expr::Ident(_))];
64        assert![matches!(e("'a'"), Expr::Str(_))];
65        assert![matches!(e("sin(x)"), Expr::FnCall(_))];
66    }
67
68    #[test]
69    fn test_loc() {
70        assert_eq!(e("a").loc(), (0, 1));
71        assert_eq!(e("'a'").loc(), (0, 3));
72        assert_eq!(e("sin(x)").loc(), (0, 6));
73        assert_eq!(e("10").loc(), (0, 2));
74        assert_eq!(e("1 >= 3").loc(), (0, 6));
75    }
76}