1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use alloc::string::String;

use super::{Block, Constant, Export, Import};
use crate::{SourceSpan, Span, Spanned};

/// This type represents the top-level forms of a Miden Assembly module
#[derive(Debug, PartialEq, Eq)]
pub enum Form {
    /// A documentation string for the entire module
    ModuleDoc(Span<String>),
    /// A documentation string
    Doc(Span<String>),
    /// An import from another module
    Import(Import),
    /// A constant definition, possibly unresolved
    Constant(Constant),
    /// An executable block, represents a program entrypoint
    Begin(Block),
    /// A procedure
    Procedure(Export),
}

impl From<Span<String>> for Form {
    fn from(doc: Span<String>) -> Self {
        Self::Doc(doc)
    }
}

impl From<Import> for Form {
    fn from(import: Import) -> Self {
        Self::Import(import)
    }
}

impl From<Constant> for Form {
    fn from(constant: Constant) -> Self {
        Self::Constant(constant)
    }
}

impl From<Block> for Form {
    fn from(block: Block) -> Self {
        Self::Begin(block)
    }
}

impl From<Export> for Form {
    fn from(export: Export) -> Self {
        Self::Procedure(export)
    }
}

impl Spanned for Form {
    fn span(&self) -> SourceSpan {
        match self {
            Self::ModuleDoc(spanned) | Self::Doc(spanned) => spanned.span(),
            Self::Import(Import { span, .. }) | Self::Constant(Constant { span, .. }) => *span,
            Self::Begin(spanned) => spanned.span(),
            Self::Procedure(spanned) => spanned.span(),
        }
    }
}