1use std::{
2 fmt,
3 sync::{Arc, RwLock},
4};
5
6use crate::{
7 format_vec,
8 interner::{Symbol, TypeNodeId, with_session_globals},
9 pattern::TypedId,
10 utils::metadata::Location,
11};
12
13#[derive(Clone, Debug, PartialEq)]
16pub enum PType {
17 Unit,
18 Int,
19 Numeric,
20 String,
21}
22
23#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
24pub struct IntermediateId(pub u64);
25
26#[derive(Clone, Debug, PartialEq)]
27pub struct TypeBound {
28 pub lower: TypeNodeId,
29 pub upper: TypeNodeId,
30}
31impl Default for TypeBound {
32 fn default() -> Self {
33 Self {
34 lower: Type::Failure.into_id(),
35 upper: Type::Any.into_id(),
36 }
37 }
38}
39
40#[derive(Clone, Debug, PartialEq)]
41pub struct TypeVar {
42 pub parent: Option<TypeNodeId>,
43 pub var: IntermediateId,
44 pub level: u64,
45 pub bound: TypeBound,
46}
47impl TypeVar {
48 pub fn new(var: IntermediateId, level: u64) -> Self {
49 Self {
50 parent: None,
51 var,
52 level,
53 bound: TypeBound::default(),
54 }
55 }
56}
57
58#[derive(Clone, Debug, PartialEq)]
59pub struct RecordTypeField {
60 pub key: Symbol,
61 pub ty: TypeNodeId,
62 pub has_default: bool,
63}
64impl RecordTypeField {
65 pub fn new(key: Symbol, ty: TypeNodeId, has_default: bool) -> Self {
66 Self {
67 key,
68 ty,
69 has_default,
70 }
71 }
72}
73impl From<TypedId> for RecordTypeField {
74 fn from(value: TypedId) -> Self {
75 Self {
76 key: value.id,
77 ty: value.ty,
78 has_default: value.default_value.is_some(),
79 }
80 }
81}
82#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
83pub struct TypeSchemeId(pub u64);
84
85#[derive(Clone, Debug)]
86pub enum Type {
87 Primitive(PType),
88 Array(TypeNodeId),
90 Tuple(Vec<TypeNodeId>),
91 Record(Vec<RecordTypeField>),
92 Function {
95 arg: TypeNodeId,
96 ret: TypeNodeId,
97 },
98 Ref(TypeNodeId),
99 Code(TypeNodeId),
101 Intermediate(Arc<RwLock<TypeVar>>),
102 TypeScheme(TypeSchemeId),
103 Any,
105 Failure,
107 Unknown,
108}
109impl PartialEq for Type {
110 fn eq(&self, other: &Self) -> bool {
111 match (self, other) {
112 (Type::Intermediate(a), Type::Intermediate(b)) => {
113 let a = a.read().unwrap();
114 let b = b.read().unwrap();
115 a.var == b.var
116 }
117 (Type::Primitive(a), Type::Primitive(b)) => a == b,
118 (Type::Array(a), Type::Array(b)) => a == b,
119 (Type::Tuple(a), Type::Tuple(b)) => a == b,
120 (Type::Record(a), Type::Record(b)) => a == b,
121 (Type::Function { arg: a1, ret: a2 }, Type::Function { arg: b1, ret: b2 }) => {
122 a1 == b1 && a2 == b2
123 }
124 (Type::Ref(a), Type::Ref(b)) => a == b,
125 (Type::Code(a), Type::Code(b)) => a == b,
126 (Type::TypeScheme(a), Type::TypeScheme(b)) => a == b,
127 (Type::Any, Type::Any) => true,
128 (Type::Failure, Type::Failure) => true,
129 (Type::Unknown, Type::Unknown) => true,
130 _ => false,
131 }
132 }
133}
134
135pub type TypeSize = u8;
137
138impl Type {
139 pub fn contains_function(&self) -> bool {
142 match self {
143 Type::Function { arg: _, ret: _ } => true,
144 Type::Tuple(t) => t.iter().any(|t| t.to_type().contains_function()),
145 Type::Record(t) => t
146 .iter()
147 .any(|RecordTypeField { ty, .. }| ty.to_type().contains_function()),
148 _ => false,
149 }
150 }
151 pub fn is_function(&self) -> bool {
152 matches!(self, Type::Function { arg: _, ret: _ })
153 }
154 pub fn contains_code(&self) -> bool {
155 match self {
156 Type::Code(_) => true,
157 Type::Tuple(t) => t.iter().any(|t| t.to_type().contains_code()),
158 Type::Record(t) => t
159 .iter()
160 .any(|RecordTypeField { ty, .. }| ty.to_type().contains_code()),
161 _ => false,
162 }
163 }
164 pub fn is_intermediate(&self) -> Option<Arc<RwLock<TypeVar>>> {
165 match self {
166 Type::Intermediate(tvar) => Some(tvar.clone()),
167 _ => None,
168 }
169 }
170
171 pub fn get_as_tuple(&self) -> Option<Vec<TypeNodeId>> {
172 match self {
173 Type::Tuple(types) => Some(types.to_vec()),
174 Type::Record(fields) => Some(
175 fields
176 .iter()
177 .map(|RecordTypeField { ty, .. }| *ty)
178 .collect::<Vec<_>>(),
179 ),
180 _ => None,
181 }
182 }
183 pub fn can_be_unpacked(&self) -> bool {
184 matches!(self, Type::Tuple(_) | Type::Record(_))
185 }
186 pub fn get_iochannel_count(&self) -> Option<u32> {
187 match self {
188 Type::Tuple(ts) => {
189 if ts
190 .iter()
191 .all(|t| t.to_type() == Type::Primitive(PType::Numeric))
192 {
193 Some(ts.len() as _)
194 } else {
195 None
196 }
197 }
198 Type::Record(kvs) => {
199 if kvs.iter().all(|RecordTypeField { ty, .. }| {
200 ty.to_type() == Type::Primitive(PType::Numeric)
201 }) {
202 Some(kvs.len() as _)
203 } else {
204 None
205 }
206 }
207 Type::Primitive(PType::Numeric) => Some(1),
208 Type::Primitive(PType::Unit) => Some(0),
209 _ => None,
210 }
211 }
212 pub fn into_id(self) -> TypeNodeId {
213 with_session_globals(|session_globals| session_globals.store_type(self))
214 }
215
216 pub fn into_id_with_location(self, loc: Location) -> TypeNodeId {
217 with_session_globals(|session_globals| session_globals.store_type_with_location(self, loc))
218 }
219
220 pub fn to_string_for_error(&self) -> String {
221 match self {
222 Type::Array(a) => {
223 format!("[{}, ...]", a.to_type().to_string_for_error())
224 }
225 Type::Tuple(v) => {
226 let vf = format_vec!(
227 v.iter()
228 .map(|x| x.to_type().to_string_for_error())
229 .collect::<Vec<_>>(),
230 ","
231 );
232 format!("({vf})")
233 }
234 Type::Record(v) => {
235 let vf = format_vec!(
236 v.iter()
237 .map(|RecordTypeField { key, ty, .. }| format!(
238 "{}: {}",
239 key.as_str(),
240 ty.to_type().to_string_for_error()
241 ))
242 .collect::<Vec<_>>(),
243 ","
244 );
245 format!("({vf})")
246 }
247 Type::Function { arg, ret } => {
248 format!(
249 "({})->{}",
250 arg.to_type().to_string_for_error(),
251 ret.to_type().to_string_for_error()
252 )
253 }
254 Type::Ref(x) => format!("&{}", x.to_type().to_string_for_error()),
255 Type::Code(c) => format!("`({})", c.to_type().to_string_for_error()),
256 Type::Intermediate(_id) => "?".to_string(),
257 x => x.to_string(),
259 }
260 }
261}
262
263impl TypeNodeId {
264 pub fn get_root(&self) -> TypeNodeId {
265 match self.to_type() {
266 Type::Intermediate(cell) => {
267 let tv = cell.read().unwrap();
268 tv.parent.map_or(*self, |t| t.get_root())
269 }
270 _ => *self,
271 }
272 }
273 pub fn apply_fn<F>(&self, mut closure: F) -> Self
274 where
275 F: FnMut(Self) -> Self,
276 {
277 let apply_scalar = |a: Self, c: &mut F| -> Self { c(a) };
278 let apply_vec = |v: &[Self], c: &mut F| -> Vec<Self> { v.iter().map(|a| c(*a)).collect() };
279 let result = match self.to_type() {
280 Type::Array(a) => Type::Array(apply_scalar(a, &mut closure)),
281 Type::Tuple(v) => Type::Tuple(apply_vec(&v, &mut closure)),
282 Type::Record(s) => Type::Record(
283 s.iter()
284 .map(
285 |RecordTypeField {
286 key,
287 ty,
288 has_default,
289 }| {
290 RecordTypeField::new(
291 *key,
292 apply_scalar(*ty, &mut closure),
293 *has_default,
294 )
295 },
296 )
297 .collect(),
298 ),
299 Type::Function { arg, ret } => Type::Function {
300 arg: apply_scalar(arg, &mut closure),
301 ret: apply_scalar(ret, &mut closure),
302 },
303 Type::Ref(x) => Type::Ref(apply_scalar(x, &mut closure)),
304 Type::Code(c) => Type::Code(apply_scalar(c, &mut closure)),
305 Type::Intermediate(id) => Type::Intermediate(id.clone()),
306 _ => self.to_type(),
307 };
308
309 result.into_id()
310 }
311
312 pub fn fold<F, R>(&self, _closure: F) -> R
313 where
314 F: Fn(Self, Self) -> R,
315 {
316 todo!()
317 }
318}
319
320impl fmt::Display for PType {
321 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322 match self {
323 PType::Unit => write!(f, "()"),
324 PType::Int => write!(f, "int"),
325 PType::Numeric => write!(f, "number"),
326 PType::String => write!(f, "string"),
327 }
328 }
329}
330impl fmt::Display for TypeVar {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 write!(
333 f,
334 "?{}[{}]{}",
335 self.var.0,
336 self.level,
337 self.parent
338 .map_or_else(|| "".to_string(), |t| format!(":{}", t.to_type()))
339 )
340 }
341}
342impl fmt::Display for RecordTypeField {
343 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
344 let def = if self.has_default { "(default)" } else { "" };
345 write!(f, "{}:{}{def}", self.key, self.ty.to_type())
346 }
347}
348impl fmt::Display for Type {
349 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350 match self {
351 Type::Primitive(p) => write!(f, "{p}"),
352 Type::Array(a) => write!(f, "[{}]", a.to_type()),
353 Type::Tuple(v) => {
354 let vf = format_vec!(
355 v.iter().map(|x| x.to_type().clone()).collect::<Vec<_>>(),
356 ","
357 );
358 write!(f, "({vf})")
359 }
360 Type::Record(v) => {
361 write!(f, "{{{}}}", format_vec!(v, ", "))
362 }
363 Type::Function { arg, ret } => {
364 write!(f, "({})->{}", arg.to_type(), ret.to_type())
365 }
366 Type::Ref(x) => write!(f, "&{}", x.to_type()),
367
368 Type::Code(c) => write!(f, "<{}>", c.to_type()),
369 Type::Intermediate(id) => {
370 write!(f, "{}", id.read().unwrap())
371 }
372 Type::TypeScheme(id) => {
373 write!(f, "g({})", id.0)
374 }
375 Type::Any => write!(f, "any"),
376 Type::Failure => write!(f, "!"),
377 Type::Unknown => write!(f, "unknown"),
378 }
379 }
380}
381
382pub mod builder;
383
384