rustr/
grow.rs

1//! R pairlist methods
2//!
3//!
4
5use rdll::*;
6use traits::*;
7use error::*;
8use protect::stackp::*;
9use rtype::*;
10use util::rprint as rp;
11
12pub fn pairlist(xs: &[&dyn Args]) -> RResult<SEXP> {
13    let mut res: Shield = Shield::new(unsafe { R_NilValue });
14    let mut it = xs.iter().rev();
15    let head: &dyn Args = match it.next() {
16        None => return rraise("need at list one input args"),
17        Some(x) => *x,
18    };
19    unsafe {
20        if head.named() {
21            let y = Shield::new(head.s());
22            let x = Shield::new(Rf_cons(y.s(), res.s()));
23            SET_TAG(x.s(), head.name().s());
24            res = x;
25        } else {
26            res = Shield::new(Rf_cons(Shield::new(head.s()).s(), res.s()));
27        }
28    }
29    for nhead in it {
30        unsafe {
31            if nhead.named() {
32                let y = Shield::new(nhead.s());
33                let x = Shield::new(Rf_cons(y.s(), res.s()));
34                SET_TAG(x.s(), nhead.name().s());
35                res = x;
36            } else {
37                res = Shield::new(Rf_cons(Shield::new(nhead.s()).s(), res.s()));
38            }
39        }
40    }
41    Ok(unsafe { res.s() })
42
43}
44
45pub fn language(xs: &[&dyn Args]) -> RResult<SEXP> {
46    let call = Shield::new(pairlist(xs)?);
47    unsafe {
48        SET_TAG(call.s(), R_NilValue);
49        SET_TYPEOF(call.s(), LANGSXP as ::std::os::raw::c_int);
50        Ok(call.s())
51    }
52}
53
54pub fn pairlist1(hd: &dyn Args, xs: &[&dyn Args]) -> RResult<SEXP> {
55    let mut res: Shield = Shield::new(unsafe { Rf_cons(hd.s(), R_NilValue) });
56    let mut it = xs.iter().rev();
57    let head: &dyn Args = match it.next() {
58        None => return Ok(unsafe { res.s() }),
59        Some(x) => *x,
60    };
61    unsafe {
62        if head.named() {
63            let y = Shield::new(head.s());
64            let x = Shield::new(Rf_cons(y.s(), res.s()));
65            SET_TAG(x.s(), head.name().s());
66            res = x;
67            rp(res.s());
68        } else {
69            res = Shield::new(Rf_cons(Shield::new(head.s()).s(), res.s()));
70            rp(res.s());
71        }
72    }
73    for nhead in it {
74        unsafe {
75            if nhead.named() {
76                let y = Shield::new(nhead.s());
77                let x = Shield::new(Rf_cons(y.s(), res.s()));
78                SET_TAG(x.s(), nhead.name().s());
79                res = x;
80                rp(res.s());
81            } else {
82                rp(nhead.s());
83                res = Shield::new(Rf_cons(Shield::new(nhead.s()).s(), res.s()));
84                rp(res.s());
85            }
86        }
87    }
88    Ok(unsafe { res.s() })
89
90}
91
92pub fn language1(hd: &dyn Args, xs: &[&dyn Args]) -> RResult<SEXP> {
93    let call = Shield::new(unsafe { Rf_lcons(hd.s(), pairlist(xs)?) });
94    unsafe {
95        SET_TAG(call.s(), R_NilValue);
96        SET_TYPEOF(call.s(), LANGSXP as ::std::os::raw::c_int);
97        Ok(call.s())
98    }
99}