1use core::fmt::Debug;
2use std::{any::Any, cell::RefCell, collections::HashMap, rc::Rc};
3
4use crate::{
5 data::Data,
6 error::{Error, ErrorSource},
7 evaluator,
8 modules::loader::ModuleWrapper,
9 parser::PosNode,
10 util::make_ref,
11};
12
13use super::{Scope, ScopeRef};
14
15#[derive(Debug, Clone)]
16pub struct CallScope {
17 parent: ScopeRef,
18 arguments: Rc<Vec<Data>>,
19 body_fn: Rc<Option<Function>>,
20 from_scope: ScopeRef,
21}
22
23impl CallScope {
24 pub fn args(&self) -> Rc<Vec<Data>> {
25 Rc::clone(&self.arguments)
26 }
27
28 pub fn body_fn(&self) -> Rc<Option<Function>> {
29 Rc::clone(&self.body_fn)
30 }
31
32 pub fn from_scope(&self) -> ScopeRef {
33 Rc::clone(&self.from_scope)
34 }
35}
36
37impl Scope for CallScope {
38 fn has_function(&self, name: &str) -> bool {
39 RefCell::borrow(&self.parent).has_function(name)
40 }
41
42 fn get_function(&self, name: &str) -> Option<Function> {
43 RefCell::borrow(&self.parent).get_function(name)
44 }
45
46 fn set_function(&mut self, name: &str, function: Function) {
47 self.parent.borrow_mut().set_function(name, function)
48 }
49
50 fn delete_function(&mut self, name: &str) {
51 self.parent.borrow_mut().delete_function(name)
52 }
53
54 fn parent(&self) -> Option<ScopeRef> {
55 Some(Rc::clone(&self.parent) as ScopeRef)
56 }
57
58 fn get_call_scope(&self) -> Option<Rc<RefCell<CallScope>>> {
59 Some(Rc::new(RefCell::new(self.clone())))
60 }
61
62 fn set_return_value(&mut self, _value: Data) {}
63 fn get_function_list(&self) -> std::collections::HashMap<String, Function> {
64 HashMap::new()
65 }
66
67 fn as_any(&self) -> &dyn Any {
68 self
69 }
70 fn as_mut(&mut self) -> &mut dyn Any {
71 self
72 }
73
74 fn set_if_state(&mut self, _state: super::block_scope::IfState) {}
75}
76
77#[derive(Clone)]
78pub enum Function {
79 Custom {
80 body: Rc<PosNode>,
81 scope_ref: ScopeRef,
82 },
83 BuiltIn {
84 callback:
85 Rc<dyn Fn(Vec<Data>, Option<Function>, ScopeRef) -> Result<Data, Error>>,
86 },
87 Variable {
88 value: Data,
89 scope_ref: ScopeRef,
90 name: String,
91 },
92 Constant {
93 value: Data,
94 },
95}
96
97impl Function {
98 fn call_verbose(
99 &self,
100 args: Vec<Data>,
101 body_fn: Option<Function>,
102 scope: ScopeRef,
103 return_scope: bool,
104 abstract_call_scope: bool,
105 from_scope: Option<ScopeRef>,
106 ) -> Result<Data, Error> {
107 match self {
108 Function::Custom { body, scope_ref } => evaluator::evaluate_verbose(
109 body,
110 if abstract_call_scope {
111 make_ref(CallScope {
112 parent: Rc::clone(&scope_ref),
113 arguments: Rc::new(args),
114 body_fn: Rc::new(body_fn),
115 from_scope: Rc::clone(from_scope.as_ref().unwrap_or(&scope)),
116 })
117 } else {
118 scope
119 },
120 return_scope,
121 None,
122 ),
123 Function::BuiltIn { callback } => {
124 if from_scope.is_some() && scope.borrow().as_any().is::<ModuleWrapper>() {
125 callback(args, body_fn, from_scope.unwrap())
126 } else {
127 callback(args, body_fn, scope)
128 }
129 }
130 Function::Variable {
131 value,
132 name,
133 scope_ref,
134 } => {
135 if let Some(v) = body_fn {
136 let pass = value.clone();
137 let value = v.call(Vec::new(), None, Rc::clone(&scope))?;
138 scope_ref.borrow_mut().set_function(
139 name,
140 Function::Variable {
141 value,
142 scope_ref: Rc::clone(scope_ref),
143 name: String::from(name),
144 },
145 );
146 Ok(pass)
147 } else {
148 Ok(value.clone())
149 }
150 }
151 Function::Constant { value } => {
152 if let Some(_) = body_fn {
153 Err(Error::new("Tried to edit constant.", ErrorSource::Internal))
154 } else {
155 Ok(value.clone())
156 }
157 }
158 }
159 }
160
161 pub fn call(
162 &self,
163 args: Vec<Data>,
164 body_fn: Option<Function>,
165 scope: ScopeRef,
166 ) -> Result<Data, Error> {
167 self.call_verbose(args, body_fn, scope, false, true, None)
168 }
169
170 pub fn call_scope(
171 &self,
172 args: Vec<Data>,
173 body_fn: Option<Function>,
174 scope: ScopeRef,
175 ) -> Result<Data, Error> {
176 self.call_verbose(args, body_fn, scope, true, false, None)
177 }
178
179 pub fn call_from(
180 &self,
181 args: Vec<Data>,
182 body_fn: Option<Function>,
183 scope: ScopeRef,
184 from_scope: Option<ScopeRef>,
185 ) -> Result<Data, Error> {
186 self.call_verbose(args, body_fn, scope, false, true, from_scope)
187 }
188
189 pub fn call_direct(
190 &self,
191 args: Vec<Data>,
192 body_fn: Option<Function>,
193 scope: ScopeRef,
194 ) -> Result<Data, Error> {
195 self.call_verbose(args, body_fn, scope, false, false, None)
196 }
197}
198
199impl Debug for Function {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 match self {
202 Self::Custom { body, scope_ref: _ } => {
203 f.debug_struct("Custom").field("body", body).finish()
204 }
205 Self::BuiltIn { .. } => f.debug_struct("BuiltIn").finish(),
206 Self::Variable {
207 value,
208 scope_ref: _,
209 name: _,
210 } => f.debug_struct("Variable").field("value", value).finish(),
211 Self::Constant { value } => {
212 f.debug_struct("Constant").field("value", value).finish()
213 }
214 }
215 }
216}