2024-01-18 22:09:11 +01:00
|
|
|
//! Instance identification for instructions and their glue.
|
|
|
|
//!
|
|
|
|
//! Instructions as defined in [`crate::instruction::Kind`] and descendants are very useful,
|
|
|
|
//! but they cannot be directly used as vertices in the graph IR,
|
|
|
|
//! as there may easily be multiple instructions of the same kind in the same program.
|
|
|
|
//!
|
|
|
|
//! Instead, this module offers an alternative way to refer to specific instances:
|
|
|
|
//!
|
2024-01-19 14:26:20 +01:00
|
|
|
//! - [`Instruction`]s are effectively just a number floating in space,
|
|
|
|
//! incremented each time a new instruction is referred to.
|
2024-01-18 22:09:11 +01:00
|
|
|
//! - [`Socket`]s contain
|
|
|
|
//! - what [`Instruction`] they belong to
|
|
|
|
//! - which index they occupy on it
|
|
|
|
//!
|
|
|
|
//! The distinction between [`Input`] and [`Output`] is implemented
|
|
|
|
//! as them being different types.
|
|
|
|
|
2024-01-20 17:59:21 +01:00
|
|
|
use std::fmt;
|
|
|
|
|
2024-01-18 22:09:11 +01:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2024-01-19 14:26:20 +01:00
|
|
|
/// One specific instruction.
|
2024-01-18 22:09:11 +01:00
|
|
|
///
|
|
|
|
/// It does **not** contain what kind of instruction this is.
|
|
|
|
/// Refer to [`crate::instruction::Kind`] for this instead.
|
2024-01-20 17:59:21 +01:00
|
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
2024-01-19 14:26:20 +01:00
|
|
|
pub struct Instruction(pub(super) u64);
|
2024-01-18 22:09:11 +01:00
|
|
|
|
2024-01-20 17:59:21 +01:00
|
|
|
impl fmt::Debug for Instruction {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "InstrId {}", self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-18 22:09:11 +01:00
|
|
|
/// On an **instruction**, accepts incoming data.
|
|
|
|
///
|
|
|
|
/// An **instruction** cannot run if any of these are not connected.
|
2024-01-19 00:45:01 +01:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
2024-01-18 22:09:11 +01:00
|
|
|
pub struct Input(pub(super) Socket);
|
|
|
|
|
2024-01-19 00:45:01 +01:00
|
|
|
impl Input {
|
|
|
|
#[must_use]
|
|
|
|
pub fn socket(&self) -> &Socket {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-18 22:09:11 +01:00
|
|
|
/// On an **instruction**, returns outgoing data to be fed to [`Input`]s.
|
|
|
|
///
|
|
|
|
/// In contrast to [`Input`]s, [`Output`]s may be used or unused.
|
2024-01-19 00:45:01 +01:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
2024-01-21 04:21:33 +01:00
|
|
|
pub struct Output(pub Socket); // TODO: Restrict publicness to super
|
2024-01-18 22:09:11 +01:00
|
|
|
|
2024-01-19 00:45:01 +01:00
|
|
|
impl Output {
|
|
|
|
#[must_use]
|
|
|
|
pub fn socket(&self) -> &Socket {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-18 22:09:11 +01:00
|
|
|
/// An unspecified socket on a specific **instruction**,
|
|
|
|
/// and where it is on that **instruction**.
|
2024-01-19 00:45:01 +01:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
2024-01-18 22:09:11 +01:00
|
|
|
pub struct Socket {
|
|
|
|
pub belongs_to: Instruction,
|
|
|
|
pub idx: SocketIdx,
|
|
|
|
}
|
|
|
|
|
2024-01-19 14:34:00 +01:00
|
|
|
/// Where a [`Socket`] is on one **instruction**.
|
|
|
|
///
|
|
|
|
/// Note that this does **not** identify a [`Socket`] globally.
|
|
|
|
/// There may be multiple [`Socket`]s sharing the same [`SocketIdx`],
|
|
|
|
/// but on different [`Instruction`]s.
|
|
|
|
///
|
|
|
|
/// This really only serves for denoting where a socket is,
|
|
|
|
/// when it's already clear which instruction is referred to.
|
2024-01-20 17:59:21 +01:00
|
|
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
2024-01-21 04:21:33 +01:00
|
|
|
pub struct SocketIdx(pub u16); // TODO: Restrict publicness to super
|
2024-01-20 17:59:21 +01:00
|
|
|
|
|
|
|
impl fmt::Debug for SocketIdx {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
self.0.fmt(f)
|
|
|
|
}
|
|
|
|
}
|