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    Str,
25}
26
27// Attempts to unify l and r, returning the resulting MetaType if they are compatible,
28// or an error if they are not
29pub fn unify_meta(l: &MetaType, r: &MetaType) -> Option<MetaType> {
30    match (l, r) {
31        (MetaType::Any, other) => Some(other.clone()),
32        (other, MetaType::Any) => Some(other.clone()),
33        (MetaType::Number, other @ (MetaType::Int | MetaType::Uint))
34        | (other @ (MetaType::Int | MetaType::Uint), MetaType::Number) => Some(other.clone()),
35        (MetaType::Type, MetaType::Type)
36        | (MetaType::Int, MetaType::Int)
37        | (MetaType::Number, MetaType::Number)
38        | (MetaType::Bool, MetaType::Bool)
39        | (MetaType::Str, MetaType::Str)
40        | (MetaType::Uint, MetaType::Uint) => Some(l.clone()),
41
42        (MetaType::Bool, _) => None,
43        (_, MetaType::Bool) => None,
44        (MetaType::Str, _) => None,
45        (_, MetaType::Str) => None,
46        (MetaType::Type, MetaType::Int)
47        | (MetaType::Type, MetaType::Uint)
48        | (MetaType::Int, MetaType::Type)
49        | (MetaType::Int, MetaType::Uint)
50        | (MetaType::Uint, MetaType::Type)
51        | (MetaType::Uint, MetaType::Int)
52        | (MetaType::Type, MetaType::Number)
53        | (MetaType::Number, MetaType::Type) => None,
54    }
55}
56
57impl MetaType {
58    /// Returns the type which is the most concrete of self and another type.
59    /// A type which can be converted into another type is less concrete than the
60    /// other type. Ordering of nnn-unifiable types is undefined
61    pub fn is_more_concrete_than(&self, other: &Self) -> bool {
62        if self > other {
63            false
64        } else {
65            true
66        }
67    }
68}
69
70impl std::fmt::Display for MetaType {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        match self {
73            MetaType::Any => write!(f, "#any"),
74            MetaType::Type => write!(f, "#type"),
75            MetaType::Int => write!(f, "#int"),
76            MetaType::Uint => write!(f, "#uint"),
77            MetaType::Bool => write!(f, "#bool"),
78            MetaType::Str => write!(f, "#str"),
79            MetaType::Number => write!(f, "#number"),
80        }
81    }
82}