makepad_live_compiler/
live_eval.rs

1pub use {
2    std::{
3        rc::Rc,
4        any::TypeId,
5    },
6    crate::{
7        makepad_math::*,
8        makepad_live_id::*,
9        makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
10        live_error::{LiveError},
11        live_node_vec::*,
12        live_registry::LiveRegistry,
13        live_node::*
14    }
15};
16
17
18#[derive(Debug)]
19pub enum LiveEval {
20    Float64(f64),
21    Vec2(Vec2),
22    Vec3(Vec3),
23    Vec4(Vec4),
24    Int64(i64),
25    Bool(bool),
26    String(Rc<String>),
27}
28
29impl LiveError {
30    fn eval_error_wrong_value_in_expression(origin: LiveErrorOrigin, index: usize, nodes: &[LiveNode], ty: &str) ->Self{
31        Self::eval_error(origin, index, nodes, format!("wrong value in expression of type {} value: {:?}", ty, nodes[index].value))
32    }
33    
34    fn eval_error_binop_undefined_in_expression(origin: LiveErrorOrigin, index: usize, nodes: &[LiveNode], op: LiveBinOp, a: LiveEval, b: LiveEval)->Self {
35        Self::eval_error(origin, index, nodes, format!("Operation {:?} undefined between {:?} and {:?}", op, a, b))
36    }
37    
38    fn eval_error_unop_undefined_in_expression(origin: LiveErrorOrigin, index: usize, nodes: &[LiveNode], op: LiveUnOp, a: LiveEval)->Self {
39        Self::eval_error(origin, index, nodes, format!("Operation {:?} undefined for {:?}", op, a))
40    }
41    
42    fn eval_error_expression_call_not_implemented(origin: LiveErrorOrigin, index: usize, nodes: &[LiveNode], ident: LiveId, args: usize)->Self {
43        Self::eval_error(origin, index, nodes, format!("Expression call not implemented ident:{} with number of args: {}", ident, args))
44    }
45    
46    fn eval_error_cant_find_target(origin: LiveErrorOrigin, index: usize, nodes: &[LiveNode], id: LiveId)->Self {
47        Self::eval_error(origin, index, nodes, format!("cant find target: {}", id))
48    }
49    
50    fn eval_error(origin: LiveErrorOrigin, index: usize, nodes: &[LiveNode], message: String)->Self{
51        LiveError {
52            origin,
53            message,
54            span: nodes[index].origin.token_id().unwrap().into()
55        }
56    }
57}
58
59pub fn live_eval(live_registry: &LiveRegistry, start: usize, index: &mut usize, nodes: &[LiveNode]) -> Result<LiveEval,LiveError> {
60    Ok(match &nodes[*index].value {
61        LiveValue::Str(_) |
62        LiveValue::InlineString(_) => {
63            LiveEval::String(Rc::new(live_registry.live_node_as_string(&nodes[*index]).unwrap()))
64        }
65        LiveValue::Dependency(v)=>LiveEval::String(v.clone()),
66        LiveValue::String(v)=>LiveEval::String(v.clone()),
67        LiveValue::Float32(v) => {
68            *index += 1;
69            LiveEval::Float64(*v as f64)
70        }
71        LiveValue::Float64(v) => {
72            *index += 1;
73            LiveEval::Float64(*v)
74        }
75        LiveValue::Int64(v) => {
76            *index += 1;
77            LiveEval::Int64(*v)
78        }
79        LiveValue::Vec2(v) => {
80            *index += 1;
81            LiveEval::Vec2(*v)
82        }
83        LiveValue::Vec3(v) => {
84            *index += 1;
85            LiveEval::Vec3(*v)
86        }
87        LiveValue::Vec4(v) => {
88            *index += 1;
89            LiveEval::Vec4(*v)
90        }
91        LiveValue::Color(c) => {
92            *index += 1;
93            LiveEval::Vec4(Vec4::from_u32(*c))
94        }
95        LiveValue::Bool(v) => {
96            *index += 1;
97            LiveEval::Bool(*v)
98        }
99        LiveValue::Id(id) => { // look it up from start on up
100            *index += 1;
101            
102            fn last_keyframe_value_from_array(index: usize, nodes: &[LiveNode]) -> Option<usize> {
103                if let Some(index) = nodes.last_child(index) {
104                    if nodes[index].value.is_object() {
105                        return nodes.child_by_name(index, live_id!(value).as_field());
106                    }
107                    else {
108                        return Some(index)
109                    }
110                }
111                None
112            }
113            
114            fn value_to_live_value(live_registry: &LiveRegistry, index: usize, nodes: &[LiveNode]) -> Result<LiveEval, LiveError> {
115                Ok(match &nodes[index].value {
116                    LiveValue::Float64(val) => LiveEval::Float64(*val),
117                    LiveValue::Int64(val) => LiveEval::Int64(*val),
118                    LiveValue::Bool(val) => LiveEval::Bool(*val),
119                    LiveValue::Vec2(val) => LiveEval::Vec2(*val),
120                    LiveValue::Vec3(val) => LiveEval::Vec3(*val),
121                    LiveValue::Vec4(val) => LiveEval::Vec4(*val),
122                    LiveValue::Color(c) => LiveEval::Vec4(Vec4::from_u32(*c)),
123                    LiveValue::Str(_) |
124                    LiveValue::InlineString(_) => LiveEval::String(Rc::new(live_registry.live_node_as_string(&nodes[index]).unwrap())),
125                    LiveValue::String(v) =>LiveEval::String(v.clone()),
126                    LiveValue::Dependency(v) =>LiveEval::String(v.clone()),
127                    LiveValue::Expr {..} => { // expr depends on expr
128                        live_eval(live_registry, index, &mut (index + 1), nodes)?
129                    }
130                    LiveValue::Array => { // got an animation track. select the last value
131                        if let Some(index) = last_keyframe_value_from_array(index, nodes) {
132                            match &nodes[index].value {
133                                LiveValue::Float64(val) => LiveEval::Float64(*val),
134                                LiveValue::Int64(val) => LiveEval::Int64(*val),
135                                LiveValue::Bool(val) => LiveEval::Bool(*val),
136                                _ => {
137                                    return Err(LiveError::eval_error_wrong_value_in_expression(live_error_origin!(), index, nodes, "Animation array"))
138                                }
139                            }
140                        }
141                        else {
142                            return Err(LiveError::eval_error_wrong_value_in_expression(live_error_origin!(), index, nodes, "Animation array"))
143                        }
144                    },
145                    _ => {
146                        return Err(LiveError::eval_error_wrong_value_in_expression(live_error_origin!(), index, nodes, "Id referenmce"))
147                    }
148                })
149            }
150            /*if let Some(index) = nodes.scope_up_by_name(start - 1, id.as_field()) {
151                // found ok now what. it depends on the type of the thing here
152                value_to_live_value(live_registry, index, nodes)?
153            }
154            else
155            if let Some(index) = nodes.scope_up_by_name(start - 1, id.as_instance()) {
156                // found ok now what. it depends on the type of the thing here
157                value_to_live_value(live_registry, index, nodes)?
158            }
159            else */if let Some(token_id) = nodes[start].origin.token_id() { // lets find it on live registry via origin
160                
161                let origin_file_id = token_id.file_id().unwrap();
162                let expand_index = nodes[start].get_expr_expand_index().unwrap();
163                
164                if let Some(ptr) = live_registry.find_scope_ptr_via_expand_index(origin_file_id, expand_index as usize, *id) {
165                    let (nodes, index) = live_registry.ptr_to_nodes_index(ptr);
166                    value_to_live_value(live_registry, index, nodes)?
167                }
168                else {
169                    return Err(LiveError::eval_error_cant_find_target(live_error_origin!(), *index, nodes, *id))
170                }
171            }
172            else {
173                return Err(LiveError::eval_error_cant_find_target(live_error_origin!(), *index, nodes, *id))
174            }
175        },
176        LiveValue::ExprUnOp(op) => {
177            *index += 1;
178            let a = live_eval(live_registry, start, index, nodes)?;
179            match op {
180                LiveUnOp::Not => match a {
181                    LiveEval::Bool(va) => LiveEval::Bool(!va),
182                    _ => return Err(LiveError::eval_error_unop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a))
183                }
184                LiveUnOp::Neg => match a {
185                    LiveEval::Float64(va) => LiveEval::Float64(-va),
186                    LiveEval::Int64(va) => LiveEval::Int64(-va),
187                    _ => return Err(LiveError::eval_error_unop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a))
188                }
189            }
190        }
191        LiveValue::ExprCall {ident, args} => {
192            *index += 1;
193            match ident {
194                live_id!(blend) if *args == 2 => {
195                    let a = live_eval(live_registry, start, index, nodes)?;
196                    let b = live_eval(live_registry, start, index, nodes)?;
197                    if let LiveEval::Vec4(va) = a {
198                        if let LiveEval::Vec4(vb) = b {
199                            // ok so how do we blend this eh.
200                            return Ok(LiveEval::Vec4(vec4(
201                                va.x + (vb.x - va.x) * vb.w,
202                                va.y + (vb.y - va.y) * vb.w,
203                                va.z + (vb.z - va.z) * vb.w,
204                                va.w
205                            )))
206                        }
207                    }
208                }
209                _ => {}
210            }
211            
212            return Err(LiveError::eval_error_expression_call_not_implemented(live_error_origin!(), *index, nodes, *ident, *args))
213        }
214        LiveValue::ExprBinOp(op) => {
215            *index += 1;
216            let a = live_eval(live_registry, start, index, nodes)?;
217            let b = live_eval(live_registry, start, index, nodes)?;
218            match op {
219                LiveBinOp::Or => match a {
220                    LiveEval::Bool(va) => match b {
221                        LiveEval::Bool(vb) => LiveEval::Bool(va || vb),
222                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
223                    }
224                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
225                }
226                LiveBinOp::And => match a {
227                    LiveEval::Bool(va) => match b {
228                        LiveEval::Bool(vb) => LiveEval::Bool(va && vb),
229                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
230                    }
231                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
232                },
233                LiveBinOp::Eq => match a {
234                    LiveEval::Bool(va) => match b {
235                        LiveEval::Bool(vb) => LiveEval::Bool(va == vb),
236                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
237                    }
238                    LiveEval::Int64(va) => match b {
239                        LiveEval::Int64(vb) => LiveEval::Bool(va == vb),
240                        LiveEval::Float64(vb) => LiveEval::Bool(va as f64 == vb),
241                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
242                    }
243                    LiveEval::Float64(va) => match b {
244                        LiveEval::Int64(vb) => LiveEval::Bool(va == vb as f64),
245                        LiveEval::Float64(vb) => LiveEval::Bool(va == vb),
246                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
247                    }
248                    LiveEval::Vec2(va) => match b {
249                        LiveEval::Vec2(vb) => LiveEval::Bool(va == vb),
250                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
251                    }
252                    LiveEval::Vec3(va) => match b {
253                        LiveEval::Vec3(vb) => LiveEval::Bool(va == vb),
254                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
255                    }
256                    LiveEval::Vec4(va) => match b {
257                        LiveEval::Vec4(vb) => LiveEval::Bool(va == vb),
258                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
259                    }
260                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
261                },
262                LiveBinOp::Ne => match a {
263                    LiveEval::Bool(va) => match b {
264                        LiveEval::Bool(vb) => LiveEval::Bool(va != vb),
265                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
266                    }
267                    LiveEval::Int64(va) => match b {
268                        LiveEval::Int64(vb) => LiveEval::Bool(va != vb),
269                        LiveEval::Float64(vb) => LiveEval::Bool(va as f64 != vb),
270                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
271                    }
272                    LiveEval::Float64(va) => match b {
273                        LiveEval::Int64(vb) => LiveEval::Bool(va != vb as f64),
274                        LiveEval::Float64(vb) => LiveEval::Bool(va != vb),
275                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
276                    }
277                    LiveEval::Vec2(va) => match b {
278                        LiveEval::Vec2(vb) => LiveEval::Bool(va != vb),
279                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
280                    }
281                    LiveEval::Vec3(va) => match b {
282                        LiveEval::Vec3(vb) => LiveEval::Bool(va != vb),
283                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
284                    }
285                    LiveEval::Vec4(va) => match b {
286                        LiveEval::Vec4(vb) => LiveEval::Bool(va != vb),
287                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
288                    }
289                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
290                },
291                LiveBinOp::Lt => match a {
292                    LiveEval::Int64(va) => match b {
293                        LiveEval::Int64(vb) => LiveEval::Bool(va < vb),
294                        LiveEval::Float64(vb) => LiveEval::Bool((va as f64) < vb),
295                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
296                    }
297                    LiveEval::Float64(va) => match b {
298                        LiveEval::Int64(vb) => LiveEval::Bool(va < vb as f64),
299                        LiveEval::Float64(vb) => LiveEval::Bool(va < vb),
300                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
301                    }
302                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
303                },
304                LiveBinOp::Le => match a {
305                    LiveEval::Int64(va) => match b {
306                        LiveEval::Int64(vb) => LiveEval::Bool(va <= vb),
307                        LiveEval::Float64(vb) => LiveEval::Bool((va as f64) <= vb),
308                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
309                    }
310                    LiveEval::Float64(va) => match b {
311                        LiveEval::Int64(vb) => LiveEval::Bool(va <= vb as f64),
312                        LiveEval::Float64(vb) => LiveEval::Bool(va <= vb),
313                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
314                    }
315                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
316                },
317                LiveBinOp::Gt => match a {
318                    LiveEval::Int64(va) => match b {
319                        LiveEval::Int64(vb) => LiveEval::Bool(va > vb),
320                        LiveEval::Float64(vb) => LiveEval::Bool((va as f64) > vb),
321                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
322                    }
323                    LiveEval::Float64(va) => match b {
324                        LiveEval::Int64(vb) => LiveEval::Bool(va > vb as f64),
325                        LiveEval::Float64(vb) => LiveEval::Bool(va > vb),
326                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
327                    }
328                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
329                },
330                LiveBinOp::Ge => match a {
331                    LiveEval::Int64(va) => match b {
332                        LiveEval::Int64(vb) => LiveEval::Bool(va >= vb),
333                        LiveEval::Float64(vb) => LiveEval::Bool((va as f64) >= vb),
334                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
335                    }
336                    LiveEval::Float64(va) => match b {
337                        LiveEval::Int64(vb) => LiveEval::Bool(va >= vb as f64),
338                        LiveEval::Float64(vb) => LiveEval::Bool(va >= vb),
339                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
340                    }
341                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
342                },
343                LiveBinOp::Add => match a {
344                    LiveEval::Int64(va) => match b {
345                        LiveEval::Int64(vb) => LiveEval::Int64(va + vb),
346                        LiveEval::Float64(vb) => LiveEval::Float64((va as f64) + vb),
347                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb + va as f32),
348                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb + va as f32),
349                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb + va as f32),
350                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
351                    }
352                    LiveEval::Float64(va) => match b {
353                        LiveEval::Int64(vb) => LiveEval::Float64(va + vb as f64),
354                        LiveEval::Float64(vb) => LiveEval::Float64(va + vb),
355                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb + va as f32),
356                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb + va as f32),
357                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb + va as f32),
358                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
359                    }
360                    LiveEval::Vec2(va) => match b {
361                        LiveEval::Vec2(vb) => LiveEval::Vec2(va + vb),
362                        LiveEval::Int64(vb) => LiveEval::Vec2(va + vb as f32),
363                        LiveEval::Float64(vb) => LiveEval::Vec2(va + vb as f32),
364                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
365                    }
366                    LiveEval::Vec3(va) => match b {
367                        LiveEval::Vec3(vb) => LiveEval::Vec3(va + vb),
368                        LiveEval::Int64(vb) => LiveEval::Vec3(va + vb as f32),
369                        LiveEval::Float64(vb) => LiveEval::Vec3(va + vb as f32),
370                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
371                    }
372                    LiveEval::Vec4(va) => match b {
373                        LiveEval::Vec4(vb) => LiveEval::Vec4(va + vb),
374                        LiveEval::Int64(vb) => LiveEval::Vec4(va + vb as f32),
375                        LiveEval::Float64(vb) => LiveEval::Vec4(va + vb as f32),
376                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
377                    }
378                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
379                },
380                LiveBinOp::Sub => match a {
381                    LiveEval::Int64(va) => match b {
382                        LiveEval::Int64(vb) => LiveEval::Int64(va - vb),
383                        LiveEval::Float64(vb) => LiveEval::Float64((va as f64) - vb),
384                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb - va as f32),
385                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb - va as f32),
386                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb - va as f32),
387                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
388                    }
389                    LiveEval::Float64(va) => match b {
390                        LiveEval::Int64(vb) => LiveEval::Float64(va - vb as f64),
391                        LiveEval::Float64(vb) => LiveEval::Float64(va - vb),
392                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb - va as f32),
393                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb - va as f32),
394                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb - va as f32),
395                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
396                    }
397                    LiveEval::Vec2(va) => match b {
398                        LiveEval::Vec2(vb) => LiveEval::Vec2(va - vb),
399                        LiveEval::Int64(vb) => LiveEval::Vec2(va - vb as f32),
400                        LiveEval::Float64(vb) => LiveEval::Vec2(va - vb as f32),
401                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
402                    }
403                    LiveEval::Vec3(va) => match b {
404                        LiveEval::Vec3(vb) => LiveEval::Vec3(va - vb),
405                        LiveEval::Int64(vb) => LiveEval::Vec3(va - vb as f32),
406                        LiveEval::Float64(vb) => LiveEval::Vec3(va - vb as f32),
407                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
408                    }
409                    LiveEval::Vec4(va) => match b {
410                        LiveEval::Vec4(vb) => LiveEval::Vec4(va - vb),
411                        LiveEval::Int64(vb) => LiveEval::Vec4(va - vb as f32),
412                        LiveEval::Float64(vb) => LiveEval::Vec4(va - vb as f32),
413                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
414                    }
415                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
416                },
417                LiveBinOp::Mul => match a {
418                    LiveEval::Int64(va) => match b {
419                        LiveEval::Int64(vb) => LiveEval::Int64(va * vb),
420                        LiveEval::Float64(vb) => LiveEval::Float64((va as f64) * vb),
421                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb * va as f32),
422                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb * va as f32),
423                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb * va as f32),
424                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
425                    }
426                    LiveEval::Float64(va) => match b {
427                        LiveEval::Int64(vb) => LiveEval::Float64(va * vb as f64),
428                        LiveEval::Float64(vb) => LiveEval::Float64(va * vb),
429                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb * va as f32),
430                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb * va as f32),
431                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb * va as f32),
432                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
433                    }
434                    LiveEval::Vec2(va) => match b {
435                        LiveEval::Vec2(vb) => LiveEval::Vec2(va * vb),
436                        LiveEval::Int64(vb) => LiveEval::Vec2(va * vb as f32),
437                        LiveEval::Float64(vb) => LiveEval::Vec2(va * vb as f32),
438                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
439                    }
440                    LiveEval::Vec3(va) => match b {
441                        LiveEval::Vec3(vb) => LiveEval::Vec3(va * vb),
442                        LiveEval::Int64(vb) => LiveEval::Vec3(va * vb as f32),
443                        LiveEval::Float64(vb) => LiveEval::Vec3(va * vb as f32),
444                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
445                    }
446                    LiveEval::Vec4(va) => match b {
447                        LiveEval::Vec4(vb) => LiveEval::Vec4(va * vb),
448                        LiveEval::Int64(vb) => LiveEval::Vec4(va * vb as f32),
449                        LiveEval::Float64(vb) => LiveEval::Vec4(va * vb as f32),
450                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
451                    }
452                    _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
453                },
454                LiveBinOp::Div => match a {
455                    LiveEval::Int64(va) => match b {
456                        LiveEval::Int64(vb) => LiveEval::Float64(va as f64 / vb as f64),
457                        LiveEval::Float64(vb) => LiveEval::Float64((va as f64) / vb),
458                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb / va as f32),
459                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb / va as f32),
460                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb / va as f32),
461                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
462                    }
463                    LiveEval::Float64(va) => match b {
464                        LiveEval::Int64(vb) => LiveEval::Float64(va / vb as f64),
465                        LiveEval::Float64(vb) => LiveEval::Float64(va / vb),
466                        LiveEval::Vec2(vb) => LiveEval::Vec2(vb / va as f32),
467                        LiveEval::Vec3(vb) => LiveEval::Vec3(vb / va as f32),
468                        LiveEval::Vec4(vb) => LiveEval::Vec4(vb / va as f32),
469                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
470                    }
471                    LiveEval::Vec2(va) => match b {
472                        LiveEval::Vec2(vb) => LiveEval::Vec2(va / vb),
473                        LiveEval::Int64(vb) => LiveEval::Vec2(va / vb as f32),
474                        LiveEval::Float64(vb) => LiveEval::Vec2(va / vb as f32),
475                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
476                    }
477                    LiveEval::Vec3(va) => match b {
478                        LiveEval::Vec3(vb) => LiveEval::Vec3(va / vb),
479                        LiveEval::Int64(vb) => LiveEval::Vec3(va / vb as f32),
480                        LiveEval::Float64(vb) => LiveEval::Vec3(va / vb as f32),
481                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
482                    }
483                    LiveEval::Vec4(va) => match b {
484                        LiveEval::Vec4(vb) => LiveEval::Vec4(va / vb),
485                        LiveEval::Int64(vb) => LiveEval::Vec4(va / vb as f32),
486                        LiveEval::Float64(vb) => LiveEval::Vec4(va / vb as f32),
487                        _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
488                    } _ => return Err(LiveError::eval_error_binop_undefined_in_expression(live_error_origin!(), *index, nodes, *op, a, b))
489                },
490            }
491        }
492        _ => {
493            return Err(LiveError::eval_error_wrong_value_in_expression(live_error_origin!(), *index, nodes, ""))
494        }
495    })
496}