-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfunc.rs
More file actions
126 lines (102 loc) · 2.91 KB
/
Copy pathfunc.rs
File metadata and controls
126 lines (102 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::any::Any;
use std::fmt;
use std::sync::{Arc, RwLock};
use once_cell::sync::{Lazy, OnceCell};
use crate::modules::get_module;
use crate::vm::Code;
use super::gen;
use super::new;
use super::result::Params;
use super::base::{ObjectRef, ObjectTrait, TypeRef, TypeTrait};
use super::class::TYPE_TYPE;
use super::func_trait::FuncTrait;
use super::ns::Namespace;
// Function Type -------------------------------------------------------
gen::type_and_impls!(FuncType, Func);
pub static FUNC_TYPE: Lazy<gen::obj_ref_t!(FuncType)> =
Lazy::new(|| gen::obj_ref!(FuncType::new()));
// Func Object ----------------------------------------------------------
pub struct Func {
ns: Namespace,
module_name: String,
module: OnceCell<ObjectRef>,
name: String,
params: Params,
code: Code,
}
gen::standard_object_impls!(Func);
impl Func {
pub fn new(module_name: String, name: String, params: Params, code: Code) -> Self {
Self {
ns: Namespace::with_entries(&[
// Instance Attributes
("$module_name", new::str(&module_name)),
("$full_name", new::str(format!("{module_name}.{name}"))),
("$name", new::str(&name)),
("$doc", code.get_doc()),
]),
module_name,
module: OnceCell::default(),
name,
params,
code,
}
}
pub fn arg_names(&self) -> Vec<&str> {
let mut names = vec![];
for name in self.params.iter() {
if name.is_empty() {
names.push("$args");
} else {
names.push(name);
}
}
names
}
pub fn code(&self) -> &Code {
&self.code
}
}
impl FuncTrait for Func {
fn ns(&self) -> &Namespace {
&self.ns
}
fn module_name(&self) -> &String {
&self.module_name
}
fn module(&self) -> ObjectRef {
(self as &dyn ObjectTrait).module()
}
fn name(&self) -> &String {
&self.name
}
fn params(&self) -> &Params {
&self.params
}
}
impl ObjectTrait for Func {
gen::object_trait_header!(FUNC_TYPE);
fn module(&self) -> ObjectRef {
self.module.get_or_init(|| get_module(&self.module_name)).clone()
}
fn is_equal(&self, rhs: &dyn ObjectTrait) -> bool {
if self.is(rhs) || rhs.is_always() {
true
} else if let Some(f) = rhs.down_to_func() {
f.params == self.params && f.code == self.code
} else {
false
}
}
}
// Display -------------------------------------------------------------
impl fmt::Display for Func {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", FuncTrait::format_string(self, Some(self.id())))
}
}
impl fmt::Debug for Func {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self}")
}
}