ligen_ir/types/
type_.rs

1use crate::{Path, Identifier, PathSegment, Mutability};
2use crate::prelude::*;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
5/// Type structure.
6pub struct Type {
7    /// Type path.
8    pub path: Path,
9    /// Type length.
10    // TODO: This is only used for array types. Maybe we should move it to a separate structure?
11    pub length: Option<usize>,
12}
13
14// TODO: Move these constructors to its all structures? Reference, Vector, String, etc... And make them convertable to Type.
15impl Type {
16    /// Returns a new `Type` representing a mutable reference type.
17    pub fn mutable_reference(type_: impl Into<Type>) -> Self {
18        PathSegment::new(Identifier::mutable_reference(), type_.into()).into()
19    }
20
21    /// Returns a new `Type` representing a reference type.
22    pub fn reference(mutability: Mutability, type_: impl Into<Type>) -> Self {
23        PathSegment::new(Identifier::reference(mutability), type_.into()).into()
24    }
25
26    /// Returns a new `Type` representing a constant reference type.
27    pub fn constant_reference(type_: impl Into<Type>) -> Self {
28        PathSegment::new(Identifier::constant_reference(), type_.into()).into()
29    }
30
31    /// Returns a new `Type` representing a slice type.
32    pub fn slice(type_: impl Into<Type>) -> Self {
33        PathSegment::new(Identifier::slice(), type_.into()).into()
34    }
35
36    /// Returns a new `Type` representing an array type.
37    pub fn array(type_: impl Into<Type>, length: usize) -> Self {
38        let path = Path::from(PathSegment::new(Identifier::array(), type_.into()));
39        let length = Some(length);
40        Self { path, length }
41    }
42
43    /// Returns a new `Type` representing a vector type.
44    pub fn vector(type_: impl Into<Type>) -> Self {
45        Path::from(PathSegment::new(Identifier::vector(), type_.into())).into()
46    }
47
48    /// Returns a new `Type`representing an union type.
49    pub fn union(types: Vec<Type>) -> Self {
50        Path::from(PathSegment::new(Identifier::union(), types)).into()
51    }
52
53    /// Returns a new `Type` representing a variadic type.
54    pub fn variadic(type_: impl Into<Type>) -> Self {
55        Path::from(PathSegment::new(Identifier::variadic(), type_.into())).into()
56    }
57
58    /// Returns a new `Type` representing a dictionary type.
59    pub fn tuple(types: Vec<Type>) -> Self {
60        Path::from(PathSegment::new(Identifier::tuple(), types)).into()
61    }
62
63    /// Returns a new `Type` representing a option type.
64    pub fn option(type_: impl Into<Type>) -> Self {
65        Path::from(PathSegment::new(Identifier::option(), type_.into())).into()
66    }
67
68    /// Returns a new `Type` representing an opaque type.
69    pub fn opaque() -> Self {
70        Identifier::opaque().into()
71    }
72
73    /// Returns a new `Type` representing a boolean type.
74    pub fn boolean() -> Self {
75        Identifier::boolean().into()
76    }
77
78    /// Returns a new `Type` representing a character type.
79    pub fn character() -> Self {
80        Identifier::character().into()
81    }
82
83    /// Returns a new `Type` representing an 8-bit signed integer type.
84    pub fn i8() -> Self {
85        Identifier::i8().into()
86    }
87
88    /// Returns a new `Type` representing a 16-bit signed integer type.
89    pub fn i16() -> Self {
90        Identifier::i16().into()
91    }
92
93    /// Returns a new `Type` representing a 32-bit signed integer type.
94    pub fn i32() -> Self {
95        Identifier::i32().into()
96    }
97
98    /// Returns a new `Type` representing a 64-bit signed integer type.
99    pub fn i64() -> Self {
100        Identifier::i64().into()
101    }
102
103    /// Returns a new `Type` representing a 128-bit signed integer type.
104    pub fn i128() -> Self {
105        Identifier::i128().into()
106    }
107
108    /// Returns a new `Type` representing an pointer-sized integer type.
109    pub fn isize() -> Self {
110        Identifier::isize().into()
111    }
112
113    /// Returns a new `Type` representing an 8-bit unsigned integer type.
114    pub fn u8() -> Self {
115        Identifier::u8().into()
116    }
117
118    /// Returns a new `Type` representing a 16-bit unsigned integer type.
119    pub fn u16() -> Self {
120        Identifier::u16().into()
121    }
122
123    /// Returns a new `Type` representing a 32-bit unsigned integer type.
124    pub fn u32() -> Self {
125        Identifier::u32().into()
126    }
127
128    /// Returns a new `Type` representing a 64-bit unsigned integer type.
129    pub fn u64() -> Self {
130        Identifier::u64().into()
131    }
132
133    /// Returns a new `Type` representing a 128-bit unsigned integer type.
134    pub fn u128() -> Self {
135        Identifier::u128().into()
136    }
137
138    /// Returns a new `Type` representing an pointer-sized unsigned integer type.
139    pub fn usize() -> Self {
140        Identifier::usize().into()
141    }
142
143    /// Returns a new `Type` representing a 16-bit floating-point type.
144    pub fn f16() -> Self {
145        Identifier::f16().into()
146    }
147
148    /// Returns a new `Type` representing a 32-bit floating-point type.
149    pub fn f32() -> Self {
150        Identifier::f32().into()
151    }
152
153    /// Returns a new `Type` representing a 64-bit floating-point type.
154    pub fn f64() -> Self {
155        Identifier::f64().into()
156    }
157
158    /// Returns a new `Type` representing a 128-bit floating-point type.
159    pub fn f128() -> Self {
160        Identifier::f128().into()
161    }
162
163    /// Returns a new `Type` representing a string type.
164    pub fn string() -> Self {
165        Identifier::string().into()
166    }
167}
168
169impl Default for Type {
170    fn default() -> Self {
171        Self::opaque()
172    }
173}
174
175impl Type {
176    /// Check if the `Type` is `Primitive`.
177    pub fn is_primitive(&self) -> bool {
178        self.is_boolean()
179        || self.is_character()
180        || self.is_float()
181        || self.is_integer()
182        || self.is_unsigned_integer()
183    }
184
185    pub fn is<T: Into<Self>>(&self, t: T) -> bool {
186        self == &t.into()
187    }
188
189    /// Check if the `Type` is `MutableReference`
190    pub fn is_mutable_reference(&self) -> bool {
191        self.path.last().identifier == Identifier::mutable_reference()
192    }
193
194    /// Check if the `Type` is `Boolean`.
195    pub fn is_boolean(&self) -> bool {
196        self.is(Self::boolean())
197    }
198
199    /// Check if the `Type` is `Character`.
200    pub fn is_character(&self) -> bool {
201        self.is(Self::character())
202    }
203
204    /// Check if the `Type` is a number.
205    pub fn is_number(&self) -> bool {
206        self.is_integer() || self.is_float()
207    }    
208
209    /// Check if the `Type` is integer.
210    pub fn is_integer(&self) -> bool {
211        self.is(Self::i8()) || self.is(Self::i16()) || self.is(Self::i32()) || self.is(Self::i64()) || self.is(Self::i128())
212    }
213
214    /// Check if the `Type` is `UnsignedInteger`.
215    pub fn is_unsigned_integer(&self) -> bool {
216        self.is(Self::u8()) || self.is(Self::u16()) || self.is(Self::u32()) || self.is(Self::u64()) || self.is(Self::u128())
217    }
218
219    /// Check if the `Type` is `Float`.
220    pub fn is_float(&self) -> bool {
221        self.is(Self::f32()) || self.is(Self::f64()) || self.is(Self::f128())
222    }
223
224    /// Check if the `Type` is `Tuple`.
225    pub fn is_tuple(&self) -> bool {
226        self.path.last().identifier == Identifier::tuple()
227    }
228
229    /// Check if the `Type` is `Vector`.
230    pub fn is_vector(&self) -> bool {
231        self.path.last().identifier == Identifier::vector()
232    }
233
234    /// Check if the `Type` is `String`.
235    pub fn is_string(&self) -> bool {
236        self.is(Self::string())
237    }
238}
239
240impl From<PathSegment> for Type {
241    fn from(path_segment: PathSegment) -> Self {
242        Path::from(path_segment).into()
243    }
244}
245
246impl From<&str> for Type {
247    fn from(value: &str) -> Self {
248        Path::from(value).into()
249    }
250}
251
252impl From<Identifier> for Type {
253    fn from(identifier: Identifier) -> Self {
254        Path::from(identifier).into()
255    }
256}
257
258impl From<Path> for Type {
259    fn from(path: Path) -> Self {
260        let length = None;
261        Self { path, length }
262    }
263}
264
265impl std::fmt::Display for Type {
266    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
267        f.write_str(&self.path.to_string())
268    }
269}