open_pql/pql_parser/ast/
expr.rs1use 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(test)]
44mod tests {
45 use super::{super::super::parser::*, *};
46
47 fn e(s: &str) -> Expr<'_> {
48 ExprParser::new().parse(s).unwrap()
49 }
50
51 #[test]
52 fn test_cmp() {
53 assert![matches!(e("1 = 1"), Expr::BinOp(BinOp::Eq, _, _))];
54 assert![matches!(e("1 > 1"), Expr::BinOp(BinOp::Gt, _, _))];
55 assert![matches!(e("1 >= 1"), Expr::BinOp(BinOp::Ge, _, _))];
56 assert![matches!(e("1 < 1"), Expr::BinOp(BinOp::Lt, _, _))];
57 assert![matches!(e("1 <= 1"), Expr::BinOp(BinOp::Le, _, _))];
58 }
59
60 #[test]
61 fn test_expr() {
62 assert![matches!(e("a"), Expr::Ident(_))];
63 assert![matches!(e("'a'"), Expr::Str(_))];
64 assert![matches!(e("sin(x)"), Expr::FnCall(_))];
65 }
66
67 #[test]
68 fn test_loc() {
69 assert_eq!(e("a").loc(), (0, 1));
70 assert_eq!(e("'a'").loc(), (0, 3));
71 assert_eq!(e("sin(x)").loc(), (0, 6));
72 assert_eq!(e("10").loc(), (0, 2));
73 assert_eq!(e("1 >= 3").loc(), (0, 6));
74 }
75}