rustdb/
cexp.rs

1use crate::{get_bytes, util, CExp, CExpPtr, EvalEnv, Function, Rc, Value};
2
3/// Function call.
4pub(crate) struct Call {
5    pub fp: Rc<Function>,
6    pub pv: Vec<CExpPtr<Value>>,
7}
8
9impl CExp<Value> for Call {
10    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> Value {
11        for exp in &self.pv {
12            let v = exp.eval(e, d);
13            e.stack.push(v);
14        }
15        e.call(&self.fp);
16        e.stack.pop().unwrap()
17    }
18}
19
20pub(crate) struct Case<T> {
21    pub whens: Vec<(CExpPtr<bool>, CExpPtr<T>)>,
22    pub els: CExpPtr<T>,
23}
24
25impl<T> CExp<T> for Case<T> {
26    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
27        for (b, v) in &self.whens {
28            if b.eval(e, d) {
29                return v.eval(e, d);
30            }
31        }
32        self.els.eval(e, d)
33    }
34}
35
36pub(crate) struct Concat(pub CExpPtr<Value>, pub CExpPtr<Value>);
37
38impl CExp<Value> for Concat {
39    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> Value {
40        let mut s1: Value = self.0.eval(e, d);
41        let s2: Rc<String> = self.1.eval(e, d).str();
42        // Append to existing string if not shared.
43        if let Value::String(s) = &mut s1 {
44            if let Some(ms) = Rc::get_mut(s) {
45                ms.push_str(&s2);
46                return s1;
47            }
48        }
49        let s1 = s1.str();
50        let mut s = String::with_capacity(s1.len() + s2.len());
51        s.push_str(&s1);
52        s.push_str(&s2);
53        Value::String(Rc::new(s))
54    }
55}
56
57pub(crate) struct BinConcat(pub CExpPtr<Value>, pub CExpPtr<Value>);
58
59impl CExp<Value> for BinConcat {
60    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> Value {
61        let mut b1 = self.0.eval(e, d);
62        let b2 = self.1.eval(e, d).bin();
63        // Append to existing bytes if not shared.
64        if let Value::RcBinary(b) = &mut b1 {
65            if let Some(mb) = Rc::get_mut(b) {
66                mb.extend_from_slice(&b2);
67                return b1;
68            }
69        }
70        let b1 = b1.bin();
71        let mut b = Vec::with_capacity(b1.len() + b2.len());
72        b.extend_from_slice(&b1);
73        b.extend_from_slice(&b2);
74        Value::RcBinary(Rc::new(b))
75    }
76}
77
78pub(crate) struct Or(pub CExpPtr<bool>, pub CExpPtr<bool>);
79
80impl CExp<bool> for Or {
81    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
82        self.0.eval(e, d) || self.1.eval(e, d)
83    }
84}
85
86pub(crate) struct And(pub CExpPtr<bool>, pub CExpPtr<bool>);
87
88impl CExp<bool> for And {
89    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
90        self.0.eval(e, d) && self.1.eval(e, d)
91    }
92}
93
94pub(crate) struct Minus<T>(pub CExpPtr<T>);
95
96impl<T> CExp<T> for Minus<T>
97where
98    T: std::ops::Neg<Output = T>,
99{
100    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
101        -self.0.eval(e, d)
102    }
103}
104
105pub(crate) struct Not(pub CExpPtr<bool>);
106
107impl CExp<bool> for Not {
108    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
109        !self.0.eval(e, d)
110    }
111}
112
113pub(crate) struct Add<T>(pub CExpPtr<T>, pub CExpPtr<T>);
114
115impl<T> CExp<T> for Add<T>
116where
117    T: std::ops::Add<Output = T>,
118{
119    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
120        self.0.eval(e, d) + self.1.eval(e, d)
121    }
122}
123
124pub(crate) struct Sub<T>(pub CExpPtr<T>, pub CExpPtr<T>);
125
126impl<T> CExp<T> for Sub<T>
127where
128    T: std::ops::Sub<Output = T>,
129{
130    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
131        self.0.eval(e, d) - self.1.eval(e, d)
132    }
133}
134
135pub(crate) struct Mul<T>(pub CExpPtr<T>, pub CExpPtr<T>);
136
137impl<T> CExp<T> for Mul<T>
138where
139    T: std::ops::Mul<Output = T>,
140{
141    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
142        self.0.eval(e, d) * self.1.eval(e, d)
143    }
144}
145
146pub(crate) struct Div<T>(pub CExpPtr<T>, pub CExpPtr<T>);
147
148impl<T> CExp<T> for Div<T>
149where
150    T: std::ops::Div<Output = T>,
151{
152    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
153        self.0.eval(e, d) / self.1.eval(e, d)
154    }
155}
156
157pub(crate) struct Rem<T>(pub CExpPtr<T>, pub CExpPtr<T>);
158
159impl<T> CExp<T> for Rem<T>
160where
161    T: std::ops::Rem<Output = T>,
162{
163    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> T {
164        self.0.eval(e, d) % self.1.eval(e, d)
165    }
166}
167
168pub(crate) struct Equal<T>(pub CExpPtr<T>, pub CExpPtr<T>);
169
170impl<T> CExp<bool> for Equal<T>
171where
172    T: std::cmp::PartialOrd,
173{
174    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
175        self.0.eval(e, d) == self.1.eval(e, d)
176    }
177}
178
179pub(crate) struct NotEqual<T>(pub CExpPtr<T>, pub CExpPtr<T>);
180
181impl<T> CExp<bool> for NotEqual<T>
182where
183    T: std::cmp::PartialOrd,
184{
185    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
186        self.0.eval(e, d) != self.1.eval(e, d)
187    }
188}
189
190pub(crate) struct Less<T>(pub CExpPtr<T>, pub CExpPtr<T>);
191
192impl<T> CExp<bool> for Less<T>
193where
194    T: std::cmp::PartialOrd,
195{
196    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
197        self.0.eval(e, d) < self.1.eval(e, d)
198    }
199}
200
201pub(crate) struct Greater<T>(pub CExpPtr<T>, pub CExpPtr<T>);
202
203impl<T> CExp<bool> for Greater<T>
204where
205    T: std::cmp::PartialOrd,
206{
207    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
208        self.0.eval(e, d) > self.1.eval(e, d)
209    }
210}
211
212pub(crate) struct LessEqual<T>(pub CExpPtr<T>, pub CExpPtr<T>);
213
214impl<T> CExp<bool> for LessEqual<T>
215where
216    T: std::cmp::PartialOrd,
217{
218    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
219        self.0.eval(e, d) <= self.1.eval(e, d)
220    }
221}
222
223pub(crate) struct GreaterEqual<T>(pub CExpPtr<T>, pub CExpPtr<T>);
224
225impl<T> CExp<bool> for GreaterEqual<T>
226where
227    T: std::cmp::PartialOrd,
228{
229    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
230        self.0.eval(e, d) >= self.1.eval(e, d)
231    }
232}
233
234pub(crate) struct ColumnI64 {
235    pub off: usize,
236}
237
238impl CExp<i64> for ColumnI64 {
239    fn eval(&self, _e: &mut EvalEnv, data: &[u8]) -> i64 {
240        util::getu64(data, self.off) as i64
241    }
242}
243
244pub(crate) struct ColumnI {
245    pub off: usize,
246    pub size: usize,
247}
248
249impl CExp<i64> for ColumnI {
250    fn eval(&self, _e: &mut EvalEnv, data: &[u8]) -> i64 {
251        util::iget(data, self.off, self.size)
252    }
253}
254
255pub(crate) struct ColumnI8 {
256    pub off: usize,
257}
258
259impl CExp<i64> for ColumnI8 {
260    fn eval(&self, _e: &mut EvalEnv, data: &[u8]) -> i64 {
261        data[self.off] as i8 as i64
262    }
263}
264
265pub(crate) struct ColumnF64 {
266    pub off: usize,
267}
268
269impl CExp<f64> for ColumnF64 {
270    fn eval(&self, _e: &mut EvalEnv, data: &[u8]) -> f64 {
271        util::getf64(data, self.off)
272    }
273}
274
275pub(crate) struct ColumnF32 {
276    pub off: usize,
277}
278
279impl CExp<f64> for ColumnF32 {
280    fn eval(&self, _e: &mut EvalEnv, data: &[u8]) -> f64 {
281        util::getf32(data, self.off) as f64
282    }
283}
284
285pub(crate) struct ColumnBool {
286    pub off: usize,
287}
288
289impl CExp<bool> for ColumnBool {
290    fn eval(&self, _e: &mut EvalEnv, data: &[u8]) -> bool {
291        data[self.off] & 1 != 0
292    }
293}
294
295pub(crate) struct ColumnString {
296    pub off: usize,
297    pub size: usize,
298}
299
300impl CExp<Value> for ColumnString {
301    fn eval(&self, ee: &mut EvalEnv, data: &[u8]) -> Value {
302        let bytes = get_bytes(&ee.db, &data[self.off..], self.size).0;
303        let str = String::from_utf8(bytes).unwrap();
304        Value::String(Rc::new(str))
305    }
306}
307
308pub(crate) struct ColumnBinary {
309    pub off: usize,
310    pub size: usize,
311}
312
313impl CExp<Value> for ColumnBinary {
314    fn eval(&self, ee: &mut EvalEnv, data: &[u8]) -> Value {
315        let bytes = get_bytes(&ee.db, &data[self.off..], self.size).0;
316        Value::RcBinary(Rc::new(bytes))
317    }
318}
319
320pub(crate) struct Local(pub usize);
321
322impl CExp<f64> for Local {
323    fn eval(&self, e: &mut EvalEnv, _d: &[u8]) -> f64 {
324        if let Value::Float(v) = e.stack[e.bp + self.0] {
325            v
326        } else {
327            unsafe_panic!()
328        }
329    }
330}
331impl CExp<i64> for Local {
332    fn eval(&self, e: &mut EvalEnv, _d: &[u8]) -> i64 {
333        if let Value::Int(v) = e.stack[e.bp + self.0] {
334            v
335        } else {
336            unsafe_panic!()
337        }
338    }
339}
340
341impl CExp<bool> for Local {
342    fn eval(&self, e: &mut EvalEnv, _d: &[u8]) -> bool {
343        if let Value::Bool(v) = e.stack[e.bp + self.0] {
344            v
345        } else {
346            unsafe_panic!()
347        }
348    }
349}
350
351impl CExp<Value> for Local {
352    fn eval(&self, e: &mut EvalEnv, _d: &[u8]) -> Value {
353        e.stack[e.bp + self.0].clone()
354    }
355}
356
357pub(crate) struct Const<T>(pub T);
358
359impl<T> CExp<T> for Const<T>
360where
361    T: Clone,
362{
363    fn eval(&self, _e: &mut EvalEnv, _d: &[u8]) -> T {
364        self.0.clone()
365    }
366}
367pub(crate) struct ValToInt(pub CExpPtr<Value>);
368
369impl CExp<i64> for ValToInt {
370    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> i64 {
371        if let Value::Int(x) = self.0.eval(e, d) {
372            return x;
373        }
374        unsafe_panic!();
375    }
376}
377
378pub(crate) struct ValToFloat(pub CExpPtr<Value>);
379
380impl CExp<f64> for ValToFloat {
381    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> f64 {
382        if let Value::Float(x) = self.0.eval(e, d) {
383            return x;
384        }
385        unsafe_panic!();
386    }
387}
388
389pub(crate) struct ValToBool(pub CExpPtr<Value>);
390
391impl CExp<bool> for ValToBool {
392    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> bool {
393        if let Value::Bool(x) = self.0.eval(e, d) {
394            return x;
395        }
396        unsafe_panic!();
397    }
398}
399
400pub(crate) struct IntToVal(pub CExpPtr<i64>);
401
402impl CExp<Value> for IntToVal {
403    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> Value {
404        Value::Int(self.0.eval(e, d))
405    }
406}
407
408pub(crate) struct FloatToVal(pub CExpPtr<f64>);
409
410impl CExp<Value> for FloatToVal {
411    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> Value {
412        Value::Float(self.0.eval(e, d))
413    }
414}
415
416pub(crate) struct BoolToVal(pub CExpPtr<bool>);
417
418impl CExp<Value> for BoolToVal {
419    fn eval(&self, e: &mut EvalEnv, d: &[u8]) -> Value {
420        Value::Bool(self.0.eval(e, d))
421    }
422}