1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::borrow::BorrowMut;
use emacs_module::emacs_value;
use emacs_macros;
use crate::{Env, Value, Result, IntoLisp};
pub unsafe trait IntoLispArgs<'e> {
type LispArgs: BorrowMut<[emacs_value]>;
fn into_lisp_args(self, env: &'e Env) -> Result<Self::LispArgs>;
}
impl<'e> Value<'e> {
pub fn call<A>(self, args: A) -> Result<Value<'e>> where A: IntoLispArgs<'e> {
let env = self.env;
let mut lisp_args = args.into_lisp_args(env)?;
let lisp_args: &mut [emacs_value] = lisp_args.borrow_mut();
let ptr = lisp_args.as_mut_ptr();
let length = lisp_args.len() as isize;
raw_call_value!(env, funcall, self.raw, length, ptr)
}
}
pub trait IntoLispCallable<'e> {
fn into_lisp_callable(self, env: &'e Env) -> Result<Value<'e>>;
}
impl Env {
#[inline]
pub fn call<'e, F, A>(&'e self, func: F, args: A) -> Result<Value<'_>>
where
F: IntoLispCallable<'e>,
A: IntoLispArgs<'e>,
{
func.into_lisp_callable(self)?.call(args)
}
pub fn list<'e, A>(&'e self, args: A) -> Result<Value<'_>> where A: IntoLispArgs<'e> {
self.call("list", args)
}
}
unsafe impl<'e, T: AsRef<[Value<'e>]> + ?Sized> IntoLispArgs<'e> for &T {
type LispArgs = Vec<emacs_value>;
fn into_lisp_args(self, _: &'e Env) -> Result<Self::LispArgs> {
Ok(self.as_ref().iter().map(|v| v.raw).collect())
}
}
emacs_macros::impl_lisp_args_for_tuples!(12);
emacs_macros::impl_lisp_args_for_arrays!(12);
impl<'e> IntoLispCallable<'e> for Value<'e> {
#[inline(always)]
fn into_lisp_callable(self, _: &'e Env) -> Result<Value<'e>> {
Ok(self)
}
}
impl<'e, T: AsRef<str>> IntoLispCallable<'e> for T {
#[inline(always)]
fn into_lisp_callable(self, env: &'e Env) -> Result<Value<'e>> {
env.intern(self.as_ref())
}
}