mimium_lang/
types.rs

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/// Basic types that are not boxed.
14/// They should be splitted semantically as the type of `feed x.e`cannot take function type.
15#[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    //aggregate types
89    Array(TypeNodeId),
90    Tuple(Vec<TypeNodeId>),
91    Record(Vec<RecordTypeField>),
92    ///Function that takes some type and return some type
93    ///If the function takes multiple arguments, the arguments becomes record type.
94    Function {
95        arg: TypeNodeId,
96        ret: TypeNodeId,
97    },
98    Ref(TypeNodeId),
99    //(experimental) code-type for multi-stage computation that will be evaluated on the next stage
100    Code(TypeNodeId),
101    Intermediate(Arc<RwLock<TypeVar>>),
102    TypeScheme(TypeSchemeId),
103    /// Any type is the top level, it can be unified with anything.
104    Any,
105    /// Failure type: it is bottom type that can be unified to any type and return bottom type.
106    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
135// currently, this refers to the number of registers
136pub type TypeSize = u8;
137
138impl Type {
139    // check if contains any function type in its member.
140    // if no functions are contained, it means that the value can be placed in linear memory.
141    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            // if no special treatment is needed, forward to the Display implementation
258            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// #[cfg(test)]
385// mod type_test {
386//     use super::*;
387// #[test]
388
389// }