Skip to main content

sim_kernel/
callable.rs

1//! The callable contract: objects that can be invoked with checked arguments.
2//!
3//! This is protocol the libraries implement; the kernel defines [`Callable`]
4//! and the invocation surface, not concrete callable behavior.
5
6use crate::{
7    env::Cx,
8    error::Result,
9    object::{Args, Object, RawArgs, ShapeRef},
10    value::Value,
11};
12
13/// Runtime protocol for values that can be called.
14///
15/// Functions, constructors, macros that accept raw expressions, and host or
16/// guest function stubs all share this protocol. A callable is always a
17/// runtime object, so it also has a class, display form, reflection table, and
18/// optional protocol views through `Object`.
19pub trait Callable: Object {
20    /// Invoke the callable with already-evaluated, checked [`Args`].
21    fn call(&self, cx: &mut Cx, args: Args) -> Result<Value>;
22
23    /// Optional shape describing the accepted argument list, for browsing.
24    fn browse_args_shape(&self, _cx: &mut Cx) -> Result<Option<ShapeRef>> {
25        Ok(None)
26    }
27
28    /// Optional shape describing the call result, for browsing.
29    fn browse_result_shape(&self, _cx: &mut Cx) -> Result<Option<ShapeRef>> {
30        Ok(None)
31    }
32
33    /// Invoke the callable on raw, unevaluated argument expressions.
34    ///
35    /// The default evaluates each expression in `cx` and forwards to
36    /// [`Callable::call`]; macro-like callables override to inspect raw forms.
37    fn call_exprs(&self, cx: &mut Cx, args: RawArgs) -> Result<Value> {
38        let values = args
39            .into_exprs()
40            .into_iter()
41            .map(|expr| cx.eval_expr(expr))
42            .collect::<Result<Vec<_>>>()?;
43        self.call(cx, Args::new(values))
44    }
45}