1#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3pub enum Signedness {
4 Signed,
6 Unsigned,
8}
9
10#[derive(Copy, Clone, Debug, PartialEq, Eq)]
12pub enum IntWidth {
13 W8,
15 W16,
17 W32,
19 W64,
21 W128,
23 WSize,
25}
26
27impl IntWidth {
28 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 pub fn bit_size(self) -> usize {
41 self.byte_size() * 8
42 }
43}
44
45#[derive(Copy, Clone, Debug, PartialEq, Eq)]
47pub enum FloatWidth {
48 W32,
50 W64,
52}
53
54impl FloatWidth {
55 pub fn byte_size(self) -> usize {
57 use FloatWidth::*;
58 match self {
59 W32 => 4,
60 W64 => 8,
61 }
62 }
63}
64
65#[derive(Copy, Clone, Debug, PartialEq, Eq)]
67pub enum Mutability {
68 Shared,
70 Mutable,
72}
73
74#[derive(Clone, Debug, PartialEq, Eq)]
76pub struct FunctionSignature {
77 pub parameters: Vec<Type>,
79 pub return_type: Box<Type>,
81}
82
83#[derive(Clone, Debug, PartialEq, Eq)]
85pub enum Type {
86 Never,
88 Bool,
90 Int(IntWidth, Signedness),
92 Float(FloatWidth),
94 Pointer(Mutability, Box<Self>),
96 Array(Box<Self>, usize),
98 Vector(Box<Self>, usize),
100 Slice(Mutability, Box<Self>),
102 Tuple(Vec<Self>),
104 Enum(Vec<Self>),
106 Named(String),
108 Function(FunctionSignature),
110}
111
112impl Type {
113 pub fn unit() -> Self {
115 Self::Tuple(Vec::new())
116 }
117
118 pub fn is_unit(&self) -> bool {
120 matches!(self, Self::Tuple(fields) if fields.is_empty())
121 }
122
123 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}