summaryrefslogtreecommitdiff
path: root/src/parsers/expression.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parsers/expression.rs')
-rw-r--r--src/parsers/expression.rs50
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 };
+}