#![deny(missing_docs)]
mod cancun;
mod shanghai;
pub use cancun::Cancun;
pub use shanghai::ShangHai;
#[macro_export]
macro_rules! opcodes {
($name:ident, $desc:literal) => {
#[doc = $desc]
$name
};
{
$version:ident,
$((
$opcode:expr,
$name:ident,
$gas:expr,
$input:expr,
$output:expr,
$desc:literal,
$since:ident,
$group:ident
)),+
} => {
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum $version {
#[cfg(feature = "data")]
Data(u8),
$(
#[doc = concat!(" ", $desc)]
$name,
)*
}
impl From<u8> for $version {
fn from(value: u8) -> Self {
match value {
$(
$opcode => Self::$name,
)*
_ => unreachable!("Invalid opcode."),
}
}
}
impl From<$version> for u8 {
fn from(version: $version) -> Self {
match version {
#[cfg(feature = "data")]
$version::Data(data) => data,
$(
$version::$name => $opcode,
)*
}
}
}
impl OpCode for $version {
fn group(&self) -> Group {
match self {
#[cfg(feature = "data")]
Self::Data(_) => Group::StopArithmetic,
$(
Self::$name => Group::$group,
)*
}
}
fn gas(&self) -> u16 {
match self {
#[cfg(feature = "data")]
Self::Data(_) => 0,
$(
Self::$name => $gas,
)*
}
}
fn since(&self) -> Upgrade {
match self {
#[cfg(feature = "data")]
Self::Data(_) => Upgrade::Shanghai,
$(
Self::$name => Upgrade::$since,
)*
}
}
fn stack_in(&self) -> u16 {
match self {
#[cfg(feature = "data")]
Self::Data(_) => 0,
$(
Self::$name => $input,
)*
}
}
fn stack_out(&self) -> u16 {
match self {
#[cfg(feature = "data")]
Self::Data(_) => 0,
$(
Self::$name => $output,
)*
}
}
}
impl core::str::FromStr for $version {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
paste::paste! {
match s {
$(
stringify!([< $name:lower >]) => Ok(Self::$name),
)*
_ => Err(()),
}
}
}
}
paste::paste! {
#[doc = concat!(" For each ", stringify!($version), " operator.")]
#[macro_export]
macro_rules! [<for_each_ $version:lower _operator>] {
($mac:ident) => {
$mac! {
$([<_ $name:lower>] => $name),+
}
}
}
}
};
}
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum Group {
StopArithmetic,
ComparisonBitwiseLogic,
Sha3,
EnvironmentalInformation,
BlockInformation,
StackMemoryStorageFlow,
Push,
Duplication,
Exchange,
Logging,
System,
}
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum Upgrade {
Frontier,
Byzantium,
Constantinople,
Istanbul,
Berlin,
London,
Shanghai,
Cancun,
}
pub trait OpCode: From<u8> + Into<u8> {
fn stack_in(&self) -> u16;
fn stack_out(&self) -> u16;
fn since(&self) -> Upgrade;
fn group(&self) -> Group;
fn gas(&self) -> u16;
}