Callbacks must be functions that take three arguments: The expression to rewrite, the environment of the function we are rewriting (i.e. the environment it is defined in, not the function call frame), and a list of formal parameters of the function we are translating.

rewrite_callbacks()

analysis_callbacks()

with_atomic_callback(callbacks, fn)

with_pairlist_callback(callbacks, fn)

with_symbol_callback(callbacks, fn, include_missing = FALSE)

with_primitive_callback(callbacks, fn)

with_call_callback(callbacks, fn)

with_topdown_pairlist_callback(callbacks, fn)

with_topdown_call_callback(callbacks, fn)

Arguments

callbacks

The list of callbacks

fn

A function to install as a callback.

include_missing

For symbols, it is possible that the expression is missing. This can happen in pair-lists if a function parameter does not have a default argument. By default, the callback is not invoked on missing expressions--there is very little you can do with them -- but you can include them by setting this parameter to TRUE.

Details

The flow of a depth-first traversal is as follows:

For expressions that are atomic, i.e. are either atomic values, pairlists, symbols, or primitives, the corresponding callback is called with the expression. The callbacks are called with the expression, expr, the environment of the function we are traversing, env, the parameters of that function, params, information collected top-down in topdown, warning flags through the wflags parameter, and any additional user-provided arguments through .... If the callbacks are used in a rewrite traversal, see depth_first_rewrite_function(), they must return an expression. This expression will be inserted as a substitute of the expr argument in the function being rewritten. If the callback is part of an analysis, see depth_first_analyse_function(), then it can return any data; what it returns will be provided to the callbacks on the enclosing expression via the bottomup parameter.

For call expressions, the topdown callback is invoked before the call is traversed. It is provided with the same arguments as the other callbacks and in addition a thunk skip that it can use to prevent the depth-first traversal to explore the call further. Whatever the topdown callback returns will be provided to the call callback via the argument topdown it it is called (i.e. if the topdown callback doesn't invoke skip).

After the topdown callback is executed, if it doesn't call skip, the call callback is called on the expression. It is called with the same arguments as the other callbacks, and must return an expression if part of a rewrite traversal or any collected information if part of an analysis traversal.

Functions

  • rewrite_callbacks: Default callbacks for rewriting expressions

  • analysis_callbacks: Default callbacks for analysing expressions

  • with_atomic_callback: Set the atomic callback function.

  • with_pairlist_callback: Set the pairlist callback function.

  • with_symbol_callback: Set the symbol callback function.

  • with_primitive_callback: Set the primitive callback function.

  • with_call_callback: Set the call callback function.

  • with_topdown_pairlist_callback: Set the topdown information-passing callback function for pair-lists

  • with_topdown_call_callback: Set the topdown information-passing callback function for calls.

See also

with_atomic_callback

with_symbol_callback

with_primitive_callback

with_pairlist_callback

with_call_callback

with_topdown_pairlist_callback

with_topdown_call_callback

warning_flags

Examples

f <- function(x) 2 + x cb <- rewrite_callbacks() %>% add_call_callback(f, function(expr, ...) { quote(2 + x) }) tr_f <- . %>% rewrite() %>% rewrite_with(cb) g <- function(y) y + f(y) tr_f(g)
#> function (y) #> y + (2 + x) #> <environment: 0x11465c840>
collect_symbols <- function(expr, ...) { list(symbols = as.character(expr)) } callbacks <- analysis_callbacks() %>% with_symbol_callback(collect_symbols) f %>% analyse() %>% analyse_with(callbacks)
#> $symbols #> [1] "+" "x" #>