Skip to main content

t_ree/
types.rs

1/// Integer signedness.
2#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3pub enum Signedness {
4    /// Signed integer.
5    Signed,
6    /// Unsigned integer.
7    Unsigned,
8}
9
10/// Integer bit width.
11#[derive(Copy, Clone, Debug, PartialEq, Eq)]
12pub enum IntWidth {
13    /// 8-bit.
14    W8,
15    /// 16-bit.
16    W16,
17    /// 32-bit.
18    W32,
19    /// 64-bit.
20    W64,
21    /// 128-bit.
22    W128,
23    /// Platform-dependent (`size_t`).
24    WSize,
25}
26
27impl IntWidth {
28    /// Returns the size in bytes.
29    pub fn byte_size(self) -> usize {
30        match self {
31            Self::W8 => 1,
32            Self::W16 => 2,
33            Self::W32 => 4,
34            Self::W64 | Self::WSize => 8,
35            Self::W128 => 16,
36        }
37    }
38
39    /// Returns the size in bits.
40    pub fn bit_size(self) -> usize {
41        self.byte_size() * 8
42    }
43}
44
45/// Float bit width.
46#[derive(Copy, Clone, Debug, PartialEq, Eq)]
47pub enum FloatWidth {
48    /// 32-bit (single precision).
49    W32,
50    /// 64-bit (double precision).
51    W64,
52}
53
54impl FloatWidth {
55    /// Returns the size in bytes.
56    pub fn byte_size(self) -> usize {
57        use FloatWidth::*;
58        match self {
59            W32 => 4,
60            W64 => 8,
61        }
62    }
63}
64
65/// Pointer/reference mutability.
66#[derive(Copy, Clone, Debug, PartialEq, Eq)]
67pub enum Mutability {
68    /// Immutable/shared access.
69    Shared,
70    /// Mutable/exclusive access.
71    Mutable,
72}
73
74/// Function type signature with parameter types and return type.
75#[derive(Clone, Debug, PartialEq, Eq)]
76pub struct FunctionSignature {
77    /// Parameter types.
78    pub parameters: Vec<Type>,
79    /// Return type.
80    pub return_type: Box<Type>,
81}
82
83/// A resolved type in the AST.
84#[derive(Clone, Debug, PartialEq, Eq)]
85pub enum Type {
86    /// Diverging type (never returns).
87    Never,
88    /// Boolean.
89    Bool,
90    /// Integer with width and signedness.
91    Int(IntWidth, Signedness),
92    /// Floating-point with width.
93    Float(FloatWidth),
94    /// Pointer with mutability and pointee type.
95    Pointer(Mutability, Box<Self>),
96    /// Fixed-size array with element type and length.
97    Array(Box<Self>, usize),
98    /// SIMD vector with element type and lane count.
99    Vector(Box<Self>, usize),
100    /// Slice with mutability and element type.
101    Slice(Mutability, Box<Self>),
102    /// Tuple of types (product/AND type).
103    Tuple(Vec<Self>),
104    /// Enum of variant types (sum/OR type).
105    Enum(Vec<Self>),
106    /// Named/user-defined type.
107    Named(String),
108    /// Function pointer type.
109    Function(FunctionSignature),
110}
111
112impl Type {
113    /// Returns the unit type (empty tuple).
114    pub fn unit() -> Self {
115        Self::Tuple(Vec::new())
116    }
117
118    /// Returns true if this is the unit type.
119    pub fn is_unit(&self) -> bool {
120        matches!(self, Self::Tuple(fields) if fields.is_empty())
121    }
122
123    /// Returns true if this type matches the given primitive type name.
124    pub fn matches_name(&self, name: &str) -> bool {
125        match self {
126            Self::Named(type_name) => type_name == name,
127            Self::Bool => name == "bool",
128            Self::Int(IntWidth::W8, Signedness::Signed) => name == "i8",
129            Self::Int(IntWidth::W16, Signedness::Signed) => name == "i16",
130            Self::Int(IntWidth::W32, Signedness::Signed) => name == "i32",
131            Self::Int(IntWidth::W64, Signedness::Signed) => name == "i64",
132            Self::Int(IntWidth::W128, Signedness::Signed) => name == "i128",
133            Self::Int(IntWidth::W8, Signedness::Unsigned) => name == "u8",
134            Self::Int(IntWidth::W16, Signedness::Unsigned) => name == "u16",
135            Self::Int(IntWidth::W32, Signedness::Unsigned) => name == "u32",
136            Self::Int(IntWidth::W64, Signedness::Unsigned) => name == "u64",
137            Self::Int(IntWidth::W128, Signedness::Unsigned) => name == "u128",
138            Self::Int(IntWidth::WSize, Signedness::Signed) => name == "isize",
139            Self::Int(IntWidth::WSize, Signedness::Unsigned) => name == "usize",
140            Self::Float(FloatWidth::W32) => name == "f32",
141            Self::Float(FloatWidth::W64) => name == "f64",
142            _ => false,
143        }
144    }
145}
146
147impl std::fmt::Display for Type {
148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149        match self {
150            Self::Never => write!(f, "never"),
151            Self::Bool => write!(f, "bool"),
152            Self::Int(IntWidth::W8, Signedness::Signed) => write!(f, "i8"),
153            Self::Int(IntWidth::W16, Signedness::Signed) => write!(f, "i16"),
154            Self::Int(IntWidth::W32, Signedness::Signed) => write!(f, "i32"),
155            Self::Int(IntWidth::W64, Signedness::Signed) => write!(f, "i64"),
156            Self::Int(IntWidth::W128, Signedness::Signed) => write!(f, "i128"),
157            Self::Int(IntWidth::WSize, Signedness::Signed) => write!(f, "isize"),
158            Self::Int(IntWidth::W8, Signedness::Unsigned) => write!(f, "u8"),
159            Self::Int(IntWidth::W16, Signedness::Unsigned) => write!(f, "u16"),
160            Self::Int(IntWidth::W32, Signedness::Unsigned) => write!(f, "u32"),
161            Self::Int(IntWidth::W64, Signedness::Unsigned) => write!(f, "u64"),
162            Self::Int(IntWidth::W128, Signedness::Unsigned) => write!(f, "u128"),
163            Self::Int(IntWidth::WSize, Signedness::Unsigned) => write!(f, "usize"),
164            Self::Float(FloatWidth::W32) => write!(f, "f32"),
165            Self::Float(FloatWidth::W64) => write!(f, "f64"),
166            Self::Pointer(Mutability::Shared, inner) => write!(f, "&{inner}"),
167            Self::Pointer(Mutability::Mutable, inner) => write!(f, "|{inner}"),
168            Self::Array(inner, length) => write!(f, "[{inner}]{length}"),
169            Self::Vector(inner, count) => write!(f, "{{{inner}}}{count}"),
170            Self::Named(name) => write!(f, "{name}"),
171            Self::Tuple(fields) => {
172                for (index, field) in fields.iter().enumerate() {
173                    if index > 0 {
174                        write!(f, " & ")?;
175                    }
176                    write!(f, "{field}")?;
177                }
178                Ok(())
179            }
180            Self::Enum(variants) => {
181                for (index, variant) in variants.iter().enumerate() {
182                    if index > 0 {
183                        write!(f, " | ")?;
184                    }
185                    write!(f, "{variant}")?;
186                }
187                Ok(())
188            }
189            Self::Slice(_, inner) => write!(f, "[{inner}]"),
190            Self::Function(signature) => {
191                write!(f, "fn(")?;
192                for (index, parameter) in signature.parameters.iter().enumerate() {
193                    if index > 0 {
194                        write!(f, ", ")?;
195                    }
196                    write!(f, "{parameter}")?;
197                }
198                write!(f, ") -> {}", signature.return_type)
199            }
200        }
201    }
202}