use crate::semantic::{AttachLiteralId, AttachNumberId, AttachVarnodeId, VarnodeId};
use crate::{Number, NumberNonZeroUnsigned, Sleigh};
use super::inner::execution::FieldSize;
use super::{PrintBase, ValueFmt};
#[derive(Clone, Debug)]
pub struct AttachVarnode(pub Box<[(usize, VarnodeId)]>);
impl AttachVarnode {
pub fn find_value(&self, index: usize) -> Option<VarnodeId> {
self.0
.iter()
.find(|(value_index, _value)| *value_index == index)
.map(|(_, value)| *value)
}
pub fn len_bytes(&self, sleigh: &Sleigh) -> NumberNonZeroUnsigned {
sleigh.varnode(self.0[0].1).len_bytes
}
}
#[derive(Clone, Debug)]
pub struct AttachLiteral(pub Box<[(usize, String)]>);
impl AttachLiteral {
pub fn find_value(&self, index: usize) -> Option<&str> {
self.0
.iter()
.find(|(value_index, _value)| *value_index == index)
.map(|(_, value)| value.as_str())
}
}
#[derive(Clone, Debug)]
pub struct AttachNumber(pub Box<[(usize, Number)]>);
impl AttachNumber {
pub fn is_signed(&self) -> bool {
self.0.iter().any(|(_i, v)| v.is_negative())
}
pub fn find_value(&self, index: usize) -> Option<Number> {
self.0
.iter()
.find(|(value_index, _value)| *value_index == index)
.map(|(_, value)| *value)
}
pub fn bits_required(&self) -> u32 {
self.0
.iter()
.map(|(_value_index, value)| value.bits_required())
.min()
.unwrap()
}
}
#[derive(Clone, Copy, Debug)]
pub enum Meaning {
NoAttach(ValueFmt),
Varnode(AttachVarnodeId),
Literal(AttachLiteralId),
Number(PrintBase, AttachNumberId),
}
impl Meaning {
pub fn is_varnode(&self) -> bool {
matches!(self, Self::Varnode(_))
}
pub fn is_literal(&self) -> bool {
matches!(self, Self::Literal(_))
}
pub fn is_number(&self) -> bool {
matches!(self, Self::Number(_, _))
}
#[deprecated]
pub fn execution_len(&self, sleigh: &super::inner::Sleigh) -> Option<FieldSize> {
match self {
Meaning::NoAttach(_) | Meaning::Literal(_) => None,
Meaning::Varnode(vars_id) => {
let vars = sleigh.attach_varnode(*vars_id);
let varnode_bits = sleigh.varnode(vars.0[0].1).len_bytes.get() * 8;
Some(FieldSize::new_bits(varnode_bits.try_into().unwrap()))
}
Meaning::Number(_, values_id) => {
let values = sleigh.attach_number(*values_id);
let len_bits = values
.0
.iter()
.map(|(_i, v)| v.bits_required())
.max()
.unwrap();
let len_bits = NumberNonZeroUnsigned::new(len_bits.into()).unwrap();
Some(FieldSize::default().set_min_bits(len_bits).unwrap())
}
}
}
}