extendr_api/
lang_macros.rs1use crate::robj::GetSexp;
5use crate::robj::Robj;
6use crate::single_threaded;
7use libR_sys::*;
8
9#[doc(hidden)]
11#[macro_export]
12macro_rules! push_args {
13 ($args: expr, $name: ident = $val : expr) => {
14 $args.push((stringify!($name), Robj::from($val)));
15 };
16 ($args: expr, $name: ident = $val : expr, $($rest: tt)*) => {
17 $args.push((stringify!($name), Robj::from($val)));
18 push_args!($args, $($rest)*);
19 };
20 ($args: expr, $val : expr) => {
21 $args.push(("", Robj::from($val)));
22 };
23 ($args: expr, $val : expr, $($rest: tt)*) => {
24 $args.push(("", Robj::from($val)));
25 push_args!($args, $($rest)*);
26 };
27}
28
29#[doc(hidden)]
30#[macro_export]
31macro_rules! args {
32 () => {
33 Vec::<(&str, Robj)>::new()
34 };
35 ($($rest: tt)*) => {
36 {
37 let mut args = Vec::<(&str, Robj)>::new();
38 push_args!(args, $($rest)*);
39 args
40 }
41 };
42}
43
44#[doc(hidden)]
45pub unsafe fn append_with_name(tail: SEXP, obj: Robj, name: &str) -> SEXP {
46 single_threaded(|| {
47 let cons = Rf_cons(obj.get(), R_NilValue);
48 SET_TAG(cons, crate::make_symbol(name));
49 SETCDR(tail, cons);
50 cons
51 })
52}
53
54#[doc(hidden)]
55pub unsafe fn append(tail: SEXP, obj: Robj) -> SEXP {
56 single_threaded(|| {
57 let cons = Rf_cons(obj.get(), R_NilValue);
58 SETCDR(tail, cons);
59 cons
60 })
61}
62
63#[doc(hidden)]
64pub unsafe fn make_lang(sym: &str) -> Robj {
65 Robj::from_sexp(single_threaded(|| Rf_lang1(crate::make_symbol(sym))))
66}
67
68#[doc(hidden)]
70#[macro_export]
71macro_rules! append_lang {
72 ($tail: ident, $name: ident = $val : expr) => {
73 $tail = append_with_name($tail, Robj::from($val), stringify!($name));
74 };
75 ($tail: ident, $name: ident = $val : expr, $($rest: tt)*) => {
76 $tail = append_with_name($tail, Robj::from($val), stringify!($name));
77 append_lang!($tail, $($rest)*);
78 };
79 ($tail: ident, $val : expr) => {
80 $tail = append($tail, Robj::from($val));
81 };
82 ($tail: ident, $val : expr, $($rest: tt)*) => {
83 $tail = append($tail, Robj::from($val));
84 append_lang!($tail, $($rest)*);
85 };
86}
87
88#[macro_export]
103macro_rules! lang {
104 ($sym : expr) => {
105 unsafe {
106 make_lang($sym)
107 }
108 };
109 ($sym : expr, $($rest: tt)*) => {
110 unsafe {
111 use extendr_api::robj::GetSexp;
112 let res = make_lang($sym);
113 let mut tail = res.get();
114 append_lang!(tail, $($rest)*);
115 let _ = tail;
116 res
117 }
118 };
119}