Files
lysp/src/vm/native.rs
T
2026-05-06 16:31:19 +03:00

60 lines
1.4 KiB
Rust

use std::{fmt, rc::Rc};
use crate::vm::{
env::Environment,
machine::{Machine, MachineError},
value::Value,
};
pub type NativeFunctionImpl =
Rc<dyn Fn(&mut Machine, &mut Environment, &[Value]) -> Result<Value, MachineError> + 'static>;
#[derive(Clone)]
pub struct NativeFunction {
name: Rc<str>,
inner: NativeFunctionImpl,
}
impl NativeFunction {
pub fn new<S, F>(name: S, function: F) -> Self
where
S: Into<Rc<str>>,
F: Fn(&mut Machine, &mut Environment, &[Value]) -> Result<Value, MachineError> + 'static,
{
Self {
name: name.into(),
inner: Rc::new(function),
}
}
pub fn invoke(
&self,
machine: &mut Machine,
environment: &mut Environment,
arguments: &[Value],
) -> Result<Value, MachineError> {
(self.inner)(machine, environment, arguments)
}
}
impl PartialEq for NativeFunction {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl fmt::Debug for NativeFunction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("NativeFunction")
.field("name", &self.name)
.field_with("inner", |f| write!(f, "{:p}", self.inner))
.finish()
}
}
impl fmt::Display for NativeFunction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<native {:?} {:p}>", self.name, self.inner)
}
}