use crate::types::{
any, b256, dyn_array, error, int, optional, r#bool, string, tuple, vector, Type,
};
use std::fmt::{Display, Formatter, Result};
#[derive(Clone, Debug)]
pub enum IntrinsicKind {
External(ExternalIntrinsic),
Internal(InternalIntrinsic),
Error,
}
impl Display for IntrinsicKind {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::Internal(kind) => write!(f, "{kind}"),
Self::External(kind) => write!(f, "{kind}"),
Self::Error => write!(f, "error"),
}
}
}
impl IntrinsicKind {
pub fn ty(&self) -> Type {
match self {
IntrinsicKind::External(kind) => kind.ty(),
IntrinsicKind::Internal(kind) => kind.ty(),
IntrinsicKind::Error => error(),
}
}
pub fn args(&self) -> Vec<Type> {
match self {
IntrinsicKind::External(kind) => kind.args(),
IntrinsicKind::Internal(kind) => kind.args(),
IntrinsicKind::Error => vec![],
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ExternalIntrinsic {
AddressOf,
ArrayLen,
RecoverSECP256k1,
Sha256,
SizeOf,
ThisAddress,
ThisContractAddress,
VecLen,
VerifyEd25519,
}
impl Display for ExternalIntrinsic {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::AddressOf => write!(f, "__address_of"),
Self::ArrayLen => write!(f, "__len"),
Self::RecoverSECP256k1 => write!(f, "__recover_secp256k1"),
Self::Sha256 => write!(f, "__sha256"),
Self::SizeOf => write!(f, "__size_of"),
Self::ThisAddress => write!(f, "__this_address"),
Self::ThisContractAddress => write!(f, "__this_contract_address"),
Self::VecLen => write!(f, "__vec_len"),
Self::VerifyEd25519 => write!(f, "__verify_ed25519"),
}
}
}
impl ExternalIntrinsic {
pub fn args(&self) -> Vec<Type> {
match self {
Self::AddressOf => vec![
string(), ],
Self::ArrayLen => vec![dyn_array(any())],
Self::RecoverSECP256k1 => vec![
b256(), tuple(vec![b256(), b256(), int()]), ],
Self::Sha256 => vec![
any(), ],
Self::SizeOf => vec![any()],
Self::ThisAddress => vec![],
Self::ThisContractAddress => vec![],
Self::VecLen => vec![
optional(vector(any())), ],
Self::VerifyEd25519 => vec![
any(), tuple(vec![b256(), b256()]), b256(), ],
}
}
pub fn ty(&self) -> Type {
match self {
Self::AddressOf => b256(),
Self::ArrayLen => int(),
Self::RecoverSECP256k1 => tuple(vec![b256(), int()]),
Self::Sha256 => b256(),
Self::SizeOf => int(),
Self::ThisAddress => b256(),
Self::ThisContractAddress => b256(),
Self::VecLen => optional(int()),
Self::VerifyEd25519 => r#bool(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum InternalIntrinsic {
PreState,
PreStateExtern,
PostState,
PostStateExtern,
}
impl Display for InternalIntrinsic {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::PreState => write!(f, "__pre_state"),
Self::PreStateExtern => write!(f, "__pre_state_extern"),
Self::PostState => write!(f, "__post_state"),
Self::PostStateExtern => write!(f, "__post_state_extern"),
}
}
}
impl InternalIntrinsic {
pub fn args(&self) -> Vec<Type> {
match self {
Self::PreState => vec![
any(), ],
Self::PreStateExtern => vec![
b256(), any(), ],
Self::PostState => vec![
any(), ],
Self::PostStateExtern => vec![
b256(), any(), ],
}
}
pub fn ty(&self) -> Type {
match self {
Self::PreState => any(),
Self::PreStateExtern => any(),
Self::PostState => any(),
Self::PostStateExtern => any(),
}
}
}