1use crate::{
2 continuation::Continuation, env::LexicalContour, error::RuntimeError, gc::Gc, proc::ExternalFn,
3 syntax::Identifier, value::Value,
4};
5use futures::future::BoxFuture;
6use std::sync::Arc;
7
8pub use scheme_rs_macros::builtin;
9
10type ExprFuture = BoxFuture<'static, Result<Vec<Gc<Value>>, RuntimeError>>;
11
12pub struct Builtin {
13 pub name: &'static str,
14 num_args: usize,
15 variadic: bool,
16 wrapper: fn(Option<Arc<Continuation>>, Vec<Gc<Value>>) -> ExprFuture,
17}
18
19impl Builtin {
20 pub const fn new(
21 name: &'static str,
22 num_args: usize,
23 variadic: bool,
24 wrapper: fn(Option<Arc<Continuation>>, Vec<Gc<Value>>) -> ExprFuture,
25 ) -> Self {
26 Self {
27 name,
28 num_args,
29 variadic,
30 wrapper,
31 }
32 }
33
34 pub fn install(&self, into: &mut LexicalContour) {
35 into.def_var(
36 &Identifier::new(self.name.to_string()),
37 Gc::new(Value::from(ExternalFn {
38 name: self.name,
39 num_args: self.num_args,
40 variadic: self.variadic,
41 func: self.wrapper,
42 })),
43 );
44 }
45}
46
47inventory::collect!(Builtin);