spade_types/
meta_types.rs

1use serde::{Deserialize, Serialize};
2
3/*
4  The meta-types form a a lattice with the following hierarchy
5
6         any
7        /    \
8     number type
9       / \
10    uint int
11*/
12
13#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)]
14pub enum MetaType {
15    Any,
16
17    Type,
18    Number,
19
20    Int,
21    Uint,
22
23    Bool,
24}
25
26// Attempts to unify l and r, returning the resulting MetaType if they are compatible,
27// or an error if they are not
28pub fn unify_meta(l: &MetaType, r: &MetaType) -> Option<MetaType> {
29    match (l, r) {
30        (MetaType::Any, other) => Some(other.clone()),
31        (other, MetaType::Any) => Some(other.clone()),
32        (MetaType::Number, other @ (MetaType::Int | MetaType::Uint))
33        | (other @ (MetaType::Int | MetaType::Uint), MetaType::Number) => Some(other.clone()),
34        (MetaType::Type, MetaType::Type)
35        | (MetaType::Int, MetaType::Int)
36        | (MetaType::Number, MetaType::Number)
37        | (MetaType::Bool, MetaType::Bool)
38        | (MetaType::Uint, MetaType::Uint) => Some(l.clone()),
39
40        (MetaType::Bool, _) => None,
41        (_, MetaType::Bool) => None,
42        (MetaType::Type, MetaType::Int)
43        | (MetaType::Type, MetaType::Uint)
44        | (MetaType::Int, MetaType::Type)
45        | (MetaType::Int, MetaType::Uint)
46        | (MetaType::Uint, MetaType::Type)
47        | (MetaType::Uint, MetaType::Int)
48        | (MetaType::Type, MetaType::Number)
49        | (MetaType::Number, MetaType::Type) => None,
50    }
51}
52
53impl MetaType {
54    /// Returns the type which is the most concrete of self and another type.
55    /// A type which can be converted into another type is less concrete than the
56    /// other type. Ordering of nnn-unifiable types is undefined
57    pub fn is_more_concrete_than(&self, other: &Self) -> bool {
58        if self > other {
59            false
60        } else {
61            true
62        }
63    }
64}
65
66impl std::fmt::Display for MetaType {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        match self {
69            MetaType::Any => write!(f, "#any"),
70            MetaType::Type => write!(f, "#type"),
71            MetaType::Int => write!(f, "#int"),
72            MetaType::Uint => write!(f, "#uint"),
73            MetaType::Bool => write!(f, "#bool"),
74            MetaType::Number => write!(f, "#number"),
75        }
76    }
77}