1 #ifndef RLANG_SEXP_H
2 #define RLANG_SEXP_H
3 
4 
r_length(sexp * x)5 static inline r_ssize r_length(sexp* x) {
6   return Rf_xlength(x);
7 }
8 
r_typeof(sexp * x)9 static inline enum r_type r_typeof(sexp* x) {
10   return TYPEOF(x);
11 }
12 
13 #define r_mark_precious R_PreserveObject
14 #define r_unmark_precious R_ReleaseObject
15 
r_mark_shared(sexp * x)16 static inline void r_mark_shared(sexp* x) {
17   MARK_NOT_MUTABLE(x);
18 }
r_is_shared(sexp * x)19 static inline bool r_is_shared(sexp* x) {
20   return MAYBE_REFERENCED(x);
21 }
22 
r_mark_object(sexp * x)23 static inline void r_mark_object(sexp* x) {
24   SET_OBJECT(x, 1);
25 }
r_unmark_object(sexp * x)26 static inline void r_unmark_object(sexp* x) {
27   SET_OBJECT(x, 0);
28 }
r_is_object(sexp * x)29 static inline bool r_is_object(sexp* x) {
30   return OBJECT(x);
31 }
32 
r_inherits(sexp * x,const char * tag)33 static inline bool r_inherits(sexp* x, const char* tag) {
34   return Rf_inherits(x, tag);
35 }
36 
r_missing_arg()37 static inline sexp* r_missing_arg() {
38   return R_MissingArg;
39 }
r_is_missing(sexp * x)40 static inline bool r_is_missing(sexp* x) {
41   return x == R_MissingArg;
42 }
43 
r_is_null(sexp * x)44 static inline bool r_is_null(sexp* x) {
45   return x == R_NilValue;
46 }
47 
r_duplicate(sexp * x,bool shallow)48 static inline sexp* r_duplicate(sexp* x, bool shallow) {
49   if (shallow) {
50     return Rf_shallow_duplicate(x);
51   } else {
52     return Rf_duplicate(x);
53   }
54 }
r_copy(sexp * x)55 static inline sexp* r_copy(sexp* x) {
56   return Rf_duplicate(x);
57 }
r_clone(sexp * x)58 static inline sexp* r_clone(sexp* x) {
59   return Rf_shallow_duplicate(x);
60 }
61 
r_maybe_duplicate(sexp * x,bool shallow)62 static inline sexp* r_maybe_duplicate(sexp* x, bool shallow) {
63   if (r_is_shared(x)) {
64     return r_duplicate(x, shallow);
65   } else {
66     return x;
67   }
68 }
69 
r_poke_type(sexp * x,enum r_type type)70 static inline sexp* r_poke_type(sexp* x, enum r_type type) {
71   SET_TYPEOF(x, type);
72   return x;
73 }
r_poke_str_type(sexp * x,const char * type)74 static inline sexp* r_poke_str_type(sexp* x, const char* type) {
75   SET_TYPEOF(x, Rf_str2type(type));
76   return x;
77 }
78 
r_type_as_c_string(enum r_type type)79 static inline const char* r_type_as_c_string(enum r_type type) {
80   return CHAR(Rf_type2str(type));
81 }
82 
r_is_symbolic(sexp * x)83 static inline bool r_is_symbolic(sexp* x) {
84   return
85     r_typeof(x) == LANGSXP ||
86     r_typeof(x) == SYMSXP;
87 }
88 
r_sexp_print(sexp * x)89 static inline void r_sexp_print(sexp* x) {
90   Rf_PrintValue(x);
91 }
92 
r_is_identical(sexp * x,sexp * y)93 static inline bool r_is_identical(sexp* x, sexp* y) {
94   // 16 corresponds to base::identical()'s defaults
95   // Do we need less conservative versions?
96   return R_compute_identical(x, y, 16);
97 }
98 
99 
100 #endif
101