use core::fmt;
use miden_debug_types::{SourceSpan, Span, Spanned};
use crate::{
LibraryPath, Word,
ast::{Ident, ProcedureName},
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
pub enum InvokeKind {
Exec = 0,
Call,
SysCall,
ProcRef,
}
impl fmt::Display for InvokeKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Exec => f.write_str("exec"),
Self::Call => f.write_str("call"),
Self::SysCall => f.write_str("syscall"),
Self::ProcRef => f.write_str("procref"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Invoke {
pub kind: InvokeKind,
pub target: InvocationTarget,
}
impl Spanned for Invoke {
fn span(&self) -> SourceSpan {
self.target.span()
}
}
impl Invoke {
pub fn new(kind: InvokeKind, target: InvocationTarget) -> Self {
Self { kind, target }
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum InvocationTarget {
MastRoot(Span<Word>),
ProcedureName(ProcedureName),
ProcedurePath { name: ProcedureName, module: Ident },
AbsoluteProcedurePath { name: ProcedureName, path: LibraryPath },
}
impl Spanned for InvocationTarget {
fn span(&self) -> SourceSpan {
match self {
Self::MastRoot(spanned) => spanned.span(),
Self::ProcedureName(spanned) => spanned.span(),
Self::ProcedurePath { name, .. } | Self::AbsoluteProcedurePath { name, .. } => {
name.span()
},
}
}
}
impl crate::prettier::PrettyPrint for InvocationTarget {
fn render(&self) -> crate::prettier::Document {
use miden_core::utils::DisplayHex;
use crate::prettier::*;
match self {
Self::MastRoot(digest) => display(DisplayHex(digest.as_bytes().as_slice())),
Self::ProcedureName(name) => display(name),
Self::ProcedurePath { name, module } => display(format_args!("{module}::{name}")),
Self::AbsoluteProcedurePath { name, path } => display(format_args!("::{path}::{name}")),
}
}
}
impl fmt::Display for InvocationTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::prettier::PrettyPrint;
self.pretty_print(f)
}
}