use crate::ir::*; use falcon::il; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct Instruction { index: usize, operation: Operation, address: Option, comment: Option, } impl Instruction { pub fn new(index: usize, operation: Operation, address: Option) -> Instruction { Instruction { index, operation, address, comment: None, } } pub fn from_il(instruction: &il::Instruction) -> Instruction { Instruction { index: instruction.index(), operation: Operation::::from_il(instruction.operation()), address: instruction.address(), comment: None, } } pub fn index(&self) -> usize { self.index } pub fn operation(&self) -> &Operation { &self.operation } pub fn operation_mut(&mut self) -> &mut Operation { &mut self.operation } pub fn set_operation(&mut self, operation: Operation) { self.operation = operation; } pub fn address(&self) -> Option { self.address } pub fn comment(&self) -> Option<&str> { self.comment.as_deref() } pub fn set_comment(&mut self, comment: Option) { self.comment = comment; } pub fn expressions(&self) -> Vec<&Expression> { self.operation.expressions() } pub fn expressions_mut(&mut self) -> Vec<&mut Expression> { self.operation.expressions_mut() } pub fn variables_read(&self) -> Option> { self.operation().variables_read() } pub fn variables_written(&self) -> Option> { self.operation().variables_written() } pub fn variables(&self) -> Option> { self.operation.variables() } } impl fmt::Display for Instruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let comment = self .comment() .map(|comment| format!(" // {}", comment)) .unwrap_or_default(); match self.address() { Some(address) => write!( f, "{:X} {:02X} {}{}", address, self.index(), self.operation(), comment ), None => write!(f, "{:02X} {}{}", self.index(), self.operation(), comment), } } }