use crate::ir::*; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub enum LValue { Variable(Variable), Dereference(Dereference), } impl LValue { pub fn variable(&self) -> Option<&Variable> { match self { LValue::Variable(variable) => Some(variable), _ => None, } } pub fn scalar(&self) -> Option<&Scalar> { self.variable().and_then(|variable| variable.scalar()) } pub fn stack_variable(&self) -> Option<&StackVariable> { self.variable() .and_then(|variable| variable.stack_variable()) } pub fn dereference(&self) -> Option<&Dereference> { match self { LValue::Dereference(dereference) => Some(dereference), _ => None, } } pub fn bits(&self) -> usize { match self { LValue::Variable(variable) => variable.bits(), LValue::Dereference(dereference) => dereference.bits(), } } } impl From> for Expression { fn from(lvalue: LValue) -> Expression { Expression::LValue(Box::new(lvalue)) } } impl From for LValue { fn from(scalar: Scalar) -> LValue { LValue::Variable(scalar.into()) } } impl fmt::Display for LValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { LValue::Variable(variable) => variable.fmt(f), LValue::Dereference(dereference) => dereference.fmt(f), } } }