fn shunting_yard(&self, prec_props_fn: &dyn Fn(&Token) -> OpTokenProps) -> Vec<&Token> {
		let mut output_queue: Vec<&Token> = vec![];
		let mut operator_stack: Vec<&Token> = vec![];

		let tokens: &[Token] = &self.0;

		for token in tokens {
			match token {
				Token::Number(_) => output_queue.push(token),
				// no impl for functions
				Token::OpenParen => operator_stack.push(token),
				Token::CloseParen => {
					while operator_stack.last().unwrap() != &&Token::OpenParen {
						output_queue.push(operator_stack.pop().unwrap())
					}

					if let Some(Token::OpenParen) = operator_stack.last() {
						let _ = operator_stack.pop();
					}

					// no function tokens
				}
				// token is an operator!
				_ => {
					fn should_pop(
						token: &Token,
						last: Option<&&Token>,
						prec_props_fn: &dyn Fn(&Token) -> OpTokenProps,
					) -> bool {
						match last {
							Some(Token::Asterisk) | Some(Token::Plus) | Some(Token::OpenParen) => {
								let token_props = prec_props_fn(token);
								let last_props = prec_props_fn(last.unwrap());

								// While:
								// - There is an operator at the top of the stack, AND
								// - The operator at the top of the operator stack has greater precedence than the token, OR
								//   - The operator at the top
								((last_props.precedence > token_props.precedence)
									|| (last_props.precedence == token_props.precedence
										&& token_props.left_associative))
									&& last != Some(&&Token::OpenParen)
							}
							_ => false,
						}
					}

					while should_pop(token, operator_stack.last(), prec_props_fn) {
						output_queue.push(operator_stack.pop().unwrap())
					}

					operator_stack.push(token)
				}
			}
		}

		while !operator_stack.is_empty() {
			output_queue.push(operator_stack.pop().unwrap())
		}

		assert!(operator_stack.is_empty());

		output_queue
	}
/// Perform the Shunting Yard Algorithm on the stream of tokens `tokens` using a precedence map function.
///
/// # Arguments
///
/// - `prec_props_fn` - an ideally `const fn` that takes a token and returns its precedence properties;
///   will only be called on operators.
Perform the Shunting Yard Algorithm on the stream of tokens `tokens` using a precedence map function.
Perform the Shunting Yard Algorithm on the stream of tokens ` tokens ` using a precedence map function .
fn shunting_yard(&self, prec_props_fn: &dyn Fn(&Token) -> OpTokenProps) -> Vec<&Token> {
		let mut output_queue: Vec<&Token> = vec![];
		let mut operator_stack: Vec<&Token> = vec![];
		let tokens: &[Token] = &self.0;
		for token in tokens {
			match token {
				Token::Number(_) => output_queue.push(token),
				// no impl for functions
				Token::OpenParen => operator_stack.push(token),
				Token::CloseParen => {
					while operator_stack.last().unwrap() != &&Token::OpenParen {
						output_queue.push(operator_stack.pop().unwrap())
					}
					if let Some(Token::OpenParen) = operator_stack.last() {
						let _ = operator_stack.pop();
					}
					// no function tokens
				}
				// token is an operator!
				_ => {
					fn should_pop(
						token: &Token,
						last: Option<&&Token>,
						prec_props_fn: &dyn Fn(&Token) -> OpTokenProps,
					) -> bool {
						match last {
							Some(Token::Asterisk) | Some(Token::Plus) | Some(Token::OpenParen) => {
								let token_props = prec_props_fn(token);
								let last_props = prec_props_fn(last.unwrap());
								// While:
								// - There is an operator at the top of the stack, AND
								// - The operator at the top of the operator stack has greater precedence than the token, OR
								//   - The operator at the top
								((last_props.precedence > token_props.precedence)
									|| (last_props.precedence == token_props.precedence
										&& token_props.left_associative))
									&& last != Some(&&Token::OpenParen)
							}
							_ => false,
						}
					}
					while should_pop(token, operator_stack.last(), prec_props_fn) {
						output_queue.push(operator_stack.pop().unwrap())
					}
					operator_stack.push(token)
				}
			}
		}
		while !operator_stack.is_empty() {
			output_queue.push(operator_stack.pop().unwrap())
		}
		assert!(operator_stack.is_empty());
		output_queue
	}
fn shunting_yard ( & self , prec_props_fn : & dyn Fn ( & Token ) -> OpTokenProps ) -> Vec < & Token > { let mut output_queue : Vec < & Token > = vec ! [ ] ; let mut operator_stack : Vec < & Token > = vec ! [ ] ; let tokens : & [ Token ] = & self . 0 ; for token in tokens { match token { Token :: Number ( _ ) => output_queue . push ( token ) , // no impl for functions Token :: OpenParen => operator_stack . push ( token ) , Token :: CloseParen => { while operator_stack . last ( ) . unwrap ( ) != & & Token :: OpenParen { output_queue . push ( operator_stack . pop ( ) . unwrap ( ) ) } if let Some ( Token :: OpenParen ) = operator_stack . last ( ) { let _ = operator_stack . pop ( ) ; } // no function tokens } // token is an operator! _ => { fn should_pop ( token : & Token , last : Option < & & Token > , prec_props_fn : & dyn Fn ( & Token ) -> OpTokenProps , ) -> bool { match last { Some ( Token :: Asterisk ) | Some ( Token :: Plus ) | Some ( Token :: OpenParen ) => { let token_props = prec_props_fn ( token ) ; let last_props = prec_props_fn ( last . unwrap ( ) ) ; // While: // - There is an operator at the top of the stack, AND // - The operator at the top of the operator stack has greater precedence than the token, OR //   - The operator at the top ( ( last_props . precedence > token_props . precedence ) || ( last_props . precedence == token_props . precedence && token_props . left_associative ) ) && last != Some ( & & Token :: OpenParen ) } _ => false , } } while should_pop ( token , operator_stack . last ( ) , prec_props_fn ) { output_queue . push ( operator_stack . pop ( ) . unwrap ( ) ) } operator_stack . push ( token ) } } } while ! operator_stack . is_empty ( ) { output_queue . push ( operator_stack . pop ( ) . unwrap ( ) ) } assert ! ( operator_stack is_empty ( ) ) ; output_queue }
Perform the Shunting Yard Algorithm on the stream of tokens `tokens` using a precedence map function.
Perform the Shunting Yard Algorithm on the stream of tokens ` tokens ` using a precedence map function .
&self
prec_props_fn
&dyn Fn(&Token) -> OpTokenProps
&self
prec_props_fn
&dyn Fn(&Token) -> OpTokenProps
an ideally `const fn` that takes a token and returns its precedence properties;
will only be called on operators.
an ideally ` const fn ` that takes a token and returns its precedence properties ; will only be called on operators .