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}