miden_assembly_syntax/ast/constants/
mod.rs

1pub mod eval;
2mod expr;
3mod value;
4
5use alloc::string::String;
6use core::fmt;
7
8use miden_debug_types::{SourceSpan, Span, Spanned};
9
10pub use self::{
11    eval::{ConstEnvironment, ConstEvalError},
12    expr::{ConstantExpr, ConstantOp, HashKind},
13    value::ConstantValue,
14};
15use crate::ast::{DocString, Ident, Visibility};
16
17// CONSTANT
18// ================================================================================================
19
20/// Represents a constant definition in Miden Assembly syntax, i.e. `const.FOO = 1 + 1`.
21#[derive(Clone)]
22pub struct Constant {
23    /// The source span of the definition.
24    pub span: SourceSpan,
25    /// The documentation string attached to this definition.
26    pub docs: Option<DocString>,
27    /// The visibility of this constant
28    pub visibility: Visibility,
29    /// The name of the constant.
30    pub name: Ident,
31    /// The expression associated with the constant.
32    pub value: ConstantExpr,
33}
34
35impl Constant {
36    /// Creates a new [Constant] from the given source span, name, and value.
37    pub fn new(span: SourceSpan, visibility: Visibility, name: Ident, value: ConstantExpr) -> Self {
38        Self {
39            span,
40            docs: None,
41            visibility,
42            name,
43            value,
44        }
45    }
46
47    /// Adds documentation to this constant declaration.
48    pub fn with_docs(mut self, docs: Option<Span<String>>) -> Self {
49        self.docs = docs.map(DocString::new);
50        self
51    }
52
53    /// Returns the documentation associated with this item.
54    pub fn docs(&self) -> Option<Span<&str>> {
55        self.docs.as_ref().map(|docstring| docstring.as_spanned_str())
56    }
57
58    /// Get the name of this constant
59    pub fn name(&self) -> &Ident {
60        &self.name
61    }
62}
63
64impl fmt::Debug for Constant {
65    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66        f.debug_struct("Constant")
67            .field("docs", &self.docs)
68            .field("visibility", &self.visibility)
69            .field("name", &self.name)
70            .field("value", &self.value)
71            .finish()
72    }
73}
74
75impl crate::prettier::PrettyPrint for Constant {
76    fn render(&self) -> crate::prettier::Document {
77        use crate::prettier::*;
78
79        let mut doc = self
80            .docs
81            .as_ref()
82            .map(|docstring| docstring.render())
83            .unwrap_or(Document::Empty);
84
85        doc += flatten(const_text("const") + const_text(" ") + display(&self.name));
86        doc += const_text(" = ");
87
88        doc + self.value.render() + nl()
89    }
90}
91
92impl Eq for Constant {}
93
94impl PartialEq for Constant {
95    fn eq(&self, other: &Self) -> bool {
96        self.name == other.name && self.value == other.value
97    }
98}
99
100impl Spanned for Constant {
101    fn span(&self) -> SourceSpan {
102        self.span
103    }
104}
105
106impl From<ConstantValue> for ConstantExpr {
107    fn from(value: ConstantValue) -> Self {
108        match value {
109            ConstantValue::Int(value) => Self::Int(value),
110            ConstantValue::String(value) => Self::String(value),
111            ConstantValue::Word(value) => Self::Word(value),
112            ConstantValue::Hash(kind, value) => Self::Hash(kind, value),
113        }
114    }
115}