1use crate::{get_bytes, util, CExp, CExpPtr, EvalEnv, Function, Rc, Value};
2
3pub(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 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 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}