acme_core/ops/
expr.rs

1/*
2    Appellation: expr <mod>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use 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}