diff options
Diffstat (limited to 'src/parsers/constant_expression.rs')
-rw-r--r-- | src/parsers/constant_expression.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/parsers/constant_expression.rs b/src/parsers/constant_expression.rs new file mode 100644 index 0000000..78dc697 --- /dev/null +++ b/src/parsers/constant_expression.rs @@ -0,0 +1,52 @@ +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 }; +} |