1use ::rdll::*;
8use ::storage::*;
9use ::traits::*;
10use ::rtype::*;
11use ::error::*;
12use std::convert::*;
13
14use symbol::*;
15
16use environment::*;
17use protect::stackp::*;
18use eval::*;
19use grow::*;
20
21
22pub type RFun = RFunM<Preserve>;
23
24
25impl<T: SEXPbucket> NewRObj for RFunM<T> {
26 fn new<E: ToSEXP>(x: E) -> RResult<Self> {
27 match unsafe { RTYPEOF(x.s()) } {
28 CLOSXP | SPECIALSXP | BUILTINSXP => unsafe { Ok(RFunM { data: T::new(x.s()) }) },
29 _ => rraise("cannot convert to function"),
30 }
31 }
32 unsafe fn unew<E: ToSEXP>(x: E) -> Self {
33 RFunM { data: T::new(x.s()) }
34 }
35}
36
37impl<T: SEXPbucket> RFunM<T> {
38 pub fn set_sexp<S: ToSEXP>(&mut self, x: S) -> RResult<()> {
39
40 match unsafe { RTYPEOF(x.s()) } {
41 CLOSXP | SPECIALSXP | BUILTINSXP => {
42 self.data.set(unsafe { x.s() });
43 Ok(())
44 }
45 _ => rraise("cannot convert to function"),
46 }
47 }
48 pub fn from_str_global(x: &str) -> RResult<RFunM<T>> {
49 let sym = Symbol::from(x);
50 unsafe { RFunM::new(Rf_findFun(sym.s(), R_GlobalEnv)) }
51 }
52 pub fn from_str<EE: SEXPbucket>(x: &str, env: EnvirM<EE>) -> RResult<RFunM<T>> {
53 let sym = Symbol::from(x);
54 unsafe { RFunM::new(Rf_findFun(sym.s(), env.s())) }
55 }
56 pub fn ufrom_str_global(x: &str) -> RFunM<T> {
57 let sym = Symbol::from(x);
58 unsafe { RFunM::unew(Rf_findFun(sym.s(), R_GlobalEnv)) }
59 }
60 pub fn ufrom_str<EE: SEXPbucket>(x: &str, env: EnvirM<EE>) -> RFunM<T> {
61 let sym = Symbol::from(x);
62 unsafe { RFunM::unew(Rf_findFun(sym.s(), env.s())) }
63 }
64 pub fn envir<S: SEXPbucket>(&self) -> RResult<EnvirM<S>> {
65 unsafe {
66 if RTYPEOF(self.s()) != CLOSXP {
67 return rraise(format!("not a closure, type = {:?}",
68 match_rtype(RTYPEOF(self.s()))));
69 }
70 Ok(EnvirM::from_sexp_envir(CLOENV(self.s())))
71 }
72 }
73 pub fn body(&self) -> SEXP {
74 unsafe { BODY(self.s()) }
75 }
76 pub fn eval<D: RNew>(&self, args: &[&dyn Args]) -> RResult<D> {
77 let call = Shield::new(try!(language1(self, args)));
78 D::rnew(try!(rustr_eval(unsafe { call.s() }, unsafe { R_GlobalEnv })))
79 }
80 pub fn eval_env<EE: SEXPbucket, D: RNew>(&self,
81 args: &[&dyn Args],
82 envir: EnvirM<EE>)
83 -> RResult<D> {
84 let call = Shield::new(try!(language1(self, args)));
85 D::rnew(try!(rustr_eval(unsafe { call.s() }, unsafe { envir.s() })))
86 }
87}
88
89impl<T: SEXPbucket> RNew for RFunM<T> {
99 fn rnew(x: SEXP) -> RResult<Self> {
100 match unsafe { RTYPEOF(x.s()) } {
101 CLOSXP | SPECIALSXP | BUILTINSXP => Ok(RFunM { data: T::new(unsafe { x.s() }) }),
102 _ => rraise("cannot convert to function"),
103 }
104 }
105}
106
107gen_traits_sexp!(RFunM);