1 #include <rlang.h>
2 #include "../internal/utils.h"
3
4
5 // attrs.c
6
rlang_poke_attrib(sexp * x,sexp * attrs)7 sexp* rlang_poke_attrib(sexp* x, sexp* attrs) {
8 SET_ATTRIB(x, attrs);
9 return x;
10 }
11
12
13 // cnd.c
14
rlang_cnd_signal(sexp * cnd)15 sexp* rlang_cnd_signal(sexp* cnd) {
16 r_cnd_signal(cnd);
17 return r_null;
18 }
19
rlang_cnd_type(sexp * cnd)20 sexp* rlang_cnd_type(sexp* cnd) {
21 enum r_condition_type type = r_cnd_type(cnd);
22 switch (type) {
23 case r_cnd_type_condition: return r_chr("condition");
24 case r_cnd_type_message: return r_chr("message");
25 case r_cnd_type_warning: return r_chr("warning");
26 case r_cnd_type_error: return r_chr("error");
27 case r_cnd_type_interrupt: return r_chr("interrupt");
28 default: r_abort("Internal error: Unhandled `r_condition_type`");
29 }
30 }
31
rlang_interrupt()32 sexp* rlang_interrupt() {
33 r_interrupt();
34 return r_null;
35 }
36
37
38 // env.c
39
rlang_env_poke_parent(sexp * env,sexp * new_parent)40 sexp* rlang_env_poke_parent(sexp* env, sexp* new_parent) {
41 if (R_IsNamespaceEnv(env)) {
42 r_abort("Can't change the parent of a namespace environment");
43 }
44 if (R_IsPackageEnv(env)) {
45 r_abort("Can't change the parent of a package environment");
46 }
47 if (R_EnvironmentIsLocked(env)) {
48 r_abort("Can't change the parent of a locked environment");
49 }
50 if (env == r_global_env) {
51 r_abort("Can't change the parent of the global environment");
52 }
53 if (env == r_base_env) {
54 r_abort("Can't change the parent of the base environment");
55 }
56 if (env == r_empty_env) {
57 r_abort("Can't change the parent of the empty environment");
58 }
59
60 SET_ENCLOS(env, new_parent);
61 return env;
62 }
63
rlang_env_frame(sexp * env)64 sexp* rlang_env_frame(sexp* env) {
65 return FRAME(env);
66 }
rlang_env_hash_table(sexp * env)67 sexp* rlang_env_hash_table(sexp* env) {
68 return HASHTAB(env);
69 }
70
rlang_env_inherits(sexp * env,sexp * ancestor)71 sexp* rlang_env_inherits(sexp* env, sexp* ancestor) {
72 return r_lgl(r_env_inherits(env, ancestor, r_empty_env));
73 }
74
rlang_env_bind_list(sexp * env,sexp * names,sexp * data)75 sexp* rlang_env_bind_list(sexp* env, sexp* names, sexp* data) {
76 if (r_typeof(env) != r_type_environment) {
77 r_abort("Internal error: `env` must be an environment.");
78 }
79 if (r_typeof(names) != r_type_character) {
80 r_abort("Internal error: `names` must be a character vector.");
81 }
82 if (r_typeof(data) != r_type_list) {
83 r_abort("Internal error: `data` must be a list.");
84 }
85
86 r_ssize n = r_length(data);
87 if (n != r_length(names)) {
88 r_abort("Internal error: `data` and `names` must have the same length.");
89 }
90
91 sexp* const * p_names = r_chr_deref_const(names);
92
93 for (r_ssize i = 0; i < n; ++i) {
94 Rf_defineVar(r_str_as_symbol(p_names[i]), r_list_get(data, i), env);
95 }
96
97 return r_null;
98 }
99
rlang_env_browse(sexp * env,sexp * value)100 sexp* rlang_env_browse(sexp* env, sexp* value) {
101 if (r_typeof(env) != r_type_environment) {
102 r_abort("`env` must be an environment.");
103 }
104 if (!r_is_bool(value)) {
105 r_abort("`value` must be a single logical value.");
106 }
107
108 sexp* old = r_lgl(RDEBUG(env));
109 SET_RDEBUG(env, r_lgl_get(value, 0));
110 return old;
111 }
112
rlang_env_is_browsed(sexp * env)113 sexp* rlang_env_is_browsed(sexp* env) {
114 if (r_typeof(env) != r_type_environment) {
115 r_abort("`env` must be an environment.");
116 }
117 return r_lgl(RDEBUG(env));
118 }
119
rlang_ns_registry_env()120 sexp* rlang_ns_registry_env() {
121 return R_NamespaceRegistry;
122 }
123
124
125 // eval.c
126
rlang_ext2_eval(sexp * call,sexp * op,sexp * args,sexp * env)127 sexp* rlang_ext2_eval(sexp* call, sexp* op, sexp* args, sexp* env) {
128 args = r_node_cdr(args);
129 return Rf_eval(r_node_car(args), r_node_cadr(args));
130 }
131
rlang_eval_top(sexp * expr,sexp * env)132 sexp* rlang_eval_top(sexp* expr, sexp* env) {
133 int jumped = 0;
134 sexp* out = R_tryEval(expr, env, &jumped);
135
136 if (jumped) {
137 r_abort("Top level jump");
138 } else {
139 return out;
140 }
141 }
142
143 // fn.c
144
rlang_is_function(sexp * x)145 sexp* rlang_is_function(sexp* x) {
146 return r_shared_lgl(r_is_function(x));
147 }
148
rlang_is_closure(sexp * x)149 sexp* rlang_is_closure(sexp* x) {
150 return r_shared_lgl(r_is_closure(x));
151 }
152
rlang_is_primitive(sexp * x)153 sexp* rlang_is_primitive(sexp* x) {
154 return r_shared_lgl(r_is_primitive(x));
155 }
rlang_is_primitive_lazy(sexp * x)156 sexp* rlang_is_primitive_lazy(sexp* x) {
157 return r_shared_lgl(r_is_primitive_lazy(x));
158 }
rlang_is_primitive_eager(sexp * x)159 sexp* rlang_is_primitive_eager(sexp* x) {
160 return r_shared_lgl(r_is_primitive_eager(x));
161 }
162
163
164 // formula.c
165
rlang_is_formula(sexp * x,sexp * scoped,sexp * lhs)166 sexp* rlang_is_formula(sexp* x, sexp* scoped, sexp* lhs) {
167 int scoped_int = r_as_optional_bool(scoped);
168 int lhs_int = r_as_optional_bool(lhs);
169
170 bool out = r_is_formula(x, scoped_int, lhs_int);
171 return r_lgl(out);
172 }
173
rlang_is_formulaish(sexp * x,sexp * scoped,sexp * lhs)174 sexp* rlang_is_formulaish(sexp* x, sexp* scoped, sexp* lhs) {
175 int scoped_int = r_as_optional_bool(scoped);
176 int lhs_int = r_as_optional_bool(lhs);
177
178 bool out = r_is_formulaish(x, scoped_int, lhs_int);
179 return r_lgl(out);
180 }
181
182
183 // parse.c
184
rlang_call_has_precedence(sexp * x,sexp * y,sexp * side)185 sexp* rlang_call_has_precedence(sexp* x, sexp* y, sexp* side) {
186 bool has_predence;
187 if (side == r_null) {
188 has_predence = r_call_has_precedence(x, y);
189 } else if (r_is_string(side, "lhs")) {
190 has_predence = r_lhs_call_has_precedence(x, y);
191 } else if (r_is_string(side, "rhs")) {
192 has_predence = r_rhs_call_has_precedence(x, y);
193 } else {
194 r_abort("`side` must be NULL, \"lhs\" or \"rhs\"");
195 }
196 return r_lgl(has_predence);
197 }
198
rlang_which_operator(sexp * call)199 sexp* rlang_which_operator(sexp* call) {
200 const char* op = r_op_as_c_string(r_which_operator(call));
201 return r_chr(op);
202 }
203
204
205 // node.c
206
rlang_node_car(sexp * x)207 sexp* rlang_node_car(sexp* x) {
208 return CAR(x);
209 }
rlang_node_cdr(sexp * x)210 sexp* rlang_node_cdr(sexp* x) {
211 return CDR(x);
212 }
rlang_node_caar(sexp * x)213 sexp* rlang_node_caar(sexp* x) {
214 return CAAR(x);
215 }
rlang_node_cadr(sexp * x)216 sexp* rlang_node_cadr(sexp* x) {
217 return CADR(x);
218 }
rlang_node_cdar(sexp * x)219 sexp* rlang_node_cdar(sexp* x) {
220 return CDAR(x);
221 }
rlang_node_cddr(sexp * x)222 sexp* rlang_node_cddr(sexp* x) {
223 return CDDR(x);
224 }
rlang_node_tail(sexp * x)225 sexp* rlang_node_tail(sexp* x) {
226 while (CDR(x) != r_null)
227 x = CDR(x);
228 return x;
229 }
230
rlang_node_poke_car(sexp * x,sexp * newcar)231 sexp* rlang_node_poke_car(sexp* x, sexp* newcar) {
232 SETCAR(x, newcar);
233 return x;
234 }
rlang_node_poke_cdr(sexp * x,sexp * newcdr)235 sexp* rlang_node_poke_cdr(sexp* x, sexp* newcdr) {
236 SETCDR(x, newcdr);
237 return x;
238 }
rlang_node_poke_caar(sexp * x,sexp * newcaar)239 sexp* rlang_node_poke_caar(sexp* x, sexp* newcaar) {
240 SETCAR(CAR(x), newcaar);
241 return x;
242 }
rlang_node_poke_cadr(sexp * x,sexp * newcar)243 sexp* rlang_node_poke_cadr(sexp* x, sexp* newcar) {
244 SETCADR(x, newcar);
245 return x;
246 }
rlang_node_poke_cdar(sexp * x,sexp * newcdar)247 sexp* rlang_node_poke_cdar(sexp* x, sexp* newcdar) {
248 SETCDR(CAR(x), newcdar);
249 return x;
250 }
rlang_node_poke_cddr(sexp * x,sexp * newcdr)251 sexp* rlang_node_poke_cddr(sexp* x, sexp* newcdr) {
252 SETCDR(CDR(x), newcdr);
253 return x;
254 }
255
rlang_node_tag(sexp * x)256 sexp* rlang_node_tag(sexp* x) {
257 return TAG(x);
258 }
rlang_node_poke_tag(sexp * x,sexp * tag)259 sexp* rlang_node_poke_tag(sexp* x, sexp* tag) {
260 SET_TAG(x, tag);
261 return x;
262 }
263
rlang_on_exit(sexp * expr,sexp * frame)264 sexp* rlang_on_exit(sexp* expr, sexp* frame) {
265 r_on_exit(expr, frame);
266 return r_null;
267 }
268
269
270 // lang.h
271
rlang_new_call_node(sexp * car,sexp * cdr)272 sexp* rlang_new_call_node(sexp* car, sexp* cdr) {
273 return Rf_lcons(car, cdr);
274 }
275
276
277 // quo.h
278
279 #include "../internal/quo.h"
280
rlang_quo_is_missing(sexp * quo)281 sexp* rlang_quo_is_missing(sexp* quo) {
282 check_quosure(quo);
283 return r_lgl(quo_is_missing(quo));
284 }
rlang_quo_is_symbol(sexp * quo)285 sexp* rlang_quo_is_symbol(sexp* quo) {
286 check_quosure(quo);
287 return r_lgl(quo_is_symbol(quo));
288 }
rlang_quo_is_call(sexp * quo)289 sexp* rlang_quo_is_call(sexp* quo) {
290 check_quosure(quo);
291 return r_lgl(quo_is_call(quo));
292 }
rlang_quo_is_symbolic(sexp * quo)293 sexp* rlang_quo_is_symbolic(sexp* quo) {
294 check_quosure(quo);
295 return r_lgl(quo_is_symbolic(quo));
296 }
rlang_quo_is_null(sexp * quo)297 sexp* rlang_quo_is_null(sexp* quo) {
298 check_quosure(quo);
299 return r_lgl(quo_is_null(quo));
300 }
301
302
303 // sexp.h
304
rlang_length(sexp * x)305 sexp* rlang_length(sexp* x) {
306 return r_int(r_length(x));
307 }
rlang_true_length(sexp * x)308 sexp* rlang_true_length(sexp* x) {
309 return r_int(XTRUELENGTH(x));
310 }
311
rlang_is_reference(sexp * x,sexp * y)312 sexp* rlang_is_reference(sexp* x, sexp* y) {
313 return r_lgl(x == y);
314 }
315
rlang_missing_arg()316 sexp* rlang_missing_arg() {
317 return R_MissingArg;
318 }
319
rlang_duplicate(sexp * x,sexp * shallow)320 sexp* rlang_duplicate(sexp* x, sexp* shallow) {
321 return r_duplicate(x, r_lgl_get(shallow, 0));
322 }
323
rlang_sexp_address(sexp * x)324 sexp* rlang_sexp_address(sexp* x) {
325 static char str[1000];
326 snprintf(str, 1000, "%p", (void*) x);
327 return Rf_mkString(str);
328 }
329
rlang_poke_type(sexp * x,sexp * type)330 sexp* rlang_poke_type(sexp* x, sexp* type) {
331 SET_TYPEOF(x, Rf_str2type(r_chr_get_c_string(type, 0)));
332 return x;
333 }
334
rlang_mark_object(sexp * x)335 sexp* rlang_mark_object(sexp* x) {
336 SET_OBJECT(x, 1);
337 return x;
338 }
rlang_unmark_object(sexp * x)339 sexp* rlang_unmark_object(sexp* x) {
340 SET_OBJECT(x, 0);
341 return x;
342 }
343
rlang_get_promise(sexp * x,sexp * env)344 sexp* rlang_get_promise(sexp* x, sexp* env) {
345 switch (r_typeof(x)) {
346 case r_type_promise:
347 return x;
348 case r_type_character:
349 if (r_length(x) == 1) {
350 x = r_sym(r_chr_get_c_string(x, 0));
351 } else {
352 goto error;
353 }
354 // fallthrough
355 case r_type_symbol: {
356 sexp* prom = r_env_find_anywhere(env, x);
357 if (r_typeof(prom) == r_type_promise) {
358 return prom;
359 }
360 // fallthrough
361 }
362 error:
363 default:
364 r_abort("`x` must be or refer to a local promise");
365 }
366 }
367
rlang_promise_expr(sexp * x,sexp * env)368 sexp* rlang_promise_expr(sexp* x, sexp* env) {
369 sexp* prom = rlang_get_promise(x, env);
370 return PREXPR(prom);
371 }
rlang_promise_env(sexp * x,sexp * env)372 sexp* rlang_promise_env(sexp* x, sexp* env) {
373 sexp* prom = rlang_get_promise(x, env);
374 return PRENV(prom);
375 }
rlang_promise_value(sexp * x,sexp * env)376 sexp* rlang_promise_value(sexp* x, sexp* env) {
377 sexp* prom = rlang_get_promise(x, env);
378 sexp* value = PRVALUE(prom);
379 if (value == r_syms_unbound) {
380 return r_sym("R_UnboundValue");
381 } else {
382 return value;
383 }
384 }
385
rlang_attrib(sexp * x)386 sexp* rlang_attrib(sexp* x) {
387 return ATTRIB(x);
388 }
389
390 // Picks up symbols from parent environment to avoid bumping namedness
391 // during promise resolution
rlang_named(sexp * x,sexp * env)392 sexp* rlang_named(sexp* x, sexp* env) {
393 int n_protect = 0;
394
395 x = PROTECT(Rf_findVarInFrame3(env, x, FALSE));
396 ++n_protect;
397
398 if (TYPEOF(x) == PROMSXP) {
399 x = PROTECT(Rf_eval(x, env));
400 ++n_protect;
401 }
402
403 UNPROTECT(n_protect);
404 return Rf_ScalarInteger(NAMED(x));
405 }
406
rlang_find_var(sexp * env,sexp * sym)407 sexp* rlang_find_var(sexp* env, sexp* sym) {
408 return Rf_findVar(sym, env);
409 }
410
rlang_chr_get(sexp * x,sexp * i)411 sexp* rlang_chr_get(sexp* x, sexp* i) {
412 if (r_typeof(i) != r_type_integer || r_length(i) != 1) {
413 r_abort("`i` must be an integer value.");
414 }
415
416 int c_i = r_int_get(i, 0);
417 if (c_i < 0 || c_i >= r_length(x)) {
418 r_abort("`i` is out of bound. Note that `r_chr_get()` takes zero-based locations.");
419 }
420
421 return r_chr_get(x, c_i);
422 }
423
424
425 // vec.h
426
rlang_vec_alloc(sexp * type,sexp * n)427 sexp* rlang_vec_alloc(sexp* type, sexp* n) {
428 return Rf_allocVector(Rf_str2type(r_chr_get_c_string(type, 0)), r_int_get(n, 0));
429 }
rlang_vec_coerce(sexp * x,sexp * type)430 sexp* rlang_vec_coerce(sexp* x, sexp* type) {
431 return Rf_coerceVector(x, Rf_str2type(r_chr_get_c_string(type, 0)));
432 }
433
434 // TODO: C-level check for scalar integerish
r_as_int(sexp * x)435 int r_as_int(sexp* x) {
436 switch(r_typeof(x)) {
437 case r_type_integer: return *INTEGER(x);
438 case r_type_double: return (int) *REAL(x);
439 default: r_abort("Internal error: Expected integerish input");
440 }
441 }
442
rlang_vec_poke_n(sexp * x,sexp * offset,sexp * y,sexp * from,sexp * n)443 sexp* rlang_vec_poke_n(sexp* x, sexp* offset,
444 sexp* y, sexp* from, sexp* n) {
445 r_ssize offset_size = r_as_ssize(offset) - 1;
446 r_ssize from_size = r_as_ssize(from) - 1;
447 r_ssize n_size = r_as_ssize(n);
448
449 r_vec_poke_n(x, offset_size, y, from_size, n_size);
450 return x;
451 }
452
rlang_vec_poke_range(sexp * x,sexp * offset,sexp * y,sexp * from,sexp * to)453 sexp* rlang_vec_poke_range(sexp* x, sexp* offset,
454 sexp* y, sexp* from, sexp* to) {
455 r_ssize offset_size = r_as_ssize(offset) - 1;
456 r_ssize from_size = r_as_ssize(from) - 1;
457 r_ssize to_size = r_as_ssize(to) - 1;
458
459 r_vec_poke_range(x, offset_size, y, from_size, to_size);
460 return x;
461 }
462
463
464 // vec-list.h
465
validate_n(sexp * n)466 static r_ssize validate_n(sexp* n) {
467 if (n == r_null) {
468 return -1;
469 }
470
471 switch (r_typeof(n)) {
472 case r_type_integer:
473 case r_type_double:
474 if (r_length(n) == 1) {
475 break;
476 }
477 // fallthrough
478 default:
479 r_abort("`n` must be NULL or a scalar integer");
480 }
481
482 return r_as_ssize(n);
483 }
484
validate_finite(sexp * finite)485 static int validate_finite(sexp* finite) {
486 switch (r_typeof(finite)) {
487 case r_type_null:
488 return -1;
489 case r_type_integer:
490 case r_type_double:
491 finite = r_vec_coerce(finite, r_type_logical);
492 case r_type_logical: {
493 int value = r_lgl_get(finite, 0);
494 if (value != NA_LOGICAL) {
495 return r_lgl_get(finite, 0);
496 } // else fallthrough
497 }
498 default:
499 r_abort("`finite` must be NULL or a scalar logical");
500 }
501 }
502
rlang_is_finite(sexp * x)503 sexp* rlang_is_finite(sexp* x) {
504 return r_shared_lgl(r_is_finite(x));
505 }
506
rlang_is_list(sexp * x,sexp * n_)507 sexp* rlang_is_list(sexp* x, sexp* n_) {
508 r_ssize n = validate_n(n_);
509 return r_shared_lgl(r_is_list(x, n));
510 }
511
rlang_is_atomic(sexp * x,sexp * n_)512 sexp* rlang_is_atomic(sexp* x, sexp* n_) {
513 r_ssize n = validate_n(n_);
514 return r_shared_lgl(r_is_atomic(x, n));
515 }
rlang_is_vector(sexp * x,sexp * n_)516 sexp* rlang_is_vector(sexp* x, sexp* n_) {
517 r_ssize n = validate_n(n_);
518 return r_shared_lgl(r_is_vector(x, n));
519 }
520
rlang_is_logical(sexp * x,sexp * n_)521 sexp* rlang_is_logical(sexp* x, sexp* n_) {
522 r_ssize n = validate_n(n_);
523 return r_shared_lgl(r_is_logical(x, n));
524 }
rlang_is_integer(sexp * x,sexp * n_)525 sexp* rlang_is_integer(sexp* x, sexp* n_) {
526 r_ssize n = validate_n(n_);
527 return r_shared_lgl(r_is_integer(x, n, -1));
528 }
rlang_is_double(sexp * x,sexp * n_,sexp * finite_)529 sexp* rlang_is_double(sexp* x, sexp* n_, sexp* finite_) {
530 r_ssize n = validate_n(n_);
531 int finite = validate_finite(finite_);
532 return r_shared_lgl(r_is_double(x, n, finite));
533 }
rlang_is_integerish(sexp * x,sexp * n_,sexp * finite_)534 sexp* rlang_is_integerish(sexp* x, sexp* n_, sexp* finite_) {
535 r_ssize n = validate_n(n_);
536 int finite = validate_finite(finite_);
537 return r_shared_lgl(r_is_integerish(x, n, finite));
538 }
539
rlang_is_character(sexp * x,sexp * n_)540 sexp* rlang_is_character(sexp* x, sexp* n_) {
541 r_ssize n = validate_n(n_);
542 return r_shared_lgl(r_is_character(x, n));
543 }
rlang_is_raw(sexp * x,sexp * n_)544 sexp* rlang_is_raw(sexp* x, sexp* n_) {
545 r_ssize n = validate_n(n_);
546 return r_shared_lgl(r_is_raw(x, n));
547 }
548
rlang_is_string(sexp * x,sexp * string)549 sexp* rlang_is_string(sexp* x, sexp* string) {
550 if (r_typeof(x) != r_type_character || r_length(x) != 1) {
551 return r_shared_false;
552 }
553
554 sexp* value = r_chr_get(x, 0);
555
556 if (value == NA_STRING) {
557 return r_shared_false;
558 }
559
560 if (string == r_null) {
561 return r_shared_true;
562 }
563
564 if (!rlang_is_string(string, r_null)) {
565 r_abort("`string` must be `NULL` or a string");
566 }
567
568 bool out = false;
569 r_ssize n = r_length(string);
570 sexp* const * p_string = r_chr_deref_const(string);
571
572 for (r_ssize i = 0; i < n; ++i) {
573 if (p_string[i] == value) {
574 out = true;
575 break;
576 }
577 }
578
579 return r_shared_lgl(out);
580 }
581