1use serde::{Deserialize, Serialize};
7use std::fmt;
8use thiserror::Error;
9
10pub mod inference;
11pub mod value;
12
13pub use value::Value;
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum Type {
18 Int,
20 Float,
21 Str,
22 Bool,
23 Bytes,
24 Unit,
25
26 List(Box<Type>),
28 Dict(Box<Type>, Box<Type>),
29 Optional(Box<Type>),
30
31 Promise(Box<Type>),
33 Result(Box<Type>, Box<Type>),
34
35 Function {
37 params: Vec<(String, Type)>,
38 return_type: Box<Type>,
39 },
40
41 TypeVar(u32),
43
44 Unknown,
46}
47
48impl Type {
49 pub fn is_assignable_to(&self, other: &Type) -> bool {
51 match (self, other) {
52 (t1, t2) if t1 == t2 => true,
54
55 (Type::Unknown, _) | (_, Type::Unknown) => true,
57
58 (Type::List(t1), Type::List(t2)) => t1.is_assignable_to(t2),
60 (Type::Optional(t1), Type::Optional(t2)) => t1.is_assignable_to(t2),
61 (Type::Promise(t1), Type::Promise(t2)) => t1.is_assignable_to(t2),
62
63 (Type::Result(ok1, err1), Type::Result(ok2, err2)) => {
65 ok1.is_assignable_to(ok2) && err1.is_assignable_to(err2)
66 }
67
68 (Type::Dict(k1, v1), Type::Dict(k2, v2)) => {
70 k1.is_assignable_to(k2) && v1.is_assignable_to(v2)
71 }
72
73 (
75 Type::Function {
76 params: p1,
77 return_type: r1,
78 },
79 Type::Function {
80 params: p2,
81 return_type: r2,
82 },
83 ) => {
84 p1.len() == p2.len()
85 && p1
86 .iter()
87 .zip(p2.iter())
88 .all(|((_, t1), (_, t2))| t2.is_assignable_to(t1))
89 && r1.is_assignable_to(r2)
90 }
91
92 _ => false,
93 }
94 }
95}
96
97impl fmt::Display for Type {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 match self {
100 Type::Int => write!(f, "int"),
101 Type::Float => write!(f, "float"),
102 Type::Str => write!(f, "str"),
103 Type::Bool => write!(f, "bool"),
104 Type::Bytes => write!(f, "bytes"),
105 Type::Unit => write!(f, "unit"),
106 Type::List(t) => write!(f, "list[{t}]"),
107 Type::Dict(k, v) => write!(f, "dict[{k}, {v}]"),
108 Type::Optional(t) => write!(f, "optional[{t}]"),
109 Type::Promise(t) => write!(f, "promise[{t}]"),
110 Type::Result(ok, err) => write!(f, "result[{ok}, {err}]"),
111 Type::Function {
112 params,
113 return_type,
114 } => {
115 write!(f, "(")?;
116 for (i, (name, typ)) in params.iter().enumerate() {
117 if i > 0 {
118 write!(f, ", ")?;
119 }
120 write!(f, "{name}: {typ}")?;
121 }
122 write!(f, ") -> {return_type}")
123 }
124 Type::TypeVar(id) => write!(f, "T{id}"),
125 Type::Unknown => write!(f, "?"),
126 }
127 }
128}
129
130#[derive(Debug, Error)]
131pub enum TypeError {
132 #[error("Type mismatch: expected {expected}, found {found}")]
133 TypeMismatch { expected: Type, found: Type },
134
135 #[error("Undefined variable: {0}")]
136 UndefinedVariable(String),
137
138 #[error("Cannot call non-function type: {0}")]
139 NotCallable(Type),
140
141 #[error("Wrong number of arguments: expected {expected}, found {found}")]
142 ArgumentCountMismatch { expected: usize, found: usize },
143
144 #[error("Cannot access attribute '{attr}' on type {typ}")]
145 AttributeError { attr: String, typ: Type },
146
147 #[error("Type inference failed: {0}")]
148 InferenceFailed(String),
149}