use crate::*; pub fn parse_constant_expression(string: &str, parent: &Tokeniser) -> ConstantExpression { use ConstantExpressionTokenVariant as TokenVar; use ConstantExpressionParseError as ParseError; let mut tokens = Vec::new(); let mut t = Tokeniser::new_child(string, parent); t.position.to_next_char(); // skip opening delimiter loop { t.drop_whitespace(); t.mark_start_position(); let token = t.eat_token(); if token.is_empty() { break; } let variant = match token.as_str() { "=" => TokenVar::Operator(Operator::Equal), "!" => TokenVar::Operator(Operator::NotEqual), "<" => TokenVar::Operator(Operator::LessThan), ">" => TokenVar::Operator(Operator::GreaterThan), "+" => TokenVar::Operator(Operator::Add), "-" => TokenVar::Operator(Operator::Subtract), "<<" => TokenVar::Operator(Operator::LeftShift), ">>" => TokenVar::Operator(Operator::RightShift), "&" => TokenVar::Operator(Operator::And), "|" => TokenVar::Operator(Operator::Or), "^" => TokenVar::Operator(Operator::Xor), "~" => TokenVar::Operator(Operator::Not), _ => if let Some(stripped) = token.strip_prefix("0x") { match usize::from_str_radix(stripped, 16) { Ok(value) => TokenVar::IntegerLiteral(value), Err(_) => TokenVar::Error( ParseError::InvalidHexadecimalLiteral(stripped.to_string())), } } else { match usize::from_str_radix(&token, 10) { Ok(value) => TokenVar::IntegerLiteral(value), Err(_) => TokenVar::SymbolReference(token.to_string()), } } }; let source = t.mark_end_position(); tokens.push(ConstantExpressionToken { source, variant }); } return ConstantExpression { tokens }; }