lang_interpreter/interpreter/data/
function.rs

1pub mod native;
2
3use std::collections::{HashMap, VecDeque};
4use std::fmt::{Debug, Display, Formatter, Write as _};
5use std::ops::Deref;
6use std::ptr;
7use gc::{Finalize, Gc, Trace};
8use crate::interpreter::{conversions, data, operators, Interpreter, InterpretingError};
9use crate::interpreter::data::{DataObject, DataObjectRef, DataType, DataTypeConstraint, DataTypeConstraintError, LangObjectRef, OptionDataObjectRef, OptionLangObjectRef, Visibility};
10use crate::interpreter::data::function::native::NativeFunction;
11use crate::lexer::CodePosition;
12use crate::parser::ast::AST;
13use crate::utils;
14
15#[derive(Debug)]
16pub struct NormalFunction {
17    argument_pos_list: Vec<CodePosition>,
18    function_body: AST,
19
20    /**
21     * If langPath is set, the Lang path from the stack frame element which is created for the function call will be overridden
22     */
23    lang_path: Option<Box<str>>,
24
25    /**
26     * If langFile or langPath is set, the Lang file from the stack frame element which is created for the function call will be overridden<br>
27     * This behavior allows for keeping the "&lt;shell&gt;" special case - when the Lang file is None - if a function within a stack frame element where the Lang file is null is
28     * called from within a stack frame element where Lang file is not None.
29     */
30    lang_file: Option<Box<str>>,
31}
32
33impl NormalFunction {
34    pub(crate) fn new(
35        argument_pos_list: Vec<CodePosition>,
36        function_body: AST,
37
38        lang_path: Option<&str>,
39        lang_file: Option<&str>,
40    ) -> Self {
41        Self {
42            argument_pos_list,
43            function_body,
44
45            lang_path: lang_path.map(Box::from),
46            lang_file: lang_file.map(Box::from),
47        }
48    }
49
50    pub fn is_equals(&self, other: &Self, _interpreter: &mut Interpreter, _pos: CodePosition) -> bool {
51        self.function_body == other.function_body
52    }
53
54    pub fn is_strict_equals(&self, other: &Self, _interpreter: &mut Interpreter, _pos: CodePosition) -> bool {
55        self.function_body == other.function_body
56    }
57
58    pub fn argument_pos_list(&self) -> &[CodePosition] {
59        &self.argument_pos_list
60    }
61
62    pub fn function_body(&self) -> &AST {
63        &self.function_body
64    }
65
66    pub fn lang_path(&self) -> Option<&str> {
67        self.lang_path.as_deref()
68    }
69
70    pub fn lang_file(&self) -> Option<&str> {
71        self.lang_file.as_deref()
72    }
73}
74
75#[derive(Debug, Trace, Finalize)]
76pub enum FunctionData {
77    //SAFETY: There are no GC reference inside NormalFunction
78    Normal(#[unsafe_ignore_trace] NormalFunction),
79    Native(NativeFunction),
80}
81
82impl FunctionData {
83    pub fn is_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
84        match (self, other) {
85            (FunctionData::Normal(s), FunctionData::Normal(o)) => s.is_equals(o, interpreter, pos),
86            (FunctionData::Native(s), FunctionData::Native(o)) => s.is_equals(o, interpreter, pos),
87
88            _ => false,
89        }
90    }
91
92    pub fn is_strict_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
93        match (self, other) {
94            (FunctionData::Normal(s), FunctionData::Normal(o)) => s.is_strict_equals(o, interpreter, pos),
95            (FunctionData::Native(s), FunctionData::Native(o)) => s.is_strict_equals(o, interpreter, pos),
96
97            _ => false,
98        }
99    }
100}
101
102#[derive(Debug, Trace, Finalize)]
103pub struct Function {
104    function: Gc<FunctionData>,
105
106    //SAFETY: There are no GC reference inside Parameter
107    #[unsafe_ignore_trace]
108    parameter_list: Vec<Parameter>,
109
110    //SAFETY: There are no GC reference inside VarArgsType
111    #[unsafe_ignore_trace]
112    var_args_parameter: Option<(usize, VarArgsType)>,
113
114    //SAFETY: There are no GC reference inside DataTypeConstraint
115    #[unsafe_ignore_trace]
116    return_value_type_constraint: Option<Box<DataTypeConstraint>>,
117
118    combinator_function_call_count: Option<usize>,
119    combinator_function_provided_arguments: Vec<DataObjectRef>,
120
121    function_name: Option<Box<str>>,
122}
123
124impl Function {
125    pub fn new_normal(
126        function: NormalFunction,
127        metadata: &FunctionMetadata,
128    ) -> Self {
129        if function.argument_pos_list.len() != metadata.parameter_list.len() {
130            panic!("Normal function parameter count does not match parameter count of function metadata");
131        }
132
133        Self::new(Gc::new(FunctionData::Normal(function)), metadata)
134    }
135
136    pub fn new_native(
137        function: NativeFunction,
138        metadata: &FunctionMetadata,
139    ) -> Self {
140        if function.lang_parameter_count() != metadata.parameter_list.len() {
141            panic!("Native function parameter count (without interpreter and without this object parameter) does not match parameter count of function metadata");
142        }
143
144        Self::new(Gc::new(FunctionData::Native(function)), metadata)
145    }
146
147    fn new(
148        function: Gc<FunctionData>,
149        metadata: &FunctionMetadata,
150    ) -> Self {
151        let mut var_args_parameter = None;
152        for (i, parameter) in metadata.parameter_list.iter().enumerate() {
153            match parameter.parameter_type {
154                ParameterType::VarArgs => {
155                    if var_args_parameter.is_some() {
156                        panic!("There can only be one var args parameter");
157                    }
158
159                    if parameter.parameter_name.starts_with("$") {
160                        if metadata.combinator_function {
161                            panic!("Text var args can not be used in combinator function");
162                        }
163
164                        var_args_parameter = Some((i, VarArgsType::Text));
165                    }else {
166                        var_args_parameter = Some((i, VarArgsType::Normal));
167                    }
168                },
169
170                ParameterType::RawVarArgs => {
171                    if var_args_parameter.is_some() {
172                        panic!("There can only be one var args parameter");
173
174                    }
175
176                    if metadata.combinator_function {
177                        panic!("Raw var args can not be used in combinator function");
178                    }
179
180                    var_args_parameter = Some((i, VarArgsType::Raw));
181                },
182
183                _ => {},
184            }
185        }
186
187        if matches!(var_args_parameter, Some((_, VarArgsType::Raw))) && metadata.parameter_list.len() != 1 {
188            panic!("If @RawVarArgs is used there must be exactly two parameters: (Interpreter, (Vec<DataObjectRef>,))");
189        }
190
191        Self {
192            function,
193
194            parameter_list: metadata.parameter_list.iter().cloned().map(Into::into).collect(),
195
196            var_args_parameter,
197
198            return_value_type_constraint: metadata.return_value_type_constraint.clone().map(Box::new),
199
200            combinator_function_call_count: metadata.combinator_function.then_some(0),
201            combinator_function_provided_arguments: Vec::with_capacity(0),
202
203            function_name: metadata.function_name.clone(),
204        }
205    }
206
207    pub fn call_native_func(
208        &self,
209        interpreter: &mut Interpreter,
210        this_object_with_super_level: Option<(LangObjectRef, usize)>,
211        mut argument_list: Vec<DataObjectRef>,
212        mut combined_argument_list: Vec<DataObjectRef>,
213    ) -> OptionDataObjectRef {
214        let FunctionData::Native(function) = self.function.as_ref() else {
215            return Some(interpreter.set_errno_error_object(
216                InterpretingError::InvalidFuncPtr,
217                Some("Function call of invalid FP"),
218                CodePosition::EMPTY,
219            ));
220        };
221
222        if function.is_method() && this_object_with_super_level.is_none() {
223            return Some(interpreter.set_errno_error_object(
224                InterpretingError::InvalidArguments,
225                Some("This-object is not bound for native function for LangObject"),
226                CodePosition::EMPTY,
227            ));
228        }
229
230        if !function.is_method() && this_object_with_super_level.is_some() {
231            return Some(interpreter.set_errno_error_object(
232                InterpretingError::InvalidArguments,
233                Some("This-object is bound for native function"),
234                CodePosition::EMPTY,
235            ));
236        }
237
238        let arg_cnt = self.parameter_list.len();
239
240        if self.combinator_function_call_count.is_some() {
241            let mut new_combined_argument_list = self.combinator_function_provided_arguments().to_vec();
242
243            new_combined_argument_list.append(&mut combined_argument_list.into_iter().
244                    map(|data_object| {
245                        let mut new_data_object = DataObject::new();
246                        new_data_object.set_data(&data_object.borrow()).unwrap();
247
248                        DataObjectRef::new(new_data_object)
249                    }).collect::<Vec<_>>());
250
251            combined_argument_list = new_combined_argument_list;
252        }
253
254        if self.var_args_parameter.is_some() {
255            //Infinite combinator functions (= Combinator functions with var args argument) must be called exactly two times
256            if self.combinator_function_call_count.is_none_or(|call_cnt| call_cnt > 0) &&
257                    combined_argument_list.len() < arg_cnt - 1 {
258                return Some(interpreter.set_errno_error_object(
259                    InterpretingError::InvalidArgCount,
260                    Some(&format!("Not enough arguments (at least {arg_cnt} needed)")),
261                    CodePosition::EMPTY,
262                ));
263            }
264        }else {
265            if self.combinator_function_call_count.is_none() && combined_argument_list.len() < arg_cnt {
266                return Some(interpreter.set_errno_error_object(
267                    InterpretingError::InvalidArgCount,
268                    Some(&format!("Not enough arguments ({arg_cnt} needed)")),
269                    CodePosition::EMPTY,
270                ));
271            }
272
273            if combined_argument_list.len() > arg_cnt {
274                return Some(interpreter.set_errno_error_object(
275                    InterpretingError::InvalidArgCount,
276                    Some(&format!("Too many arguments ({arg_cnt} needed)")),
277                    CodePosition::EMPTY,
278                ));
279            }
280        }
281
282        let mut native_function_args = Vec::with_capacity(arg_cnt);
283        let mut argument_index = 0;
284        'outer:
285        for i in 0..arg_cnt {
286            if let Some(call_cnt) = self.combinator_function_call_count
287                && argument_index >= combined_argument_list.len() &&
288                        (self.var_args_parameter.is_none() || call_cnt == 0) {
289                    return Some(self.combinator_call(
290                        this_object_with_super_level,
291                        combined_argument_list,
292                    ));
293                }
294
295            let parameter = &self.parameter_list[i];
296
297            let variable_name = &parameter.parameter_name;
298
299            let is_ignore_type_check = matches!(parameter.parameter_type,
300                ParameterType::CallByPointer | ParameterType::VarArgs | ParameterType::RawVarArgs);
301
302            if !is_ignore_type_check && !parameter.type_constraint.
303                    is_type_allowed(combined_argument_list[argument_index].data_type()) {
304                return Some(interpreter.set_errno_error_object(
305                    InterpretingError::InvalidArguments,
306                    Some(&format!(
307                        "The type of argument {} (\"{}\") must be one of [{}]",
308                        argument_index + 1,
309                        variable_name,
310                        parameter.type_constraint.allowed_types().iter().
311                                map(|data_type| data_type.to_string()).
312                                collect::<Vec<_>>().
313                                join(", "),
314                    )),
315                    CodePosition::EMPTY,
316                ));
317            }
318
319            let number_data_object = if matches!(parameter.parameter_type, ParameterType::Number) {
320                let number = conversions::to_number(
321                    interpreter,
322                    &combined_argument_list[argument_index],
323                    CodePosition::EMPTY,
324                );
325
326                if number.is_none() {
327                    return Some(interpreter.set_errno_error_object(
328                        InterpretingError::NoNum,
329                        Some(&format!(
330                            "Argument {} (\"{}\") must be a number",
331                            argument_index + 1,
332                            variable_name,
333                        )),
334                        CodePosition::EMPTY,
335                    ));
336                }
337
338                number.map(|number| {
339                    let mut number_data_object = DataObject::new();
340                    number_data_object.set_number(number).unwrap();
341
342                    DataObjectRef::new(number_data_object)
343                })
344            }else {
345                None
346            };
347
348            if matches!(parameter.parameter_type, ParameterType::Callable) &&
349                    !utils::is_callable(&combined_argument_list[argument_index]) {
350                return Some(interpreter.set_errno_error_object(
351                    InterpretingError::InvalidArguments,
352                    Some(&format!(
353                        "Argument {} (\"{}\") must be callable",
354                        argument_index + 1,
355                        variable_name,
356                    )),
357                    CodePosition::EMPTY,
358                ));
359            }
360
361            let ret = 'error: {
362                match parameter.parameter_type {
363                    ParameterType::RawVarArgs => {
364                        native_function_args.append(&mut argument_list);
365
366                        //There can only be one parameter if raw var args is used
367                        break 'outer;
368                    },
369
370                    ParameterType::VarArgs => {
371                        //Infinite combinator functions (= Combinator functions with var args argument) must be called exactly two times
372                        if self.combinator_function_call_count.is_some_and(|call_cnt| call_cnt == 0) {
373                            return Some(self.combinator_call(
374                                this_object_with_super_level,
375                                combined_argument_list,
376                            ));
377                        }
378
379                        let mut var_args_argument_list = combined_argument_list[i..combined_argument_list.len() + i + 1 - arg_cnt].iter().
380                                map(|data_object| {
381                                    let mut new_data_object = DataObject::new();
382                                    new_data_object.set_data(&data_object.borrow()).unwrap();
383
384                                    DataObjectRef::new(new_data_object)
385                                }).collect::<Vec<_>>();
386
387                        if !matches!(self.var_args_parameter, Some((_, VarArgsType::Text))) {
388                            for (j, arg) in var_args_argument_list.iter().
389                                    enumerate() {
390                                if !parameter.type_constraint.is_type_allowed(arg.data_type()) {
391                                    return Some(interpreter.set_errno_error_object(
392                                        InterpretingError::InvalidArguments,
393                                        Some(&format!(
394                                            "The type of argument {} (for var args parameter \"{}\") must be one of [{}]",
395                                            i + j + 1,
396                                            variable_name,
397                                            parameter.type_constraint.allowed_types().iter().
398                                                    map(|data_type| data_type.to_string()).
399                                                    collect::<Vec<_>>().
400                                                    join(", "),
401                                        )),
402                                        CodePosition::EMPTY,
403                                    ));
404                                }
405                            }
406                        }
407
408                        if matches!(self.var_args_parameter, Some((_, VarArgsType::Text))) {
409                            let mut argument_list_copy = VecDeque::from(argument_list.clone());
410
411                            //Remove leading arguments
412                            for _ in 0..i {
413                                for _ in 0..argument_list_copy.len() {
414                                    if argument_list_copy.pop_front().
415                                            is_some_and(|val| val.
416                                                    data_type() == DataType::ARGUMENT_SEPARATOR) {
417                                        break;
418                                    }
419                                }
420                            }
421
422                            //Remove trailing arguments
423                            for _ in 0..arg_cnt - i - 1 {
424                                for k in (0..argument_list_copy.len()).rev() {
425                                    if argument_list_copy.remove(k).
426                                            is_some_and(|val| val.
427                                                    data_type() == DataType::ARGUMENT_SEPARATOR) {
428                                        break;
429                                    }
430                                }
431                            }
432
433                            let combined_arguments = utils::combine_data_objects(
434                                argument_list_copy.make_contiguous(),
435                                interpreter,
436                                CodePosition::EMPTY,
437                            );
438
439                            let text = combined_arguments.map(|arg| conversions::to_text(
440                                interpreter,
441                                &arg,
442                                CodePosition::EMPTY,
443                            )).unwrap_or_default();
444
445                            let mut argument = DataObject::new_text(text);
446                            let ret = argument.set_variable_name(
447                                Some(variable_name),
448                            );
449                            if ret.is_err() {
450                                break 'error ret.map(|_| ());
451                            }
452
453                            native_function_args.push(DataObjectRef::new(argument));
454                        }else {
455                            native_function_args.append(&mut var_args_argument_list);
456                        }
457
458                        //Not "+1", because argumentIndex will be incremented at the end of the for loop
459                        argument_index = (combined_argument_list.len() + i).wrapping_sub(arg_cnt);
460
461                        Ok(())
462                    },
463
464                    ParameterType::CallByPointer => {
465                        let mut argument = DataObject::new();
466                        let ret = argument.set_variable_name(
467                            Some(variable_name),
468                        );
469                        if ret.is_err() {
470                            break 'error ret.map(|_| ());
471                        }
472
473                        let ret = argument.set_var_pointer(
474                            combined_argument_list[argument_index].clone(),
475                        );
476                        if ret.is_err() {
477                            break 'error ret.map(|_| ());
478                        }
479
480                        let ret = argument.set_type_constraint(
481                            parameter.type_constraint.clone(),
482                        );
483                        if ret.is_err() {
484                            break 'error ret.map(|_| ());
485                        }
486
487                        native_function_args.push(DataObjectRef::new(argument));
488
489                        Ok(())
490                    },
491
492                    _ => {
493                        let mut argument = DataObject::new();
494
495                        let ret = if let Some(number_data_object) = &number_data_object {
496                            argument.set_data(&number_data_object.borrow())
497                        }else {
498                            argument.set_data(&combined_argument_list[argument_index].borrow())
499                        };
500                        if ret.is_err() {
501                            break 'error ret.map(|_| ());
502                        }
503
504                        let ret = argument.set_variable_name(
505                            Some(variable_name),
506                        );
507                        if ret.is_err() {
508                            break 'error ret.map(|_| ());
509                        }
510
511                        let ret = argument.set_type_constraint(
512                            parameter.type_constraint.clone(),
513                        );
514                        if ret.is_err() {
515                            break 'error ret.map(|_| ());
516                        }
517
518                        native_function_args.push(DataObjectRef::new(argument));
519
520                        Ok(())
521                    },
522                }
523            };
524            if let Err(e) = ret {
525                return Some(interpreter.set_errno_error_object(
526                    InterpretingError::IncompatibleDataType,
527                    Some(&e.message),
528                    CodePosition::EMPTY,
529                ));
530            }
531
532            argument_index = argument_index.wrapping_add(1);
533        }
534
535        let ret = function.function_body().lang_call(
536            interpreter,
537            this_object_with_super_level.map(|(this_object, _)| this_object),
538            native_function_args,
539        );
540
541        if let Err(ret) = ret {
542            //TODO print stack trace if enabled
543
544            return Some(interpreter.set_errno_error_object(
545                InterpretingError::SystemError,
546                Some(&format!("Native Error: {}", ret)),
547                CodePosition::EMPTY,
548            ));
549        };
550
551        let ret = ret.unwrap();
552
553        if let Some(type_constraint) = &self.return_value_type_constraint
554            && !interpreter.is_thrown_value() {
555                //Thrown values are always allowed
556
557                let ret = utils::none_to_lang_void(ret.clone());
558                if !type_constraint.is_type_allowed(ret.data_type()) {
559                    return Some(interpreter.set_errno_error_object(
560                        InterpretingError::IncompatibleDataType,
561                        Some(&format!("Invalid return value type \"{}\"", ret.data_type())),
562                        CodePosition::EMPTY,
563                    ));
564                }
565            }
566
567        ret
568    }
569
570    pub(crate) fn combinator_call(
571        &self,
572        this_object_with_super_level: Option<(LangObjectRef, usize)>,
573        combined_argument_list: Vec<DataObjectRef>,
574    ) -> DataObjectRef {
575        let function_name = combined_argument_list.iter().
576                map(|data_object| {
577                    let Some(func) = data_object.function_pointer_value() else {
578                        return "<arg>".to_string();
579                    };
580
581                    if let Some(function_name) = &func.function_name {
582                        function_name.to_string()
583                    }else {
584                        data_object.variable_name().map(|str| str.to_string()).unwrap_or("null".to_string())
585                    }
586                }).collect::<Vec<_>>().join(", ");
587
588        let function_name = "<".to_string() + self.var_args_parameter.map_or("", |_| "inf-") +
589                self.function_name.as_deref().unwrap_or("null") + "-func(" + &function_name + ")>";
590
591        let function = Function {
592            function: Gc::clone(&self.function),
593
594            parameter_list: self.parameter_list.clone(),
595
596            var_args_parameter: self.var_args_parameter,
597
598            return_value_type_constraint: self.return_value_type_constraint.clone(),
599
600            combinator_function_call_count: self.combinator_function_call_count.map(|cnt| cnt + 1),
601            combinator_function_provided_arguments: combined_argument_list,
602
603            function_name: self.function_name.clone(),
604        };
605
606        let mut fp = FunctionPointerObject::new_with_function_name(&function_name, function);
607
608        if let Some((this_object, super_level)) = this_object_with_super_level {
609            fp = FunctionPointerObject::copy_with_this_object(&fp, this_object).unwrap().
610                    copy_with_mapped_functions(|function|
611                            InternalFunction::copy_with_super_level(function, super_level));
612        }
613
614        DataObjectRef::new(DataObject::with_update(|data_object| {
615            data_object.set_function_pointer(Gc::new(fp))
616        }).unwrap())
617    }
618
619    pub fn is_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
620        match (self.var_args_parameter, other.var_args_parameter) {
621            (Some((s_index, s_var_args_type)), Some((o_index, o_var_args_type))) => {
622                if s_index != o_index || (matches!(s_var_args_type, VarArgsType::Text) != matches!(o_var_args_type, VarArgsType::Text)) {
623                    return false;
624                }
625            },
626
627            (None, None) => {},
628
629            _ => {
630                return false;
631            },
632        }
633
634        self.function.is_equals(other.function.as_ref(), interpreter, pos) &&
635                self.parameter_list.len() == other.parameter_list.len() &&
636                self.parameter_list.iter().zip(other.parameter_list.iter()).
637                        all(|(s, o)|s.is_equals(o, interpreter, pos)) &&
638                self.combinator_function_provided_arguments.len() == other.combinator_function_provided_arguments.len() &&
639                self.combinator_function_provided_arguments.iter().zip(other.combinator_function_provided_arguments.iter()).
640                        all(|(s, o)|operators::is_equals(interpreter, s, o, pos))
641    }
642
643    pub fn is_strict_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
644        match (self.var_args_parameter, other.var_args_parameter) {
645            (Some((s_index, s_var_args_type)), Some((o_index, o_var_args_type))) => {
646                if s_index != o_index || (matches!(s_var_args_type, VarArgsType::Text) != matches!(o_var_args_type, VarArgsType::Text)) {
647                    return false;
648                }
649            },
650
651            (None, None) => {},
652
653            _ => {
654                return false;
655            },
656        }
657
658        self.function.is_strict_equals(other.function.as_ref(), interpreter, pos) &&
659                self.parameter_list.len() == other.parameter_list.len() &&
660                self.parameter_list.iter().zip(other.parameter_list.iter()).
661                        all(|(s, o)|s.is_strict_equals(o, interpreter, pos)) &&
662                self.combinator_function_provided_arguments.len() == other.combinator_function_provided_arguments.len() &&
663                self.combinator_function_provided_arguments.iter().zip(other.combinator_function_provided_arguments.iter()).
664                        all(|(s, o)|operators::is_strict_equals(interpreter, s, o, pos))
665    }
666
667    pub fn to_function_signature_string(&self) -> String {
668        let mut builder = String::new();
669
670        builder += "(";
671
672        for parameter in self.parameter_list.iter() {
673            let variable_name = &parameter.parameter_name;
674
675            if matches!(parameter.parameter_type, ParameterType::CallByPointer) {
676                if variable_name.is_empty() {
677                    builder += "$[]";
678                }else {
679                    let _ = write!(builder, "$[{}]", &variable_name[1..variable_name.len()]);
680                }
681            }else {
682                builder += variable_name;
683            }
684
685            match parameter.parameter_type {
686                ParameterType::VarArgs => {
687                    if *parameter.type_constraint != *data::CONSTRAINT_NORMAL {
688                        builder += &parameter.type_constraint.to_type_constraint_syntax();
689                    }
690
691                    builder += "...";
692                },
693
694                ParameterType::RawVarArgs => {
695                    if *parameter.type_constraint != *data::CONSTRAINT_NORMAL {
696                        builder += &parameter.type_constraint.to_type_constraint_syntax();
697                    }
698
699                    builder += "...{raw}";
700                },
701
702                ParameterType::Number => {
703                    builder += "{number}";
704                },
705
706                ParameterType::Callable => {
707                    builder += "{callable}";
708                },
709
710                ParameterType::Boolean => {
711                    builder += "{boolean}";
712                },
713
714                _ => {
715                    if *parameter.type_constraint != *DataObject::get_type_constraint_for(Some(variable_name)) {
716                        builder += &parameter.type_constraint.to_type_constraint_syntax();
717                    }
718                },
719            }
720
721            builder += ", ";
722        }
723
724        if !self.parameter_list.is_empty() {
725            builder = builder[..builder.len() - 2].to_string();
726        }
727
728        builder += ")";
729
730        builder
731    }
732
733    pub fn function(&self) -> &FunctionData {
734        &self.function
735    }
736
737    pub fn parameter_list(&self) -> &[Parameter] {
738        &self.parameter_list
739    }
740
741    pub fn var_args_parameter(&self) -> Option<(usize, VarArgsType)> {
742        self.var_args_parameter
743    }
744
745    pub fn return_value_type_constraint(&self) -> Option<&DataTypeConstraint> {
746        self.return_value_type_constraint.as_deref()
747    }
748
749    pub fn combinator_function_call_count(&self) -> Option<usize> {
750        self.combinator_function_call_count
751    }
752
753    pub fn combinator_function_provided_arguments(&self) -> &[DataObjectRef] {
754        &self.combinator_function_provided_arguments
755    }
756
757    pub fn function_name(&self) -> Option<&str> {
758        self.function_name.as_deref()
759    }
760}
761
762#[derive(Debug, Clone, Trace, Finalize)]
763pub struct InternalFunction {
764    super_level: Option<usize>,
765
766    function: Gc<Function>,
767
768    member_of_class: OptionLangObjectRef,
769    //SAFETY: There are no GC reference inside DeprecationInfo
770    #[unsafe_ignore_trace]
771    member_visibility: Option<Visibility>,
772}
773
774impl InternalFunction {
775    pub fn new(function: Gc<Function>) -> Self {
776        Self {
777            super_level: None,
778
779            function,
780
781            member_of_class: None,
782            member_visibility: None,
783        }
784    }
785
786    #[must_use]
787    pub(crate) fn copy_with_class_member_attributes(
788        &self,
789        member_of_class: LangObjectRef,
790        member_visibility: Visibility
791    ) -> Self {
792        Self {
793            super_level: self.super_level,
794
795            function: self.function.clone(),
796
797            member_of_class: Some(member_of_class),
798            member_visibility: Some(member_visibility),
799        }
800    }
801
802    #[must_use]
803    pub(crate) fn copy_with_super_level(
804        &self,
805        super_level: usize,
806    ) -> Self {
807        Self {
808            super_level: Some(super_level),
809
810            function: self.function.clone(),
811
812            member_of_class: self.member_of_class.clone(),
813            member_visibility: self.member_visibility,
814        }
815    }
816
817    pub fn is_accessible(&self, accessing_class: Option<&LangObjectRef>) -> bool {
818        let Some(member_of_class) = &self.member_of_class else {
819            return true;
820        };
821
822        let Some(member_visibility) = self.member_visibility else {
823            return true;
824        };
825
826        if member_visibility == Visibility::Public {
827            return true;
828        }
829
830        let Some(accessing_class) = accessing_class else {
831            return false;
832        };
833
834        ptr::eq(accessing_class.borrow().deref(), member_of_class.borrow().deref()) || (
835            member_visibility == Visibility::Protected &&
836                    accessing_class.borrow().is_instance_of(member_of_class.borrow().deref())
837        )
838    }
839
840    pub fn to_function_signature_string(&self) -> String {
841        self.function.to_function_signature_string()
842    }
843
844    pub fn lang_path(&self) -> Option<&str> {
845        match self.function.function.as_ref() {
846            FunctionData::Normal(function) => function.lang_path(),
847
848            _ => None,
849        }
850    }
851
852    pub fn lang_file(&self) -> Option<&str> {
853        match self.function.function.as_ref() {
854            FunctionData::Normal(function) => function.lang_file(),
855
856            _ => None,
857        }
858    }
859
860    pub fn is_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
861        self.super_level == other.super_level &&
862                self.function.is_equals(other.function.as_ref(), interpreter, pos)
863    }
864
865    pub fn is_strict_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
866        self.super_level == other.super_level &&
867                self.function.is_strict_equals(other.function.as_ref(), interpreter, pos)
868    }
869
870    pub fn super_level(&self) -> Option<usize> {
871        self.super_level
872    }
873
874    pub fn function(&self) -> &Function {
875        self.function.as_ref()
876    }
877
878    pub fn member_of_class(&self) -> Option<&LangObjectRef> {
879        self.member_of_class.as_ref()
880    }
881
882    pub fn member_visibility(&self) -> Option<Visibility> {
883        self.member_visibility
884    }
885}
886
887#[derive(Debug, Clone, Trace, Finalize)]
888pub struct FunctionPointerObject {
889    this_object: OptionLangObjectRef,
890
891    function_name: Option<Box<str>>,
892    function_info: Option<Box<str>>,
893
894    linker_function: bool,
895    //SAFETY: There are no GC reference inside DeprecationInfo
896    #[unsafe_ignore_trace]
897    deprecated: Option<DeprecationInfo>,
898
899    functions: Vec<InternalFunction>,
900}
901
902impl FunctionPointerObject {
903    pub fn create_function_pointer_objects_from_native_functions(
904        mut functions: Vec<(FunctionMetadata, Function)>,
905    ) -> HashMap<Box<str>, Self> {
906        let mut functions_by_name = HashMap::new();
907
908        //Functions with the "has_info" contain the metadata for the function pointer object.
909        //They must be inserted before the functions without "has_info".
910        functions.sort_unstable_by_key(|(metadata, _)| !metadata.has_info);
911
912        for (metadata, function) in functions.into_iter() {
913            let function_name = function.function_name.as_ref().expect("Function name may not be None");
914
915            let entry = functions_by_name.entry(function_name.clone());
916            let vec = entry.or_insert(Vec::new());
917            vec.push((metadata, function));
918        }
919
920        let mut function_map = HashMap::new();
921
922        for (function_name, functions) in functions_by_name {
923            let (metadata, functions): (Vec<FunctionMetadata>, Vec<InternalFunction>) = functions.
924                    into_iter().
925                    map(|(metadata, function)|
926                            (metadata, InternalFunction::new(Gc::new(function)))).
927                    unzip();
928
929            #[cfg(debug_assertions)]
930            {
931                if functions.len() == 1 && metadata.iter().
932                        map(|metadata| metadata.has_info as u32).
933                        sum::<u32>() > 0 {
934                    panic!("has_info can only be used if there are at least two functions (Invalid for function: {function_name})");
935                }
936
937                if functions.len() > 1 && metadata.iter().
938                        map(|metadata| metadata.has_info as u32).
939                        sum::<u32>() != 1 {
940                    panic!("has_info can only be once (Invalid for function: {function_name})");
941                }
942            }
943
944            function_map.insert(function_name, FunctionPointerObject::new_with_functions(
945                None,
946                &functions,
947                &metadata[0],
948            ).unwrap());
949        }
950
951        function_map
952    }
953
954    pub(crate) fn new_dummy_definition() -> Self {
955        Self {
956            this_object: None,
957
958            function_name: None,
959            function_info: None,
960            linker_function: false,
961            deprecated: None,
962            functions: Vec::new(),
963        }
964    }
965
966    pub fn new(metadata: &FunctionMetadata, func: Function) -> Self {
967        Self {
968            this_object: None,
969
970            function_name: metadata.function_name.clone(),
971            function_info: metadata.function_info.clone(),
972
973            linker_function: metadata.linker_function,
974            deprecated: metadata.deprecated.clone(),
975
976            functions: vec![
977                InternalFunction::new(Gc::new(func)),
978            ],
979        }
980    }
981
982    pub fn new_with_function_name(function_name: &str, func: Function) -> Self {
983        Self {
984            this_object: None,
985
986            function_name: Some(Box::from(function_name)),
987            function_info: None,
988
989            linker_function: false,
990            deprecated: None,
991
992            functions: vec![
993                InternalFunction::new(Gc::new(func)),
994            ],
995        }
996    }
997
998    pub fn new_with_functions(
999        this_object: OptionLangObjectRef,
1000        functions: &[InternalFunction],
1001        metadata: &FunctionMetadata,
1002    ) -> Result<Self, DataTypeConstraintError> {
1003        if let Some(this_object) = &this_object
1004            && this_object.borrow().is_class() {
1005                return Err(DataTypeConstraintError::with_message(
1006                    "The this-object must be an object",
1007                ));
1008            }
1009
1010        Ok(Self {
1011            this_object,
1012
1013            function_name: metadata.function_name.clone(),
1014            function_info: metadata.function_info.clone(),
1015
1016            linker_function: metadata.linker_function,
1017            deprecated: metadata.deprecated.clone(),
1018
1019            functions: Vec::from(functions),
1020        })
1021    }
1022
1023    pub(crate) fn copy_with_this_object(
1024        func: &Self,
1025        this_object: LangObjectRef,
1026    ) -> Result<Self, DataTypeConstraintError> {
1027        if this_object.borrow().is_class() {
1028            return Err(DataTypeConstraintError::with_message(
1029                "The this-object must be an object",
1030            ));
1031        }
1032
1033        Ok(Self {
1034            this_object: Some(this_object),
1035
1036            function_name: func.function_name.clone(),
1037            function_info: func.function_info.clone(),
1038
1039            linker_function: func.linker_function,
1040            deprecated: func.deprecated.clone(),
1041
1042            functions: func.functions.clone(),
1043        })
1044    }
1045
1046    #[must_use]
1047    pub fn copy_with_function_name(&self, function_name: &str) -> Self {
1048        Self {
1049            this_object: self.this_object.clone(),
1050
1051            function_name: Some(Box::from(function_name)),
1052            function_info: self.function_info.clone(),
1053
1054            linker_function: self.linker_function,
1055            deprecated: self.deprecated.clone(),
1056
1057            functions: self.functions.clone(),
1058        }
1059    }
1060
1061    #[must_use]
1062    pub fn copy_with_function_info(&self, function_info: &str) -> Self {
1063        Self {
1064            this_object: self.this_object.clone(),
1065
1066            function_name: self.function_name.clone(),
1067            function_info: Some(Box::from(function_info)),
1068
1069            linker_function: self.linker_function,
1070            deprecated: self.deprecated.clone(),
1071
1072            functions: self.functions.clone(),
1073        }
1074    }
1075
1076    #[must_use]
1077    pub fn copy_with_linker(&self, linker_function: bool) -> Self {
1078        Self {
1079            this_object: self.this_object.clone(),
1080
1081            function_name: self.function_name.clone(),
1082            function_info: self.function_info.clone(),
1083
1084            linker_function,
1085            deprecated: self.deprecated.clone(),
1086
1087            functions: self.functions.clone(),
1088        }
1089    }
1090
1091    #[must_use]
1092    pub fn copy_with_deprecation_info(&self, deprecated: DeprecationInfo) -> Self {
1093        Self {
1094            this_object: self.this_object.clone(),
1095
1096            function_name: self.function_name.clone(),
1097            function_info: self.function_info.clone(),
1098
1099            linker_function: self.linker_function,
1100            deprecated: Some(deprecated),
1101
1102            functions: self.functions.clone(),
1103        }
1104    }
1105
1106    #[must_use]
1107    pub fn copy_with_functions(&self, functions: &[InternalFunction]) -> Self {
1108        Self {
1109            this_object: self.this_object.clone(),
1110
1111            function_name: self.function_name.clone(),
1112            function_info: self.function_info.clone(),
1113
1114            linker_function: self.linker_function,
1115            deprecated: self.deprecated.clone(),
1116
1117            functions: Vec::from(functions),
1118        }
1119    }
1120
1121    #[must_use]
1122    pub fn copy_with_added_function(&self, function: InternalFunction) -> Self {
1123        let mut functions = self.functions.clone();
1124        functions.push(function);
1125
1126        Self {
1127            this_object: self.this_object.clone(),
1128
1129            function_name: self.function_name.clone(),
1130            function_info: self.function_info.clone(),
1131
1132            linker_function: self.linker_function,
1133            deprecated: self.deprecated.clone(),
1134
1135            functions,
1136        }
1137    }
1138
1139    #[must_use]
1140    pub fn copy_with_added_functions(&self, function_pointer_object: &Self) -> Self {
1141        let mut functions = self.functions.clone();
1142        functions.append(&mut function_pointer_object.functions.clone());
1143
1144        Self {
1145            this_object: self.this_object.clone(),
1146
1147            function_name: self.function_name.clone(),
1148            function_info: self.function_info.clone(),
1149
1150            linker_function: self.linker_function,
1151            deprecated: self.deprecated.clone(),
1152
1153            functions,
1154        }
1155    }
1156
1157    #[must_use]
1158    pub fn copy_with_mapped_functions(&self, mapper: impl FnMut(&InternalFunction) -> InternalFunction) -> Self {
1159        let functions = self.functions.iter().
1160                map(mapper).
1161                collect();
1162
1163        Self {
1164            this_object: self.this_object.clone(),
1165
1166            function_name: self.function_name.clone(),
1167            function_info: self.function_info.clone(),
1168
1169            linker_function: self.linker_function,
1170            deprecated: self.deprecated.clone(),
1171
1172            functions,
1173        }
1174    }
1175
1176    pub fn is_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
1177        match (&self.this_object, &other.this_object) {
1178            (Some(s), Some(o)) => {
1179                //Check for same reference of thisObjects
1180                if !ptr::eq(s.borrow().deref(), o.borrow().deref()) {
1181                    return false;
1182                }
1183            },
1184
1185            (None, None) => {},
1186
1187            _ => {
1188                return false;
1189            },
1190        }
1191
1192        self.functions.len() == other.functions.len() &&
1193                self.functions.iter().zip(other.functions.iter()).
1194                        all(|(s, o)|s.is_equals(o, interpreter, pos))
1195    }
1196
1197    pub fn is_strict_equals(&self, other: &Self, interpreter: &mut Interpreter, pos: CodePosition) -> bool {
1198        match (&self.this_object, &other.this_object) {
1199            (Some(s), Some(o)) => {
1200                //Check for same reference of thisObjects
1201                if !ptr::eq(s.borrow().deref(), o.borrow().deref()) {
1202                    return false;
1203                }
1204            },
1205
1206            (None, None) => {},
1207
1208            _ => {
1209                return false;
1210            },
1211        }
1212
1213        self.functions.len() == other.functions.len() &&
1214                self.functions.iter().zip(other.functions.iter()).
1215                        all(|(s, o)|s.is_strict_equals(o, interpreter, pos))
1216    }
1217
1218    pub fn this_object(&self) -> Option<&LangObjectRef> {
1219        self.this_object.as_ref()
1220    }
1221
1222    pub fn function_name(&self) -> Option<&str> {
1223        self.function_name.as_deref()
1224    }
1225
1226    pub fn function_info(&self) -> Option<&str> {
1227        self.function_info.as_deref()
1228    }
1229
1230    pub fn linker_function(&self) -> bool {
1231        self.linker_function
1232    }
1233
1234    pub fn deprecated(&self) -> Option<&DeprecationInfo> {
1235        self.deprecated.as_ref()
1236    }
1237
1238    pub fn functions(&self) -> &[InternalFunction] {
1239        &self.functions
1240    }
1241
1242    pub(crate) fn functions_mut(&mut self) -> &mut [InternalFunction] {
1243        &mut self.functions
1244    }
1245
1246    pub fn get_function(&self, index: usize) -> Option<&InternalFunction> {
1247        self.functions.get(index)
1248    }
1249
1250    pub fn get_overloaded_function_count(&self) -> usize {
1251        self.functions.len()
1252    }
1253}
1254
1255impl Display for FunctionPointerObject {
1256    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1257        if let Some(function_name) = &self.function_name {
1258            return f.write_str(function_name);
1259        }
1260
1261        f.write_str(if self.this_object.is_some() {
1262            "<Method>"
1263        }else {
1264            "<Function>"
1265        })
1266    }
1267}
1268
1269impl From<(FunctionMetadata, Function)> for FunctionPointerObject {
1270    fn from((metadata, func): (FunctionMetadata, Function)) -> Self {
1271        Self::new(&metadata, func)
1272    }
1273}
1274
1275impl From<(&FunctionMetadata, Function)> for FunctionPointerObject {
1276    fn from((metadata, func): (&FunctionMetadata, Function)) -> Self {
1277        Self::new(metadata, func)
1278    }
1279}
1280
1281#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
1282pub enum ParameterType {
1283    Normal,
1284    Number,
1285    Callable,
1286    Boolean,
1287    CallByPointer,
1288    VarArgs,
1289    RawVarArgs,
1290}
1291
1292#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
1293pub enum VarArgsType {
1294    Normal,
1295    Text,
1296    Raw,
1297}
1298
1299#[derive(Debug, Clone)]
1300pub struct Parameter {
1301    parameter_name: Box<str>,
1302    parameter_info: Option<Box<str>>,
1303    type_constraint: Box<DataTypeConstraint>,
1304    parameter_type: ParameterType,
1305}
1306
1307impl Parameter {
1308    pub fn new(
1309        parameter_name: &str,
1310        parameter_info: Option<&str>,
1311        type_constraint: Box<DataTypeConstraint>,
1312        parameter_type: ParameterType,
1313    ) -> Self {
1314        Self {
1315            parameter_name: Box::from(parameter_name),
1316            parameter_info: parameter_info.map(Box::from),
1317            type_constraint,
1318            parameter_type,
1319        }
1320    }
1321
1322    pub fn is_equals(&self, other: &Self, _interpreter: &mut Interpreter, _pos: CodePosition) -> bool {
1323        self.parameter_name == other.parameter_name && self.type_constraint == other.type_constraint &&
1324                self.parameter_type == other.parameter_type
1325    }
1326
1327    pub fn is_strict_equals(&self, other: &Self, _interpreter: &mut Interpreter, _pos: CodePosition) -> bool {
1328        self.parameter_name == other.parameter_name && self.type_constraint == other.type_constraint &&
1329                self.parameter_type == other.parameter_type
1330    }
1331
1332    pub fn parameter_name(&self) -> &str {
1333        &self.parameter_name
1334    }
1335
1336    pub fn parameter_info(&self) -> Option<&str> {
1337        self.parameter_info.as_deref()
1338    }
1339
1340    pub fn type_constraint(&self) -> &DataTypeConstraint {
1341        &self.type_constraint
1342    }
1343
1344    pub fn parameter_type(&self) -> ParameterType {
1345        self.parameter_type
1346    }
1347}
1348
1349impl From<ParameterMetadata> for Parameter {
1350    fn from(value: ParameterMetadata) -> Self {
1351        let type_constraint = value.type_constraint.map(Box::new).
1352                unwrap_or_else(|| if matches!(value.parameter_type, ParameterType::VarArgs | ParameterType::RawVarArgs) {
1353                    Box::new(data::CONSTRAINT_NORMAL.clone())
1354                }else {
1355                    Box::new(DataObject::get_type_constraint_for(Some(&value.parameter_name)).clone())
1356                });
1357
1358        Self {
1359            parameter_name: value.parameter_name,
1360            parameter_info: value.parameter_info,
1361            type_constraint,
1362            parameter_type: value.parameter_type,
1363        }
1364    }
1365}
1366
1367#[derive(Debug, Clone)]
1368pub struct DeprecationInfo {
1369    remove_version: Option<Box<str>>,
1370    replacement_function: Option<Box<str>>,
1371}
1372
1373impl DeprecationInfo {
1374    pub fn new(remove_version: Option<&str>, replacement_function: Option<&str>) -> Self {
1375        Self {
1376            remove_version: remove_version.map(Box::from),
1377            replacement_function: replacement_function.map(Box::from),
1378        }
1379    }
1380
1381    pub fn remove_version(&self) -> Option<&str> {
1382        self.remove_version.as_deref()
1383    }
1384
1385    pub fn replacement_function(&self) -> Option<&str> {
1386        self.replacement_function.as_deref()
1387    }
1388}
1389
1390#[derive(Debug, Clone)]
1391pub struct ParameterMetadata {
1392    parameter_name: Box<str>,
1393    parameter_info: Option<Box<str>>,
1394    type_constraint: Option<DataTypeConstraint>,
1395    parameter_type: ParameterType,
1396}
1397
1398impl ParameterMetadata {
1399    pub fn new(
1400        parameter_name: &str,
1401        parameter_info: Option<&str>,
1402        type_constraint: Option<DataTypeConstraint>,
1403        parameter_type: ParameterType,
1404    ) -> Self {
1405        Self {
1406            parameter_name: Box::from(parameter_name),
1407            parameter_info: parameter_info.map(Box::from),
1408            type_constraint,
1409            parameter_type,
1410        }
1411    }
1412
1413    pub fn parameter_name(&self) -> &str {
1414        &self.parameter_name
1415    }
1416
1417    pub fn parameter_info(&self) -> Option<&str> {
1418        self.parameter_info.as_deref()
1419    }
1420
1421    pub fn type_constraint(&self) -> Option<&DataTypeConstraint> {
1422        self.type_constraint.as_ref()
1423    }
1424
1425    pub fn parameter_type(&self) -> ParameterType {
1426        self.parameter_type
1427    }
1428}
1429
1430#[derive(Debug, Clone)]
1431pub struct FunctionMetadata {
1432    function_name: Option<Box<str>>,
1433    function_info: Option<Box<str>>,
1434
1435    has_info: bool,
1436
1437    combinator_function: bool,
1438
1439    linker_function: bool,
1440    deprecated: Option<DeprecationInfo>,
1441
1442    parameter_list: Vec<ParameterMetadata>,
1443
1444    return_value_type_constraint: Option<DataTypeConstraint>,
1445}
1446
1447impl FunctionMetadata {
1448    #[expect(clippy::too_many_arguments)]
1449    pub fn new(
1450        function_name: Option<&str>,
1451        function_info: Option<&str>,
1452
1453        has_info: bool,
1454
1455        combinator_function: bool,
1456
1457        linker_function: bool,
1458        deprecated: Option<DeprecationInfo>,
1459
1460        parameter_list: Vec<ParameterMetadata>,
1461
1462        return_value_type_constraint: Option<DataTypeConstraint>,
1463    ) -> Self {
1464        Self {
1465            function_name: function_name.map(Box::from),
1466            function_info: function_info.map(Box::from),
1467
1468            has_info,
1469            combinator_function,
1470
1471            linker_function,
1472            deprecated,
1473
1474            parameter_list,
1475
1476            return_value_type_constraint,
1477        }
1478    }
1479
1480    pub fn function_name(&self) -> Option<&str> {
1481        self.function_name.as_deref()
1482    }
1483
1484    pub fn function_info(&self) -> Option<&str> {
1485        self.function_info.as_deref()
1486    }
1487
1488    pub fn has_info(&self) -> bool {
1489        self.has_info
1490    }
1491
1492    pub fn combinator_function(&self) -> bool {
1493        self.combinator_function
1494    }
1495
1496    pub fn linker_function(&self) -> bool {
1497        self.linker_function
1498    }
1499
1500    pub fn deprecated(&self) -> Option<&DeprecationInfo> {
1501        self.deprecated.as_ref()
1502    }
1503
1504    pub fn parameter_list(&self) -> &[ParameterMetadata] {
1505        &self.parameter_list
1506    }
1507
1508    pub fn return_value_type_constraint(&self) -> Option<&DataTypeConstraint> {
1509        self.return_value_type_constraint.as_ref()
1510    }
1511}