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 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 = ¶meter.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 break 'outer;
369 },
370
371 ParameterType::VarArgs => {
372 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 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 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 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 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 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 = ¶meter.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 += ¶meter.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 += ¶meter.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 += ¶meter.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 #[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 #[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.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 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 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}