deskc_conc_types/
lib.rs

1use region::RegionId;
2use serde::{Deserialize, Serialize};
3
4mod region;
5
6#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
7pub struct ConcEffect {
8    pub input: ConcType,
9    pub output: ConcType,
10}
11
12/// Concrete type
13///
14/// For example, distinguishes between array or list.
15#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
16pub enum ConcType {
17    Number,
18    String,
19    Tuple(Vec<Self>),
20    Enum(Vec<Self>),
21    Function {
22        parameters: Vec<Self>,
23        body: Box<Self>,
24    },
25    Array(Box<Self>),
26    Set(Box<Self>),
27    Variable(String),
28    ForAll {
29        variable: String,
30        body: Box<Self>,
31    },
32    Effectful {
33        ty: Box<Self>,
34        effects: ConcEffectExpr,
35    },
36    Ref {
37        region: RegionId,
38        item: Box<Self>,
39    },
40    RefMut {
41        region: RegionId,
42        item: Box<Self>,
43    },
44    Label {
45        // Just for distinguish types
46        label: String,
47        item: Box<Self>,
48    },
49}
50
51impl ConcType {
52    pub fn needs_cast_to(&self, other: &Self) -> bool {
53        match (self, other) {
54            (x, y) if x == y => false,
55            (
56                ConcType::Effectful { ty, effects: _ },
57                ConcType::Effectful {
58                    ty: ty2,
59                    effects: _effects2,
60                },
61            ) if !ty.needs_cast_to(ty2) => false,
62            (ConcType::Label { label: _, item }, x) if !item.needs_cast_to(x) => false,
63            (x, ConcType::Label { label: _, item }) if !item.needs_cast_to(x) => false,
64            (ConcType::Enum(types), ConcType::Enum(types2)) => types
65                .iter()
66                .zip(types2.iter())
67                .any(|(x, y)| x.needs_cast_to(y)),
68            (ConcType::Tuple(types), ConcType::Tuple(types2)) => types
69                .iter()
70                .zip(types2.iter())
71                .any(|(x, y)| x.needs_cast_to(y)),
72            (x, ConcType::Effectful { ty, effects: _ }) if !x.needs_cast_to(ty) => false,
73            _ => true,
74        }
75    }
76}
77
78#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
79pub enum ConcEffectExpr {
80    Effects(Vec<ConcEffect>),
81    Add(Vec<ConcEffectExpr>),
82    Sub {
83        minuend: Box<ConcEffectExpr>,
84        subtrahend: Box<ConcEffectExpr>,
85    },
86    Apply {
87        function: Box<ConcType>,
88        arguments: Vec<ConcType>,
89    },
90}