#![deny(missing_docs)]
use crate::{impl_table_key, ty::Type};
mod cfg;
mod dfg;
mod inst;
mod layout;
mod module;
pub mod prelude;
mod sig;
mod unit;
use self::cfg::*;
use self::dfg::*;
pub use self::inst::*;
use self::layout::*;
pub use self::module::*;
pub use self::sig::*;
pub use self::unit::*;
impl_table_key! {
struct Inst(u32) as "i";
struct Value(u32) as "v";
struct Block(u32) as "bb";
struct Arg(u32) as "arg";
struct ExtUnit(u32) as "ext";
}
impl Value {
pub(crate) fn invalid() -> Self {
Value(std::u32::MAX)
}
pub fn is_invalid(&self) -> bool {
self.0 == std::u32::MAX
}
}
impl Block {
pub(crate) fn invalid() -> Self {
Block(std::u32::MAX)
}
pub fn is_invalid(&self) -> bool {
self.0 == std::u32::MAX
}
}
#[allow(missing_docs)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum ValueData {
Invalid,
Inst { ty: Type, inst: Inst },
Arg { ty: Type, arg: Arg },
Placeholder { ty: Type },
}
impl ValueData {
pub fn is_placeholder(&self) -> bool {
match self {
ValueData::Placeholder { .. } => true,
_ => false,
}
}
}
impl Default for ValueData {
fn default() -> ValueData {
ValueData::Invalid
}
}
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct BlockData {
pub name: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ExtUnitData {
pub name: UnitName,
pub sig: Signature,
}
impl Default for ExtUnitData {
fn default() -> ExtUnitData {
ExtUnitData {
name: UnitName::Anonymous(0),
sig: Signature::default(),
}
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum AnyObject {
Inst(Inst),
Value(Value),
Block(Block),
Arg(Arg),
}
impl From<Inst> for AnyObject {
fn from(x: Inst) -> Self {
AnyObject::Inst(x)
}
}
impl From<Value> for AnyObject {
fn from(x: Value) -> Self {
AnyObject::Value(x)
}
}
impl From<Block> for AnyObject {
fn from(x: Block) -> Self {
AnyObject::Block(x)
}
}
impl From<Arg> for AnyObject {
fn from(x: Arg) -> Self {
AnyObject::Arg(x)
}
}
impl std::fmt::Display for AnyObject {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
AnyObject::Inst(x) => write!(f, "{}", x),
AnyObject::Value(x) => write!(f, "{}", x),
AnyObject::Block(x) => write!(f, "{}", x),
AnyObject::Arg(x) => write!(f, "{}", x),
}
}
}
impl Value {
pub fn dump<'a>(self, unit: &Unit<'a>) -> ValueDumper<'a> {
ValueDumper(self, *unit)
}
}
pub struct ValueDumper<'a>(Value, Unit<'a>);
impl std::fmt::Display for ValueDumper<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.0.is_invalid() {
write!(f, "%<invalid>")
} else if let Some(name) = self.1.get_name(self.0) {
write!(f, "%{}", name)
} else if let Some(index) = self.1.get_anonymous_hint(self.0) {
write!(f, "%{}", index)
} else {
write!(f, "%{}", self.0)
}
}
}
impl Block {
pub fn dump<'a>(self, unit: &Unit<'a>) -> BlockDumper<'a> {
BlockDumper(self, *unit)
}
}
pub struct BlockDumper<'a>(Block, Unit<'a>);
impl std::fmt::Display for BlockDumper<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.0.is_invalid() {
write!(f, "<invalid>")
} else if let Some(name) = self.1.get_block_name(self.0) {
write!(f, "{}", name)
} else if let Some(index) = self.1.get_anonymous_block_hint(self.0) {
write!(f, "{}", index)
} else {
write!(f, "{}", self.0)
}
}
}