1 #ifndef RLANG_INTERNAL_EXPR_INTERP_H
2 #define RLANG_INTERNAL_EXPR_INTERP_H
3 
4 #include "quo.h"
5 
6 
7 #define UQ_N 2
8 #define UQS_N 2
9 
10 static const char* uqs_names[UQS_N] = { "UQS", "!!!"};
11 
12 
is_maybe_rlang_call(sexp * x,const char * name)13 static inline bool is_maybe_rlang_call(sexp* x, const char* name) {
14   return
15     r_is_call(x, name) ||
16     r_is_namespaced_call(x, "rlang", name);
17 }
is_maybe_rlang_call_any(sexp * x,const char ** names,int n)18 static inline bool is_maybe_rlang_call_any(sexp* x, const char** names, int n) {
19   return
20     r_is_call_any(x, names, n) ||
21     r_is_namespaced_call_any(x, "rlang", names, n);
22 }
is_splice_call(sexp * node)23 static inline bool is_splice_call(sexp* node) {
24   return is_maybe_rlang_call_any(node, uqs_names, UQS_N);
25 }
26 
27 
28 #define EXPANSION_OP_MAX 7
29 enum expansion_op {
30   OP_EXPAND_NONE,
31   OP_EXPAND_UQ,
32   OP_EXPAND_UQS,
33   OP_EXPAND_UQN,
34   OP_EXPAND_FIXUP,
35   OP_EXPAND_DOT_DATA,
36   OP_EXPAND_CURLY
37 };
38 
39 struct expansion_info {
40   enum expansion_op op;
41   sexp* operand;  // Expression being unquoted
42   sexp* parent;   // Node pointing to the future unquoted value
43   sexp* root;     // Expression wrapping the unquoted value (optional)
44 };
45 
init_expansion_info()46 static inline struct expansion_info init_expansion_info() {
47   struct expansion_info info;
48 
49   info.op = OP_EXPAND_NONE;
50   info.operand = r_null;
51   info.parent = r_null;
52   info.root = r_null;
53 
54   return info;
55 }
56 
57 struct expansion_info which_uq_op(sexp* x);
58 struct expansion_info which_expansion_op(sexp* x, bool unquote_names);
59 struct expansion_info is_big_bang_op(sexp* x);
60 
61 sexp* big_bang_coerce(sexp* expr);
62 
63 sexp* rlang_interp(sexp* x, sexp* env);
64 sexp* call_interp(sexp* x, sexp* env);
65 sexp* call_interp_impl(sexp* x, sexp* env, struct expansion_info info);
66 
67 
forward_quosure(sexp * x,sexp * env)68 static inline sexp* forward_quosure(sexp* x, sexp* env) {
69   switch (r_typeof(x)) {
70   case r_type_call:
71     if (rlang_is_quosure(x)) {
72       return x;
73     }
74     // else fallthrough
75   case r_type_symbol:
76   case r_type_closure:
77     return rlang_new_quosure(x, env);
78   default:
79     return rlang_new_quosure(x, r_empty_env);
80   }
81 }
82 
83 
84 #endif
85