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 lang_path: Option<Box<str>>,
24
25 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 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 #[unsafe_ignore_trace]
108 parameter_list: Vec<Parameter>,
109
110 #[unsafe_ignore_trace]
112 var_args_parameter: Option<(usize, VarArgsType)>,
113
114 #[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 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 = ¶meter.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 break 'outer;
368 },
369
370 ParameterType::VarArgs => {
371 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 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 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 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 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 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 = ¶meter.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 += ¶meter.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 += ¶meter.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 += ¶meter.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 #[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 #[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.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 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 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}