mirror of
				https://github.com/rm-dr/daisy
				synced 2025-10-30 22:14:55 -07:00 
			
		
		
		
	Cleaned up evaluator
This commit is contained in:
		| @ -7,62 +7,57 @@ use super::operator::eval_operator; | ||||
| use super::function::eval_function; | ||||
| use super::EvalError; | ||||
|  | ||||
| pub fn evaluate(t: &Token, context: &Context) -> Result<Token, EvalError> { | ||||
| 	let mut g = t.clone(); | ||||
| pub fn evaluate(t: &Token, context: &mut Context) -> Result<Token, EvalError> { | ||||
|  | ||||
| 	// Keeps track of our position in the token tree. | ||||
| 	// For example, the coordinates [0, 2, 1] are interpreted as follows: | ||||
| 	// Start at the root node, | ||||
| 	//    then move to that node's 0th child, | ||||
| 	//    then move to that node's 2nd child, | ||||
| 	//    then move to that node's 1st child. | ||||
| 	// | ||||
| 	let mut coords: Vec<usize> = Vec::with_capacity(16); | ||||
| 	let mut root = t.clone(); | ||||
|  | ||||
| 	// coords points to the *next* node we will move to. | ||||
| 	coords.push(0); | ||||
|  | ||||
| 	'outer: loop { | ||||
| 		let mut h = &mut g; | ||||
| 	// Repeats while we have coordinates to parse. | ||||
| 	// Exits when we finish parsing the root node. | ||||
| 	loop { | ||||
| 		// Current position in the tree | ||||
| 		let g = root.get_at_coords_mut(&coords[0 .. coords.len() - 1]); | ||||
|  | ||||
| 		for t in coords.iter() { | ||||
| 			let inner = h.get_args_mut(); | ||||
| 		// "Move up" step. | ||||
| 		// We move up if we're at a leaf or if we're out of children to move down to. | ||||
| 		if { | ||||
| 			g.is_quantity() || | ||||
| 			g.get_args().is_none() || | ||||
| 			(coords.len() != 0 && (*coords.last().unwrap() >= g.get_args().unwrap().len())) | ||||
| 		} { | ||||
|  | ||||
| 			if inner.is_none() || *t >= inner.as_ref().unwrap().len() { | ||||
| 				coords.pop(); | ||||
| 			if !g.is_quantity() { | ||||
| 				*g = match g { | ||||
| 					Token::Quantity(_) => panic!(), | ||||
|  | ||||
|  | ||||
| 				let p = Token::get_at_coords(&mut g, &coords); | ||||
| 				let mut e = p.clone(); | ||||
|  | ||||
| 				// Evaluate until we get a single number. | ||||
| 				// This loop is necessary because some eval_* functions | ||||
| 				// May return an incomplete result. | ||||
| 				// ( For example, csc(x) is treated as 1/sin(x) ) | ||||
| 				loop { | ||||
| 					e = match e { | ||||
| 						Token::Quantity(_) => { break; }, | ||||
| 						Token::Constant(c) => { evaluate(&c.value(), context).unwrap() }, | ||||
| 						Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? }, | ||||
| 						Token::Operator(o, v) => { eval_operator(&o, &v)? }, | ||||
| 						Token::Variable(s) => { context.get_variable(&s).unwrap() } | ||||
| 					}; | ||||
| 					Token::Constant(c) => { evaluate(&c.value(), context).unwrap() }, | ||||
| 					Token::Variable(s) => { context.get_variable(&s).unwrap() }, | ||||
| 					Token::Operator(Operator::Function(f), v) => { eval_function(&f, &v)? }, | ||||
| 					Token::Operator(o, v) => { eval_operator(&o, &v, context)? }, | ||||
| 				} | ||||
|  | ||||
| 				*p = e; | ||||
|  | ||||
| 				if coords.len() == 0 { break 'outer; } | ||||
| 				let l = coords.pop().unwrap(); | ||||
| 				coords.push(l + 1); | ||||
| 				continue 'outer; | ||||
| 			} | ||||
|  | ||||
| 			h = &mut inner.unwrap()[*t]; | ||||
| 			// Move up the tree | ||||
| 			coords.pop(); | ||||
| 			if coords.len() != 0 { | ||||
| 				*coords.last_mut().unwrap() += 1; | ||||
| 			} else { break; } | ||||
|  | ||||
| 		} else { | ||||
| 			// Move down the tree | ||||
| 			coords.push(0); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		match h { | ||||
| 			Token::Operator(_,_) | ||||
| 			| Token::Constant(_) | ||||
| 			| Token::Variable(_) | ||||
| 			=> { coords.push(0); }, | ||||
|  | ||||
| 			Token::Quantity(_) => { | ||||
| 				let l = coords.pop().unwrap(); | ||||
| 				coords.push(l + 1); | ||||
| 			} | ||||
| 		}; | ||||
| 	} | ||||
|  | ||||
| 	return Ok(g); | ||||
| 	return Ok(root); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user