daisy/src/evaluate.rs

62 lines
1.0 KiB
Rust
Raw Normal View History

2023-03-27 09:47:02 -07:00
use crate::tokens::Token;
2023-03-24 13:16:58 -07:00
2023-03-24 13:18:56 -07:00
#[inline(always)]
2023-03-24 13:16:58 -07:00
fn get_at_coords<'a>(g: &'a mut Token, coords: &Vec<usize>) -> &'a mut Token {
let mut h = &mut *g;
for t in coords.iter() {
2023-03-25 09:40:08 -07:00
let inner = h.get_args().unwrap();
2023-03-24 13:16:58 -07:00
h = &mut inner[*t];
}
return h;
}
2023-03-27 09:47:02 -07:00
pub fn evaluate(
2023-03-24 13:16:58 -07:00
mut g: Token,
2023-03-27 09:47:02 -07:00
) -> Result<Token, ()> {
2023-03-24 13:16:58 -07:00
let mut coords: Vec<usize> = Vec::with_capacity(16);
coords.push(0);
'outer: loop {
let mut h = &mut g;
for t in coords.iter() {
2023-03-25 09:40:08 -07:00
let inner = h.get_args();
2023-03-24 13:16:58 -07:00
2023-03-25 09:27:15 -07:00
if inner.is_none() || *t >= inner.as_ref().unwrap().len() {
2023-03-24 13:16:58 -07:00
coords.pop();
let p = get_at_coords(&mut g, &coords);
let e = p.eval();
*p = e;
2023-03-27 21:22:29 -07:00
if coords.len() == 0 { break 'outer; }
2023-03-24 13:16:58 -07:00
let l = coords.pop().unwrap();
coords.push(l + 1);
continue 'outer;
}
2023-03-25 09:27:15 -07:00
h = &mut inner.unwrap()[*t];
2023-03-24 13:16:58 -07:00
}
match h {
2023-03-27 21:22:29 -07:00
Token::Operator(_,_,_)
2023-03-24 13:16:58 -07:00
=> {
coords.push(0);
continue 'outer;
},
2023-03-24 20:21:48 -07:00
Token::Constant(_,_,_) |
2023-03-24 13:16:58 -07:00
Token::Number(_,_) => {
let l = coords.pop().unwrap();
coords.push(l + 1);
continue 'outer;
}
};
}
return Ok(g);
}