1use super::{BinaryOp, UnaryOp};
6use crate::id::IndexId;
7use crate::prelude::AnyBox;
8use strum::EnumIs;
9
10#[doc(hidden)]
11#[derive(Clone, Debug, EnumIs, Eq, Hash, Ord, PartialEq, PartialOrd)]
12pub enum Expr<K = usize, V = AnyBox> {
13 Binary(BinaryExpr<K, V>),
14 Unary(UnaryExpr<K, V>),
15 Constant(V),
16 Variable { id: IndexId<K>, value: V },
17}
18
19impl<K, V> Expr<K, V> {
20 pub fn binary(lhs: Expr<K, V>, rhs: Expr<K, V>, op: BinaryOp) -> Self {
21 Self::Binary(BinaryExpr::new(lhs, rhs, op))
22 }
23
24 pub fn constant(value: V) -> Self {
25 Self::Constant(value)
26 }
27
28 pub fn unary(arg: Expr<K, V>, op: UnaryOp) -> Self {
29 Self::Unary(UnaryExpr::new(arg, op))
30 }
31
32 pub fn variable(idx: K, value: V) -> Self {
33 Self::Variable {
34 id: IndexId::from_index(idx),
35 value,
36 }
37 }
38}
39
40#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
41pub struct BinaryExpr<K = usize, V = AnyBox> {
42 lhs: Box<Expr<K, V>>,
43 op: BinaryOp,
44 rhs: Box<Expr<K, V>>,
45}
46
47#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
48pub struct UnaryExpr<K = usize, V = AnyBox> {
49 op: UnaryOp,
50 recv: Box<Expr<K, V>>,
51}
52
53mod expr_impl {
54 use super::{BinaryExpr, Expr, UnaryExpr};
55 use crate::ops::{BinaryOp, UnaryOp};
56
57 impl<K, V> BinaryExpr<K, V> {
58 pub fn new(lhs: Expr<K, V>, rhs: Expr<K, V>, op: BinaryOp) -> Self {
59 Self {
60 lhs: Box::new(lhs),
61 op,
62 rhs: Box::new(rhs),
63 }
64 }
65
66 pub fn lhs(&self) -> &Expr<K, V> {
67 &self.lhs
68 }
69
70 pub fn lhs_mut(&mut self) -> &mut Expr<K, V> {
71 &mut self.lhs
72 }
73
74 pub fn op(&self) -> BinaryOp {
75 self.op
76 }
77
78 pub fn op_mut(&mut self) -> &mut BinaryOp {
79 &mut self.op
80 }
81
82 pub fn rhs(&self) -> &Expr<K, V> {
83 &self.rhs
84 }
85
86 pub fn rhs_mut(&mut self) -> &mut Expr<K, V> {
87 &mut self.rhs
88 }
89 }
90
91 impl<K, V> UnaryExpr<K, V> {
92 pub fn new(recv: Expr<K, V>, op: UnaryOp) -> Self {
93 Self {
94 recv: Box::new(recv),
95 op,
96 }
97 }
98
99 pub fn op(&self) -> UnaryOp {
100 self.op
101 }
102
103 pub fn op_mut(&mut self) -> &mut UnaryOp {
104 &mut self.op
105 }
106
107 pub fn recv(&self) -> &Expr<K, V> {
108 &self.recv
109 }
110
111 pub fn recv_mut(&mut self) -> &mut Expr<K, V> {
112 &mut self.recv
113 }
114 }
115}