18.15 Two helper functions

  • First, we need an epxr_type() function to return the type of expression element as a string.
expr_type <- function(x) {
  if (rlang::is_syntactic_literal(x)) {
    "constant"
  } else if (is.symbol(x)) {
    "symbol"
  } else if (is.call(x)) {
    "call"
  } else if (is.pairlist(x)) {
    "pairlist"
  } else {
    typeof(x)
  }
}
expr_type(expr("a"))
# [1] "constant"
expr_type(expr(x))
# [1] "symbol"
expr_type(expr(f(1, 2)))
# [1] "call"
  • Second, we need a wrapper function to handle exceptions.
switch_expr <- function(x, ...) {
  switch(expr_type(x),
    ...,
    stop("Don't know how to handle type ", typeof(x), call. = FALSE)
  )
}
  • Lastly, we can write a basic template that walks the AST using the switch() statement.
recurse_call <- function(x) {
  switch_expr(x,
    # Base cases
    symbol = ,
    constant = ,

    # Recursive cases
    call = ,
    pairlist =
  )
}