rustr/
promise.rs

1//! R Promise type
2//!
3//!
4
5
6use ::rdll::*;
7use ::storage::*;
8use ::traits::*;
9use ::rtype::*;
10use ::error::*;
11use std::convert::*;
12// use std::ffi::*;
13// use ::moredll::*;
14
15pub type Promise = PromiseM<Preserve>;
16
17gen_traits_sexp!(PromiseM);
18
19impl<T: SEXPbucket> PromiseM<T> {
20    pub fn new<E: ToSEXP>(x: E) -> RResult<PromiseM<T>> {
21        unsafe {
22            if RTYPEOF(x.s()) != PROMSXP {
23                return rraise("not a promise");
24            }
25
26            let mut re = x.s();
27
28            while RTYPEOF(PRCODE(re)) == PROMSXP {
29                re = PRCODE(re);
30            }
31
32            Ok(PromiseM { data: T::new(re) })
33        }
34    }
35    pub fn seen(&self) -> ::std::os::raw::c_int {
36        unsafe { PRSEEN(self.data.s()) }
37    }
38
39
40    pub fn value<S: SEXPbucket, D: RNew>(&self) -> RResult<D> {
41        unsafe {
42            let val = PRVALUE(self.data.s());
43            if val == R_UnboundValue {
44                return rerror(REKind::UnevaluatedPromise("an Unevaluated promise value".into()));
45            }
46            D::rnew(val)
47        }
48    }
49
50    pub fn was_evaluated(&self) -> bool {
51        unsafe { PRVALUE(self.data.s()) != R_UnboundValue }
52    }
53    // todo return ExprVec
54    pub fn expression(&self) -> SEXP {
55        unsafe { PRCODE(self.data.s()) }
56    }
57    pub fn environment<S: SEXPbucket>(&self) -> EnvirM<S> {
58        unsafe { EnvirM::from_sexp_envir(PRENV(self.data.s())) }
59    }
60}
61
62use environment::*;