midenc_codegen_masm/compiler/
mast.rs

1use std::sync::Arc;
2
3use miden_assembly::Library as CompiledLibrary;
4use miden_processor::{Digest, MastForest};
5use midenc_hir::Symbol;
6use midenc_session::{Emit, OutputMode, OutputType, Session};
7
8/// The artifact produced by lowering a [Program] to a Merkelized Abstract Syntax Tree
9///
10/// This type is used in compilation pipelines to abstract over the type of output requested.
11#[derive(Clone)]
12pub enum MastArtifact {
13    /// A MAST artifact which can be executed by the VM directly
14    Executable(Arc<miden_core::Program>),
15    /// A MAST artifact which can be used as a dependency by a [miden_core::Program]
16    Library(Arc<CompiledLibrary>),
17}
18
19impl MastArtifact {
20    pub fn unwrap_program(self) -> Arc<miden_core::Program> {
21        match self {
22            Self::Executable(prog) => prog,
23            Self::Library(_) => panic!("attempted to unwrap 'mast' library as program"),
24        }
25    }
26
27    /// Get the content digest associated with this artifact
28    pub fn digest(&self) -> Digest {
29        match self {
30            Self::Executable(ref prog) => prog.hash(),
31            Self::Library(ref lib) => *lib.digest(),
32        }
33    }
34
35    /// Get the underlying [MastForest] for this artifact
36    pub fn mast_forest(&self) -> &MastForest {
37        match self {
38            Self::Executable(ref prog) => prog.mast_forest(),
39            Self::Library(ref lib) => lib.mast_forest(),
40        }
41    }
42}
43
44impl Emit for MastArtifact {
45    fn name(&self) -> Option<Symbol> {
46        None
47    }
48
49    fn output_type(&self, mode: OutputMode) -> OutputType {
50        match mode {
51            OutputMode::Text => OutputType::Mast,
52            OutputMode::Binary => OutputType::Masl,
53        }
54    }
55
56    fn write_to<W: std::io::Write>(
57        &self,
58        writer: W,
59        mode: OutputMode,
60        session: &Session,
61    ) -> std::io::Result<()> {
62        match self {
63            Self::Executable(ref prog) => {
64                if matches!(mode, OutputMode::Binary) {
65                    log::warn!(
66                        "unable to write 'masl' output type for miden_core::Program: skipping.."
67                    );
68                }
69                prog.write_to(writer, mode, session)
70            }
71            Self::Library(ref lib) => lib.write_to(writer, mode, session),
72        }
73    }
74}