use core::fmt;
macro_rules! entity {
($(#[$doc:meta])* $name:ident, $prefix:literal, $example:literal) => {
$(#[$doc])*
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct $name(u32);
impl $name {
#[doc = concat!("use backend_lang::mir::", stringify!($name), ";")]
#[doc = concat!("assert_eq!(", stringify!($name), "::new(3).index(), 3);")]
#[inline]
#[must_use]
pub const fn new(index: u32) -> $name {
$name(index)
}
#[doc = $example]
#[inline]
#[must_use]
pub const fn index(self) -> usize {
self.0 as usize
}
#[allow(dead_code, reason = "not every id type is built from a length")]
pub(crate) const fn from_index(index: usize) -> $name {
$name(index as u32)
}
}
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, concat!($prefix, "{}"), self.0)
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, concat!($prefix, "{}"), self.0)
}
}
};
}
entity!(
Block,
"block",
"use backend_lang::mir::Function;\nuse backend_lang::x86_64::SYSV;\nlet mut f = Function::new(\"f\", &SYSV);\nlet _ = f.block()?;\nassert_eq!(f.block()?.index(), 1);\n# Ok::<(), backend_lang::mir::MirError>(())"
);
entity!(
Inst,
"inst",
"use backend_lang::mir::Function;\nuse backend_lang::x86_64::{op, SYSV};\nlet mut f = Function::new(\"f\", &SYSV);\nlet b = f.block()?;\nassert_eq!(f.push(b, op::RET, &[])?.index(), 0);\n# Ok::<(), backend_lang::mir::MirError>(())"
);
entity!(
StackSlot,
"ss",
"use backend_lang::mir::{Function, SlotKind};\nuse backend_lang::x86_64::SYSV;\nlet mut f = Function::new(\"f\", &SYSV);\nlet s = f.stack_slot(SlotKind::Local { size: 8, align: 8 })?;\nassert_eq!(s.index(), 0);\n# Ok::<(), backend_lang::mir::MirError>(())"
);
entity!(
Symbol,
"sym",
"use backend_lang::mir::Function;\nuse backend_lang::x86_64::SYSV;\nlet mut f = Function::new(\"f\", &SYSV);\nassert_eq!(f.symbol(\"g\")?.index(), 0);\n# Ok::<(), backend_lang::mir::MirError>(())"
);
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct CondCode(u8);
impl CondCode {
#[inline]
#[must_use]
pub const fn new(code: u8) -> CondCode {
CondCode(code)
}
#[inline]
#[must_use]
pub const fn code(self) -> u8 {
self.0
}
}