summaryrefslogtreecommitdiff
path: root/src/tokens/constant_expression.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tokens/constant_expression.rs')
-rw-r--r--src/tokens/constant_expression.rs134
1 files changed, 0 insertions, 134 deletions
diff --git a/src/tokens/constant_expression.rs b/src/tokens/constant_expression.rs
deleted file mode 100644
index e4aa099..0000000
--- a/src/tokens/constant_expression.rs
+++ /dev/null
@@ -1,134 +0,0 @@
-use crate::*;
-
-
-pub struct ConstantExpression {
- pub tokens: Vec<ConstantExpressionToken>,
-}
-
-impl ConstantExpression {
- pub fn from_str(string: &str, tokeniser: &Tokeniser) -> Self {
- parse_constant_expression(string, tokeniser)
- }
-}
-
-pub struct ConstantExpressionToken {
- pub source: SourceSpan,
- pub variant: ConstantExpressionTokenVariant,
-}
-
-pub enum ConstantExpressionTokenVariant {
- SymbolReference(String),
- IntegerLiteral(usize),
- Operator(Operator),
- Error(ConstantExpressionParseError),
-}
-
-pub enum Operator {
- Equal,
- NotEqual,
- LessThan,
- GreaterThan,
- Add,
- Subtract,
- LeftShift,
- RightShift,
- And,
- Or,
- Xor,
- Not,
-}
-
-pub enum ConstantExpressionParseError {
- InvalidHexadecimalLiteral(String),
-}
-
-
-impl ConstantExpression {
- pub fn evaluate(&self, environment: &Environment) -> Result<usize, ConstantExpressionEvaluationError> {
- use ConstantExpressionTokenVariant as Token;
- use ConstantExpressionEvaluationError as EvalErr;
-
- let mut stack = Vec::new();
- macro_rules! push {
- ($value:expr) => { stack.push($value) };
- }
- macro_rules! pop {
- ($name:ident) => { let $name = match stack.pop() {
- Some(value) => value,
- None => return Err(EvalErr::StackUnderflow),
- }; };
- }
- macro_rules! truth {
- ($bool:expr) => { match $bool { true => 1, false => 0 } };
- }
-
- for token in &self.tokens {
- match &token.variant {
- Token::IntegerLiteral(value) => push!(*value),
- Token::SymbolReference(name) => match environment.get_integer(name) {
- Ok(value) => push!(value),
- Err(_) => todo!(),
- }
- Token::Operator(operator) => match operator {
- Operator::Equal => { pop!(b); pop!(a); push!(truth!(a==b)) },
- Operator::NotEqual => { pop!(b); pop!(a); push!(truth!(a!=b)) },
- Operator::LessThan => { pop!(b); pop!(a); push!(truth!(a < b)) },
- Operator::GreaterThan => { pop!(b); pop!(a); push!(truth!(a > b)) },
- Operator::Add => { pop!(b); pop!(a); push!(a + b) },
- Operator::Subtract => { pop!(b); pop!(a); push!(a - b) },
- Operator::LeftShift => { pop!(b); pop!(a); push!(a << b) },
- Operator::RightShift => { pop!(b); pop!(a); push!(a >> b) },
- Operator::And => { pop!(b); pop!(a); push!(a & b) },
- Operator::Or => { pop!(b); pop!(a); push!(a | b) },
- Operator::Xor => { pop!(b); pop!(a); push!(a ^ b) },
- Operator::Not => { pop!(a); push!(!a) },
- }
- Token::Error(_) => (),
- }
- }
- match stack.len() {
- 0 => Err(EvalErr::NoReturnValue),
- 1 => Ok(stack[0]),
- _ => Err(EvalErr::MultipleReturnValues),
- }
- }
-}
-
-pub enum ConstantExpressionEvaluationError {
- StackUnderflow,
- MultipleReturnValues,
- NoReturnValue,
-}
-
-
-impl std::fmt::Debug for ConstantExpression {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
- use ConstantExpressionTokenVariant as TokenVar;
- for (i, token) in self.tokens.iter().enumerate() {
- let string = match &token.variant {
- TokenVar::SymbolReference(name) => name,
- TokenVar::IntegerLiteral(value) => &value.to_string(),
- TokenVar::Operator(operator) => match operator {
- Operator::Equal => "=",
- Operator::NotEqual => "!",
- Operator::LessThan => "<",
- Operator::GreaterThan => ">",
- Operator::Add => "+",
- Operator::Subtract => "-",
- Operator::LeftShift => "<<",
- Operator::RightShift => ">>",
- Operator::And => "&",
- Operator::Or => "|",
- Operator::Xor => "^",
- Operator::Not => "~",
- }
- TokenVar::Error(_) => "<error>",
- };
- match i {
- 0 => write!(f, "{string}")?,
- _ => write!(f, " {string}")?,
- }
- }
- return Ok(());
- }
-}