123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- translate_to_r <- function(node, envir) {
- UseMethod("translate_to_r", node)
- }
- translate_to_r.node <- function(node, envir) {
- stop("translation error")
- }
- translate_to_r.llr_nil <- function(node, envir) {
- NULL
- }
- translate_to_r.ral_string <- function(node, envir) {
- node
- }
- translate_to_r.integer <- function(node, envir) {
- ral_integer(node)
- }
- translate_to_r.ral_integer <- function(node, envir) {
- node
- }
- translate_to_r.ral_double <- function(node, envir) {
- node
- }
- translate_to_r.numeric <- function(node, envir) {
- ral_double(node)
- }
- translate_to_r.name <- function(node, envir) {
- node_str <- as.character(node)
- if (nchar(node_str) >= 3 && grepl("/", node_str, fixed = TRUE)) {
- split_str <- strsplit(node_str, "/", fixed = TRUE)[[1]]
- ns <- sym(split_str[[1]])
- symbol <- sym(split_str[[2]])
- return(
- expr(
- `*ns_manager*`$val_by_ns(!!ns, !!symbol)
- )
- )
- }
- sym(node)
- }
- translate_to_r.ns_call <- function(node, envir) {
- expr(`*ns_manager*`$create(!!as.character(sym(node[[2]]))))
- }
- translate_to_r.r_name <- function(node, envir) {
- r_val_name <- as.character(node)
- r_val <- substr(r_val_name, 3, nchar(r_val_name))
- tryCatch(
- parse(text = r_val)[[1]],
- error = function(e) sym(r_val)
- )
- }
- translate_to_r.keyword_node <- function(node, envir) {
- node
- }
- translate_to_r.llr_boolean <- function(node, envir) {
- node
- }
- translate_to_r.symbolic_value_inf_node <- function(node, envir) {
- Inf
- }
- translate_to_r.symbolic_value_minf_node <- function(node, envir) {
- -Inf
- }
- translate_to_r.symbolic_value_nan_node <- function(node, envir) {
- NaN
- }
- translate_to_r.def_call <- function(node, envir) {
- target <- node[[2]]
- expr({
- `*ns_manager*`$get_current_ns()$set(
- !!target,
- !!translate_to_r(node[[3]], envir)
- )
- })
- }
- translate_to_r.if_call <- function(node, envir) {
- yes <- translate_to_r(node[[3]], envir)
- no <- if (length(node) > 3) {
- translate_to_r(node[[4]], envir)
- } else {
- NULL # TODO: replace with nil once there is a nil
- }
- expr(
- (function() {
- test <- !!translate_to_r(node[[2]], envir)
- `if`(
- !( # NULL (later nil) and false are the only values that evaluate to false
- is.null(test) ||
- (is.logical(test) && length(test) == 1 && !is.na(test) && !test)
- )
- ,
- !!!base::list(yes, no)
- )
- })()
- )
- }
- translate_to_r.meta_node <- function(node, envir) {
- expr((function() {
- val <- quote(!!translate_to_r(node$value, envir))
- meta <- !!translate_to_r(node$meta_data, envir)
- attr(val, "ral_meta_data") <- meta
- val
- })())
- }
- translate_to_r.fn_call <- function(node, envir) {
- stopifnot(length(node) > 2)
- has_name <- is_symbol(node[[2]])
- fun_name <- if (has_name) {
- node[[2]]
- }
- # here is a break point, either we observe a vector, then we have
- # case 1 or we observe a list, then we can expect case 2
- # at the moment we just implement case 1
- is_multi_fun <- inherits(node[[has_name + 2]], "ral_list")
- if (is_multi_fun) {
- fun_defs <- if (has_name) node[-2] else node
- code <- lapply(fun_defs[-1], function(fun_def) {
- fun_node <- ral_list(.data = fun_def, .subclass = "fn_call")
- create_fun_r_ast(FALSE, fun_name, fun_node)
- })
- # TODO: assumes that dots are last
- code <- lapply(code, function(x) {
- if (is.finite(x$len_args)) {
- expr(
- if (arg_len == !!x$len_args) {
- return(
- (!!x$fun)(...)
- )
- }
- )
- } else {
- expr(
- return(
- (!!x$fun)(...)
- )
- )
- }
- })
- recur <- if (has_name) {
- fun_name
- } else {
- quote(wat________) # TODO
- }
- expr((function() {
- `<-`(!!recur, function(...) {
- arg_len <- ...length()
- !!!code
- stop("Invalid arity provided")
- })
- })())
- } else {
- create_fun_r_ast(has_name, fun_name, node[-1])[["fun"]]
- }
- }
- create_fun_r_ast <- function(has_name, fun_name, node) {
- has_condition_map <- inherits(node[[has_name + 2]], "map_node")
- body <- translate_to_r(node[[has_name + has_condition_map + 2]], envir)
- args <- node[[has_name + 1]]
- has_any_ampand <- length(args) > 1 && args[[length(args) - 1]] == "&"
- if (has_any_ampand) {
- args <- args[-(length(args) - 1)]
- dot_name <- sym(args[[length(args)]])
- args[[length(args)]] <- quote(`...`)
- body <- expr({
- `<-`(!!dot_name, base::list(...))
- !!body
- })
- }
- if (has_name) {
- body <- expr({
- `<-`(!!fun_name, Recall)
- !!body
- })
- }
- if (has_condition_map) {
- stop("not implemented")
- }
- # args are symbols at compile time
- stopifnot(
- all(
- vapply(args, inherits, logical(1), "name")
- )
- )
- arg_names <- vapply(args, function(x) {
- paste0(deparse(x), collapse = "")
- }, character(1))
- arg_values <- lapply(args, function(x) {
- quote(alist(a = ))[[2]]
- })
- names(arg_values) <- arg_names
- len_params <- if (has_any_ampand) Inf else length(args)
- list(
- len_args = len_params,
- fun = expr(rlang::new_function(!!arg_values, quote(!!body)))
- )
- }
- translate_to_r.let_call <- function(node, envir) {
- args <- node[[2]]
- body_exprs <- lapply(node[-(1:2)], function(x) {
- translate_to_r(x, envir)
- })
- stopifnot(length(args) %% 2 == 0)
- var_def <- mapply(
- function(name, value) {
- stopifnot(is.name(name))
- expr(`<-`(!!name, !!translate_to_r(value, envir)))
- },
- as.list(args[seq(1, (length(args) - 1), 2)]),
- as.list(args[seq(2, length(args), 2)])
- )
- expr(
- (function() {
- !!!var_def
- !!!body_exprs
- })()
- )
- }
- translate_to_r.squote_call <- function(node, envir) {
- expr(squote(!!node[[2]]))
- }
- translate_to_r.quote_call <- function(node, envir) {
- expr(quote(!!node[[2]]))
- }
- translate_to_r.ral_vector <- function(node, envir) {
- vals <- lapply(node, function(x) {
- translate_to_r(x, envir)
- })
- expr(ral_vector(!!!vals, .meta = !!meta_data(node)))
- }
- translate_to_r.ral_map <- function(node, envir) {
- keys <- lapply(node$keys(), function(x) {
- translate_to_r(x, envir)
- })
- vals <- lapply(node$values(), function(x) {
- translate_to_r(x, envir)
- })
- expr(
- ral_map(
- keys = base::list(!!!keys),
- values = base::list(!!!vals)
- )
- )
- }
- translate_to_r.ral_list <- function(node, envir) {
- if (length(node) >= 1 && inherits(node[[1]], "r_name")) {
- return(translate_to_r.r_call(node, envir))
- }
- x <- lapply(node, function(x) {
- translate_to_r(x, envir)
- })
- if (length(x) >= 1) {
- return(expr((!!x[[1]])(!!!x[-1])))
- }
- expr(!!ral_list())
- }
- translate_to_r.list <- translate_to_r.ral_list
- translate_to_r.loop_call <- function(node, envir) {
- args <- node[[2]]
- body_exprs <- lapply(node[-(1:2)], function(x) {
- translate_to_r(x, envir)
- })
- stopifnot(length(args) %% 2 == 0)
- names <- as.list(args[seq(1, (length(args) - 1), 2)])
- init_vals <- as.list(args[seq(2, length(args), 2)])
- var_assigns <- mapply(function(name, value) {
- stopifnot(is.name(name))
- expr(assign(!!as.character(name), !!translate_to_r(value, envir), envir = ral_______eval_env))
- }, names, init_vals)
- var_gets <- lapply(names, function(name) {
- expr(`<-`(!!name, get0(!!as.character(name), envir = ral_______eval_env)))
- })
- var_assigns_idx <- mapply(function(i, name) {
- stopifnot(is.name(name))
- expr({
- if (i == !!i) {
- assign(!!as.character(name), ...elt(i), envir = ral_______eval_env)
- }
- })
- }, seq_along(names), names)
- expr(
- (function() {
- ral_______eval_env <- new.env()
- ral_______return_val <- NULL
- !!!var_assigns
- ral____tmp_recur_next <- FALSE
- ral____tmp_recur <- function(...) {
- for (i in seq_len(...length())) {
- !!!var_assigns_idx
- }
- ral____tmp_recur_next <<- TRUE
- }
- repeat {
- !!!var_gets
- !!!body_exprs[-length(body_exprs)]
- ral_______return_val <- {
- !!body_exprs[[length(body_exprs)]]
- }
- if (ral____tmp_recur_next) {
- ral____tmp_recur_next <- FALSE
- next()
- } else {
- break()
- }
- }
- ral_______return_val
- })()
- )
- }
- translate_to_r.recur_call <- function(node, envir) {
- new_values <- lapply(node[-1], function(x) {
- translate_to_r(x, envir)
- })
- expr({
- ral____tmp_recur(!!!new_values)
- })
- }
- #' @importFrom stats setNames
- translate_to_r.r_call <- function(node, envir) {
- r_fun <- translate_to_r(node[[1]])
- args <- list()
- free_slot <- 1
- i <- 2
- while (i <= length(node)) {
- val <- node[[i]]
- if (inherits(val, "keyword_node")) {
- stopifnot(i + 1 <= length(node))
- args[[free_slot]] <- setNames(
- list(expr(!!translate_to_r(node[[i + 1]]))),
- as.character(drop_colon(val))
- )
- i <- i + 2
- } else {
- args[[free_slot]] <- translate_to_r(val, envir)
- i <- i + 1
- }
- free_slot <- free_slot + 1
- }
- # TODO: revisit the next line
- args <- as.list(unlist(args, recursive = FALSE))
- rlang::call2(expr(!!r_fun), !!!args)
- }
- drop_colon <- function(keyword) {
- stopifnot(startsWith(keyword, ":"))
- sym(substr(keyword, 2, nchar(keyword)))
- }
- # translate_to_r(read_tokens(tokenize("\"abc\"")))
|