Skip to main content

cl_typeck/
type_kind.rs

1//! A [TypeKind] is a node in the [Table](crate::table::Table)'s type graph
2
3use crate::handle::Handle;
4use cl_ast::types::Symbol;
5use std::{fmt::Debug, str::FromStr};
6
7mod display;
8
9/// A [TypeKind] represents an item
10/// (a component of a [Table](crate::table::Table))
11#[derive(Clone, Debug, PartialEq, Eq, Hash)]
12pub enum TypeKind {
13    /// A type that is yet to be inferred!
14    Inferred,
15    /// A type variable, to be monomorphized
16    Variable,
17    /// An alias for an already-defined type
18    Instance(Handle),
19    /// A primitive type, built-in to the compiler
20    Primitive(Primitive),
21    /// A user-defined aromatic data type
22    Adt(Adt),
23    /// A reference to an already-defined type: &T
24    Ref(Handle),
25    /// A raw pointer to an already-defined type: &T
26    Ptr(Handle),
27    /// A contiguous view of dynamically sized memory
28    Slice(Handle),
29    /// A contiguous view of statically sized memory
30    Array(Handle, usize),
31    /// A tuple of existing types
32    Tuple(Vec<Handle>),
33    /// A function which accepts multiple inputs and produces an output
34    FnSig { args: Handle, rety: Handle },
35    /// An untyped module
36    Module,
37}
38
39#[derive(Clone, Debug, PartialEq, Eq, Hash)]
40pub enum Visibility {
41    Public,
42    Private,
43}
44
45/// A user-defined Aromatic Data Type
46#[derive(Clone, Debug, PartialEq, Eq, Hash)]
47pub enum Adt {
48    /// A union-like enum type
49    Enum(Vec<(Symbol, Handle)>),
50
51    /// A structural product type with named members
52    Struct(Vec<(Symbol, Visibility, Handle)>),
53    /// A structural product type with unnamed members
54    TupleStruct(Vec<(Visibility, Handle)>),
55    /// A structural product type of neither named nor unnamed members
56    UnitStruct,
57
58    /// A choose your own undefined behavior type
59    /// TODO: should unions be a language feature?
60    Union(Vec<(Symbol, Handle)>),
61}
62
63/// The set of compiler-intrinsic types.
64/// These primitive types have native implementations of the basic operations.
65#[rustfmt::skip]
66#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
67pub enum Primitive {
68    I8, I16, I32, I64, I128, Isize, // Signed integers
69    U8, U16, U32, U64, U128, Usize, // Unsigned integers
70    F8, F16, F32, F64, F128, Fsize, // Floating point numbers
71    Integer, Float,                 // Inferred int and float
72    Bool,                           // boolean value
73    Char,                           // Unicode codepoint
74    Str,                            // UTF-8 string
75    Never,                          // The never type
76}
77
78#[rustfmt::skip]
79impl Primitive {
80    /// Checks whether self is an integer
81    pub fn is_integer(self) -> bool {
82        matches!(
83            self, 
84            | Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128 | Self::Isize
85            | Self::U8 | Self::U16 | Self::U32 | Self::U64 | Self::U128 | Self::Usize
86            | Self::Integer
87        )
88    }
89    /// Checks whether self is a floating point number
90    pub fn is_float(self) -> bool {
91        matches!(
92            self, 
93            | Self::F8 | Self::F16 | Self::F32 | Self::F64 | Self::F128 | Self::Fsize
94            | Self::Float
95        )
96    }
97}
98
99// Author's note: the fsize type is a meme
100
101impl FromStr for Primitive {
102    type Err = ();
103
104    fn from_str(s: &str) -> Result<Self, Self::Err> {
105        Ok(match s {
106            "i8" => Primitive::I8,
107            "i16" => Primitive::I16,
108            "i32" => Primitive::I32,
109            "i64" => Primitive::I64,
110            "i128" => Primitive::I128,
111            "isize" => Primitive::Isize,
112            "u8" => Primitive::U8,
113            "u16" => Primitive::U16,
114            "u32" => Primitive::U32,
115            "u64" => Primitive::U64,
116            "u128" => Primitive::U128,
117            "usize" => Primitive::Usize,
118            "f8" => Primitive::F8,
119            "f16" => Primitive::F16,
120            "f32" => Primitive::F32,
121            "f64" => Primitive::F64,
122            "f128" => Primitive::F128,
123            "fsize" => Primitive::Fsize,
124            "bool" => Primitive::Bool,
125            "char" => Primitive::Char,
126            "str" => Primitive::Str,
127            "never" => Primitive::Never,
128            _ => Err(())?,
129        })
130    }
131}