bean_script/scope/
function.rs

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}