midenc_hir_type/
pointer_type.rs

1use core::{fmt, str::FromStr};
2
3use super::Type;
4
5/// A pointer to an object in memory
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct PointerType {
9    /// The address space used by pointers of this type.
10    pub addrspace: AddressSpace,
11    /// The type of value located at the pointed-to address
12    pub pointee: Type,
13}
14
15impl PointerType {
16    /// Create a new byte-addressable pointer type to `pointee`
17    pub fn new(pointee: Type) -> Self {
18        Self {
19            addrspace: AddressSpace::Byte,
20            pointee,
21        }
22    }
23
24    /// Create a new pointer type to `pointee` in `addrspace`
25    pub fn new_with_address_space(pointee: Type, addrspace: AddressSpace) -> Self {
26        Self { addrspace, pointee }
27    }
28
29    /// Returns the type pointed to by pointers of this type
30    pub fn pointee(&self) -> &Type {
31        &self.pointee
32    }
33
34    /// Returns the address space of this pointer type
35    pub fn addrspace(&self) -> AddressSpace {
36        self.addrspace
37    }
38
39    /// Returns true if this pointer type represents a byte pointer
40    pub fn is_byte_pointer(&self) -> bool {
41        matches!(self.addrspace, AddressSpace::Byte)
42    }
43}
44
45impl fmt::Display for PointerType {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        use miden_formatting::prettier::PrettyPrint;
48        self.pretty_print(f)
49    }
50}
51
52impl miden_formatting::prettier::PrettyPrint for PointerType {
53    fn render(&self) -> miden_formatting::prettier::Document {
54        use miden_formatting::prettier::*;
55
56        const_text("ptr<")
57            + self.addrspace.render()
58            + const_text(", ")
59            + self.pointee.render()
60            + const_text(">")
61    }
62}
63
64/// This error is raised when parsing an [AddressSpace]
65#[derive(Debug, thiserror::Error)]
66pub enum InvalidAddressSpaceError {
67    #[error("invalid address space identifier: expected 'byte' or 'element'")]
68    InvalidId,
69}
70
71/// The address space a pointer address is evaluated in.
72#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74pub enum AddressSpace {
75    /// The pointer address is evaluated as a byte address.
76    ///
77    /// This is the default unit type for pointers in HIR.
78    #[default]
79    Byte,
80    /// The pointer address is evaluated as an element address.
81    ///
82    /// This is the unit type for native Miden VM addresses.
83    ///
84    /// All byte-addressable pointers must be converted to element pointers at runtime before
85    /// loading/storing memory.
86    Element,
87}
88
89impl fmt::Display for AddressSpace {
90    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91        use miden_formatting::prettier::PrettyPrint;
92        self.pretty_print(f)
93    }
94}
95
96impl miden_formatting::prettier::PrettyPrint for AddressSpace {
97    fn render(&self) -> miden_formatting::prettier::Document {
98        use miden_formatting::prettier::*;
99
100        match self {
101            Self::Byte => const_text("byte"),
102            Self::Element => const_text("element"),
103        }
104    }
105}
106
107impl FromStr for AddressSpace {
108    type Err = InvalidAddressSpaceError;
109
110    fn from_str(s: &str) -> Result<Self, Self::Err> {
111        match s {
112            "byte" => Ok(Self::Byte),
113            "element" => Ok(Self::Element),
114            _ => Err(InvalidAddressSpaceError::InvalidId),
115        }
116    }
117}