Add __call metamethod
This commit is contained in:
parent
875cfc1220
commit
71c11e87e5
@ -653,7 +653,9 @@ impl ClosureRunner {
|
||||
"__index",
|
||||
vec![value.unwrap().clone(), index_value.clone()],
|
||||
) {
|
||||
Ok(value) => StackValue::Value(value),
|
||||
Ok(value) => {
|
||||
StackValue::Value(value.first().unwrap().clone())
|
||||
}
|
||||
Err(_) => StackValue::Value(Value::Nil),
|
||||
}
|
||||
}
|
||||
@ -773,7 +775,7 @@ impl ClosureRunner {
|
||||
.get(func_reg)
|
||||
.map(|v| v.borrow().clone())
|
||||
.unwrap_or(Value::Nil);
|
||||
match value {
|
||||
match &value {
|
||||
Value::RustFunction(func) => {
|
||||
let ret_values = func.borrow_mut().execute(params)?;
|
||||
if *ret_len != 0 {
|
||||
@ -807,6 +809,34 @@ impl ClosureRunner {
|
||||
}
|
||||
self.inner = Some(Box::new(closure.run(params)));
|
||||
}
|
||||
Value::Table { metatable, .. } => {
|
||||
let mut metamethod_params = vec![value.clone()];
|
||||
metamethod_params.extend(params);
|
||||
let ret_values =
|
||||
self.call_metamethod(&metatable, "__call", metamethod_params)?;
|
||||
|
||||
if *ret_len != 0 {
|
||||
for i in 0..=(*ret_len - 2) {
|
||||
self.set_stack(
|
||||
*func_reg + i,
|
||||
StackValue::Value(
|
||||
ret_values
|
||||
.get(i as usize)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Nil),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (i, value) in ret_values.iter().enumerate() {
|
||||
self.set_stack(
|
||||
*func_reg + i as u16 + 1,
|
||||
StackValue::Value(value.clone()),
|
||||
);
|
||||
}
|
||||
self.top = *func_reg + ret_values.len() as u16;
|
||||
}
|
||||
}
|
||||
_ => return Err(RuntimeError::TriedCallingNonFunction(value.clone())),
|
||||
}
|
||||
}
|
||||
@ -1019,6 +1049,8 @@ impl ClosureRunner {
|
||||
"__eq",
|
||||
vec![lhs.clone(), rhs.clone()],
|
||||
)?
|
||||
.first()
|
||||
.unwrap()
|
||||
.is_truthy(),
|
||||
))),
|
||||
);
|
||||
@ -1093,7 +1125,10 @@ impl ClosureRunner {
|
||||
Value::Table { metatable, .. } => {
|
||||
match self.call_metamethod(&metatable, "__len", vec![value.clone()]) {
|
||||
Ok(result) => {
|
||||
self.set_stack(*res, StackValue::Value(result));
|
||||
self.set_stack(
|
||||
*res,
|
||||
StackValue::Value(result.first().unwrap().clone()),
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
self.set_stack(*res, StackValue::Value(value.len()?));
|
||||
@ -1187,7 +1222,11 @@ impl ClosureRunner {
|
||||
.borrow()
|
||||
.contains_key(&IndexableValue::String(metamethod.to_owned()))
|
||||
{
|
||||
self.call_metamethod(metatable, metamethod, vec![param.clone()])
|
||||
Ok(self
|
||||
.call_metamethod(metatable, metamethod, vec![param.clone()])?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap())
|
||||
} else {
|
||||
Err(RuntimeError::InvalidUnop(
|
||||
metamethod.to_owned(),
|
||||
@ -1218,14 +1257,26 @@ impl ClosureRunner {
|
||||
.borrow()
|
||||
.contains_key(&IndexableValue::String(metamethod.to_owned()))
|
||||
{
|
||||
self.call_metamethod(&metatable, metamethod, vec![lhs.clone(), rhs])
|
||||
Ok(self
|
||||
.call_metamethod(&metatable, metamethod, vec![lhs.clone(), rhs])?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap())
|
||||
} else {
|
||||
if let Value::Table { metatable, .. } = &rhs {
|
||||
if metatable
|
||||
.borrow()
|
||||
.contains_key(&IndexableValue::String(metamethod.to_owned()))
|
||||
{
|
||||
self.call_metamethod(&metatable, metamethod, vec![lhs, rhs.clone()])
|
||||
Ok(self
|
||||
.call_metamethod(
|
||||
&metatable,
|
||||
metamethod,
|
||||
vec![lhs, rhs.clone()],
|
||||
)?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap())
|
||||
} else {
|
||||
Err(RuntimeError::InvalidBinop(
|
||||
metamethod.to_owned(),
|
||||
@ -1246,7 +1297,11 @@ impl ClosureRunner {
|
||||
.borrow()
|
||||
.contains_key(&IndexableValue::String(metamethod.to_owned()))
|
||||
{
|
||||
self.call_metamethod(&metatable, metamethod, vec![lhs, rhs.clone()])
|
||||
Ok(self
|
||||
.call_metamethod(&metatable, metamethod, vec![lhs, rhs.clone()])?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap())
|
||||
} else {
|
||||
Err(RuntimeError::InvalidBinop(
|
||||
metamethod.to_owned(),
|
||||
@ -1270,7 +1325,7 @@ impl ClosureRunner {
|
||||
metatable: &Table,
|
||||
metamethod: &str,
|
||||
params: Vec<Value>,
|
||||
) -> Result<Value, RuntimeError> {
|
||||
) -> Result<Vec<Value>, RuntimeError> {
|
||||
if let Some(value) = metatable
|
||||
.borrow()
|
||||
.get(&IndexableValue::String(metamethod.to_owned()))
|
||||
@ -1278,7 +1333,7 @@ impl ClosureRunner {
|
||||
match value {
|
||||
Value::RustFunction(function) => {
|
||||
let result = function.borrow_mut().execute(params)?;
|
||||
Ok(result.into_iter().next().unwrap())
|
||||
Ok(result)
|
||||
}
|
||||
Value::Function(closure) => {
|
||||
let mut runnable = closure.run(params);
|
||||
@ -1288,7 +1343,7 @@ impl ClosureRunner {
|
||||
return_value = runnable.next()?;
|
||||
return_value.is_none()
|
||||
} {}
|
||||
Ok(return_value.unwrap().into_iter().next().unwrap())
|
||||
Ok(return_value.unwrap())
|
||||
}
|
||||
_ => Err(RuntimeError::MetafunctionNotCallable(value.clone())),
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user