// © 2023 John Breaux //! A [JumpTarget] contains the [pc-relative offset](Number) or [Identifier] //! for a [Jump instruction encoding](Encoding::Jump) use super::*; /// The target of a [Jump](Encoding::Jump) #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct JumpTarget(Number); impl JumpTarget { pub fn word(&self) -> u16 { u16::from(self.0) & 0x3ff } } impl Parsable for JumpTarget { /// - Identifier /// - Number /// - Negative /// - Number fn parse<'text, T>(p: &Parser, stream: &mut T) -> Result where T: crate::TokenStream<'text> { // Try to parse a number let target = Number::parse(p, stream)?; match target.into() { i if i % 2 != 0 => Err(Error::JumpedOdd(i).context(stream.context()))?, i if (-1024..=1022).contains(&(i - 2)) => Ok(Self((target - 2) >> 1)), i => Err(Error::JumpedTooFar(i).context(stream.context()))?, } } } impl From for u16 { fn from(value: JumpTarget) -> Self { value.0.into() } } impl Display for JumpTarget { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", (1 + isize::from(self.0)) << 1) } }