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