mf_expression/functions/
defs.rs1use crate::functions::arguments::Arguments;
6use crate::variable::VariableType;
7use crate::Variable;
8use std::any::Any;
9use std::collections::HashSet;
10use std::rc::Rc;
11
12pub trait FunctionDefinition: Any {
16 fn required_parameters(&self) -> usize;
18 fn optional_parameters(&self) -> usize;
20 fn check_types(
22 &self,
23 args: &[Rc<VariableType>],
24 ) -> FunctionTypecheck;
25 fn call(
27 &self,
28 args: Arguments,
29 ) -> anyhow::Result<Variable>;
30 fn param_type(
32 &self,
33 index: usize,
34 ) -> Option<VariableType>;
35 fn param_type_str(
37 &self,
38 index: usize,
39 ) -> String;
40 fn return_type(&self) -> VariableType;
42 fn return_type_str(&self) -> String;
44}
45
46#[derive(Debug, Default)]
50pub struct FunctionTypecheck {
51 pub general: Option<String>,
53 pub arguments: Vec<(usize, String)>,
55 pub return_type: VariableType,
57}
58
59#[derive(Clone)]
63pub struct FunctionSignature {
64 pub parameters: Vec<VariableType>,
66 pub return_type: VariableType,
68}
69
70impl FunctionSignature {
71 pub fn single(
77 parameter: VariableType,
78 return_type: VariableType,
79 ) -> Self {
80 Self { parameters: vec![parameter], return_type }
81 }
82}
83
84#[derive(Clone)]
88pub struct StaticFunction {
89 pub signature: FunctionSignature,
91 pub implementation: Rc<dyn Fn(Arguments) -> anyhow::Result<Variable>>,
93}
94
95impl FunctionDefinition for StaticFunction {
96 fn required_parameters(&self) -> usize {
98 self.signature.parameters.len()
99 }
100
101 fn optional_parameters(&self) -> usize {
103 0
104 }
105
106 fn check_types(
108 &self,
109 args: &[Rc<VariableType>],
110 ) -> FunctionTypecheck {
111 let mut typecheck = FunctionTypecheck::default();
112 typecheck.return_type = self.signature.return_type.clone();
113
114 if args.len() != self.required_parameters() {
116 typecheck.general = Some(format!(
117 "期望 `{}` 参数, 实际 `{}` 参数.",
118 self.required_parameters(),
119 args.len()
120 ));
121 }
122
123 for (i, (arg, expected_type)) in
125 args.iter().zip(self.signature.parameters.iter()).enumerate()
126 {
127 if !arg.satisfies(expected_type) {
128 typecheck.arguments.push((
129 i,
130 format!(
131 "参数类型 `{arg}` 不能赋值给参数类型 `{expected_type}`.",
132 ),
133 ));
134 }
135 }
136
137 typecheck
138 }
139
140 fn call(
142 &self,
143 args: Arguments,
144 ) -> anyhow::Result<Variable> {
145 (&self.implementation)(args)
146 }
147
148 fn param_type(
150 &self,
151 index: usize,
152 ) -> Option<VariableType> {
153 self.signature.parameters.get(index).cloned()
154 }
155
156 fn param_type_str(
158 &self,
159 index: usize,
160 ) -> String {
161 self.signature
162 .parameters
163 .get(index)
164 .map(|x| x.to_string())
165 .unwrap_or_else(|| "never".to_string())
166 }
167
168 fn return_type(&self) -> VariableType {
170 self.signature.return_type.clone()
171 }
172
173 fn return_type_str(&self) -> String {
175 self.signature.return_type.to_string()
176 }
177}
178
179#[derive(Clone)]
183pub struct CompositeFunction {
184 pub signatures: Vec<FunctionSignature>,
186 pub implementation: Rc<dyn Fn(Arguments) -> anyhow::Result<Variable>>,
188}
189
190impl FunctionDefinition for CompositeFunction {
191 fn required_parameters(&self) -> usize {
193 self.signatures.iter().map(|x| x.parameters.len()).min().unwrap_or(0)
194 }
195
196 fn optional_parameters(&self) -> usize {
198 let required_params = self.required_parameters();
199 let max = self
200 .signatures
201 .iter()
202 .map(|x| x.parameters.len())
203 .max()
204 .unwrap_or(0);
205
206 max - required_params
207 }
208
209 fn check_types(
211 &self,
212 args: &[Rc<VariableType>],
213 ) -> FunctionTypecheck {
214 let mut typecheck = FunctionTypecheck::default();
215 if self.signatures.is_empty() {
216 typecheck.general = Some("No implementation".to_string());
217 return typecheck;
218 }
219
220 let required_params = self.required_parameters();
221 let optional_params = self.optional_parameters();
222 let total_params = required_params + optional_params;
223
224 if args.len() < required_params || args.len() > total_params {
226 typecheck.general = Some(format!(
227 "Expected `{required_params} - {total_params}` arguments, got `{}`.",
228 args.len()
229 ))
230 }
231
232 for signature in &self.signatures {
234 let all_match = args
235 .iter()
236 .zip(signature.parameters.iter())
237 .all(|(arg, param)| arg.satisfies(param));
238 if all_match {
239 typecheck.return_type = signature.return_type.clone();
240 return typecheck;
241 }
242 }
243
244 for (i, arg) in args.iter().enumerate() {
246 let possible_types: Vec<&VariableType> = self
247 .signatures
248 .iter()
249 .filter_map(|sig| sig.parameters.get(i))
250 .collect();
251
252 if !possible_types.iter().any(|param| arg.satisfies(param)) {
253 let type_union = self.param_type_str(i);
254 typecheck.arguments.push((
255 i,
256 format!(
257 "Argument of type `{arg}` is not assignable to parameter of type `{type_union}`.",
258 ),
259 ))
260 }
261 }
262
263 let available_signatures = self
265 .signatures
266 .iter()
267 .map(|sig| {
268 let param_list = sig
269 .parameters
270 .iter()
271 .map(|x| x.to_string())
272 .collect::<Vec<_>>()
273 .join(", ");
274 format!("`({param_list}) -> {}`", sig.return_type)
275 })
276 .collect::<Vec<_>>()
277 .join("\n");
278 typecheck.general = Some(format!(
279 "No function overload matches provided arguments. Available overloads:\n{available_signatures}"
280 ));
281
282 typecheck
283 }
284
285 fn call(
287 &self,
288 args: Arguments,
289 ) -> anyhow::Result<Variable> {
290 (&self.implementation)(args)
291 }
292
293 fn param_type(
295 &self,
296 index: usize,
297 ) -> Option<VariableType> {
298 self.signatures
299 .iter()
300 .filter_map(|sig| sig.parameters.get(index))
301 .cloned()
302 .reduce(|a, b| a.merge(&b))
303 }
304
305 fn param_type_str(
307 &self,
308 index: usize,
309 ) -> String {
310 let possible_types: Vec<String> = self
311 .signatures
312 .iter()
313 .filter_map(|sig| sig.parameters.get(index))
314 .map(|x| x.to_string())
315 .collect();
316 if possible_types.is_empty() {
317 return String::from("never");
318 }
319
320 let is_optional = possible_types.len() != self.signatures.len();
321 let possible_types: Vec<String> = possible_types
322 .into_iter()
323 .collect::<HashSet<_>>()
324 .into_iter()
325 .collect();
326
327 let type_union = possible_types.join(" | ");
328 if is_optional {
329 return format!("Optional<{type_union}>");
330 }
331
332 type_union
333 }
334
335 fn return_type(&self) -> VariableType {
337 self.signatures
338 .iter()
339 .map(|sig| &sig.return_type)
340 .cloned()
341 .reduce(|a, b| a.merge(&b))
342 .unwrap_or(VariableType::Null)
343 }
344
345 fn return_type_str(&self) -> String {
347 let possible_types: Vec<String> = self
348 .signatures
349 .iter()
350 .map(|sig| sig.return_type.clone())
351 .map(|x| x.to_string())
352 .collect();
353 if possible_types.is_empty() {
354 return String::from("never");
355 }
356
357 possible_types
358 .into_iter()
359 .collect::<HashSet<_>>()
360 .into_iter()
361 .collect::<Vec<_>>()
362 .join(" | ")
363 }
364}