use crate::*; pub fn parse_constant_expression(mut t: Tokeniser, source: SourceSpan) -> Expression { use ExpressionTokenVariant as TokenVar; use ExpressionParseError as ParseError; let mut tokens = Vec::new(); loop { t.eat_whitespace(); t.mark_start(); 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::Literal(value as isize), Err(_) => TokenVar::Error( ParseError::InvalidHexadecimalLiteral(stripped.to_string())), } } else { match usize::from_str_radix(&token, 10) { Ok(value) => TokenVar::Literal(value as isize), Err(_) => TokenVar::Invocation(token.to_string()), } } }; let source = t.get_source(); tokens.push(ExpressionToken { source, variant }); } return Expression { source, tokens }; }