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