lust/ast/
types.rs

1use super::Span;
2use alloc::{boxed::Box, string::{String, ToString}, vec::Vec};
3use core::fmt;
4#[derive(Debug, Clone, Eq, Hash)]
5pub struct Type {
6    pub kind: TypeKind,
7    pub span: Span,
8}
9
10impl PartialEq for Type {
11    fn eq(&self, other: &Self) -> bool {
12        self.kind == other.kind
13    }
14}
15
16impl Type {
17    pub fn new(kind: TypeKind, span: Span) -> Self {
18        Self { kind, span }
19    }
20}
21
22impl fmt::Display for Type {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        self.kind.fmt(f)
25    }
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Hash)]
29pub enum TypeKind {
30    Int,
31    Float,
32    String,
33    Bool,
34    Named(String),
35    Generic(String),
36    Array(Box<Type>),
37    Map(Box<Type>, Box<Type>),
38    Table,
39    Function {
40        params: Vec<Type>,
41        return_type: Box<Type>,
42    },
43    Tuple(Vec<Type>),
44    Option(Box<Type>),
45    Result(Box<Type>, Box<Type>),
46    Ref(Box<Type>),
47    MutRef(Box<Type>),
48    Pointer {
49        mutable: bool,
50        pointee: Box<Type>,
51    },
52    GenericInstance {
53        name: String,
54        type_args: Vec<Type>,
55    },
56    Unknown,
57    Union(Vec<Type>),
58    Trait(String),
59    TraitBound(Vec<String>),
60    Unit,
61    Infer,
62}
63
64impl TypeKind {
65    pub fn is_primitive(&self) -> bool {
66        matches!(
67            self,
68            TypeKind::Int | TypeKind::Float | TypeKind::String | TypeKind::Bool
69        )
70    }
71}
72
73impl fmt::Display for TypeKind {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        match self {
76            TypeKind::Int => write!(f, "int"),
77            TypeKind::Float => write!(f, "float"),
78            TypeKind::String => write!(f, "string"),
79            TypeKind::Bool => write!(f, "bool"),
80            TypeKind::Named(name) => write!(f, "{name}"),
81            TypeKind::Generic(name) => write!(f, "{name}"),
82            TypeKind::Array(inner) => write!(f, "Array<{}>", inner),
83            TypeKind::Map(key, value) => write!(f, "Map<{}, {}>", key, value),
84            TypeKind::Table => write!(f, "Table"),
85            TypeKind::Function {
86                params,
87                return_type,
88            } => {
89                let params = params
90                    .iter()
91                    .map(|p| p.to_string())
92                    .collect::<Vec<_>>()
93                    .join(", ");
94                write!(f, "function({}) -> {}", params, return_type)
95            }
96
97            TypeKind::Tuple(elements) => {
98                let elems = elements
99                    .iter()
100                    .map(|t| t.to_string())
101                    .collect::<Vec<_>>()
102                    .join(", ");
103                write!(f, "Tuple<{}>", elems)
104            }
105
106            TypeKind::Option(inner) => write!(f, "Option<{}>", inner),
107            TypeKind::Result(ok, err) => write!(f, "Result<{}, {}>", ok, err),
108            TypeKind::Ref(inner) => write!(f, "&{}", inner),
109            TypeKind::MutRef(inner) => write!(f, "&mut {}", inner),
110            TypeKind::Pointer { mutable, pointee } => {
111                if *mutable {
112                    write!(f, "*mut {}", pointee)
113                } else {
114                    write!(f, "*{}", pointee)
115                }
116            }
117
118            TypeKind::GenericInstance { name, type_args } => {
119                let args = type_args
120                    .iter()
121                    .map(|t| t.to_string())
122                    .collect::<Vec<_>>()
123                    .join(", ");
124                write!(f, "{name}<{}>", args)
125            }
126
127            TypeKind::Unknown => write!(f, "unknown"),
128            TypeKind::Union(types) => {
129                let parts = types
130                    .iter()
131                    .map(|t| t.to_string())
132                    .collect::<Vec<_>>()
133                    .join(" | ");
134                write!(f, "{parts}")
135            }
136
137            TypeKind::Trait(name) => write!(f, "{name}"),
138            TypeKind::TraitBound(traits) => write!(f, "{}", traits.join(" + ")),
139            TypeKind::Unit => write!(f, "()"),
140            TypeKind::Infer => write!(f, "_"),
141        }
142    }
143}