(
meta: &mut ParserMetadata,
mut fun: FunctionDecl,
args: &[Type],
tok: Option<Token>,
persist: bool,
)
| 25 | } |
| 26 | |
| 27 | pub fn run_function_with_args( |
| 28 | meta: &mut ParserMetadata, |
| 29 | mut fun: FunctionDecl, |
| 30 | args: &[Type], |
| 31 | tok: Option<Token>, |
| 32 | persist: bool, |
| 33 | ) -> Result<(Type, usize), Failure> { |
| 34 | // Check if there are the correct amount of arguments |
| 35 | if fun.args.len() != args.len() { |
| 36 | let max_args = fun.args.len(); |
| 37 | let min_args = |
| 38 | fun.args.len() - fun.args.iter().filter(|arg| arg.optional.is_some()).count(); |
| 39 | let opt_argument = if max_args > min_args { |
| 40 | &format!(" ({max_args} optional)") |
| 41 | } else { |
| 42 | "" |
| 43 | }; |
| 44 | // Determine the correct grammar |
| 45 | let txt_arguments = pluralize(min_args, "argument", "arguments"); |
| 46 | let txt_given = pluralize(args.len(), "was given", "were given"); |
| 47 | // Return an error |
| 48 | return error!( |
| 49 | meta, |
| 50 | tok, |
| 51 | format!( |
| 52 | "Function '{}' expects {} {txt_arguments}{opt_argument}, but {} {txt_given}", |
| 53 | fun.name, |
| 54 | min_args, |
| 55 | args.len() |
| 56 | ) |
| 57 | ); |
| 58 | } |
| 59 | // Check if the function argument types match |
| 60 | if fun.is_args_typed { |
| 61 | for (index, (arg, given_type)) in izip!(fun.args.iter(), args.iter()).enumerate() { |
| 62 | let arg_name = &arg.name; |
| 63 | let arg_type = &arg.kind; |
| 64 | if !given_type.is_allowed_in(arg_type) { |
| 65 | let fun_name = &fun.name; |
| 66 | let ordinal = ordinal_number(index); |
| 67 | return error!(meta, tok, format!("{ordinal} argument '{arg_name}' of function '{fun_name}' expects type '{arg_type}', but '{given_type}' was given")); |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | let mut context = meta.fun_cache.get_context(fun.id).unwrap().clone(); |
| 72 | let mut block = meta |
| 73 | .fun_cache |
| 74 | .get_block(fun.id) |
| 75 | .unwrap() |
| 76 | .clone() |
| 77 | .with_needs_noop() |
| 78 | .with_no_syntax(); |
| 79 | let mut args_global_ids = vec![]; |
| 80 | |
| 81 | // Check if the function is already being parsed (recursion) |
| 82 | // If so, return the variant id that is currently being parsed |
| 83 | if let Some(variant_id) = meta.parsing_functions.get(&(fun.id, args.to_vec())) { |
| 84 | return Ok((fun.returns.clone(), *variant_id)); |
no test coverage detected