use alloc::sync::Arc;
use core::fmt;
use miden_debug_types::{SourceSpan, Span, Spanned};
use crate::{Path, Word, ast::Ident};
#[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>),
Symbol(Ident),
Path(Span<Arc<Path>>),
}
impl InvocationTarget {
pub fn unwrap_path(&self) -> &Path {
match self {
Self::Symbol(name) => name.as_ref(),
Self::Path(path) => path.inner().as_ref(),
Self::MastRoot(_) => panic!("expected invocation target to be a path"),
}
}
}
impl Spanned for InvocationTarget {
fn span(&self) -> SourceSpan {
match self {
Self::MastRoot(spanned) => spanned.span(),
Self::Symbol(spanned) => spanned.span(),
Self::Path(spanned) => spanned.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::Symbol(name) => display(name),
Self::Path(path) => display(path),
}
}
}
impl fmt::Display for InvocationTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::prettier::PrettyPrint;
self.pretty_print(f)
}
}