diff options
Diffstat (limited to 'src/tokens/constant_expression.rs')
-rw-r--r-- | src/tokens/constant_expression.rs | 134 |
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(()); - } -} |