ast-translator.R 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. translate_to_r <- function(node, envir) {
  2. UseMethod("translate_to_r", node)
  3. }
  4. translate_to_r.node <- function(node, envir) {
  5. stop("translation error")
  6. }
  7. translate_to_r.llr_nil <- function(node, envir) {
  8. NULL
  9. }
  10. translate_to_r.ral_string <- function(node, envir) {
  11. node
  12. }
  13. translate_to_r.integer <- function(node, envir) {
  14. ral_integer(node)
  15. }
  16. translate_to_r.ral_integer <- function(node, envir) {
  17. node
  18. }
  19. translate_to_r.ral_double <- function(node, envir) {
  20. node
  21. }
  22. translate_to_r.numeric <- function(node, envir) {
  23. ral_double(node)
  24. }
  25. translate_to_r.name <- function(node, envir) {
  26. node_str <- as.character(node)
  27. if (nchar(node_str) >= 3 && grepl("/", node_str, fixed = TRUE)) {
  28. split_str <- strsplit(node_str, "/", fixed = TRUE)[[1]]
  29. ns <- sym(split_str[[1]])
  30. symbol <- sym(split_str[[2]])
  31. return(
  32. expr(
  33. `*ns_manager*`$val_by_ns(!!ns, !!symbol)
  34. )
  35. )
  36. }
  37. sym(node)
  38. }
  39. translate_to_r.ns_call <- function(node, envir) {
  40. expr(`*ns_manager*`$create(!!as.character(sym(node[[2]]))))
  41. }
  42. translate_to_r.r_name <- function(node, envir) {
  43. r_val_name <- as.character(node)
  44. r_val <- substr(r_val_name, 3, nchar(r_val_name))
  45. tryCatch(
  46. parse(text = r_val)[[1]],
  47. error = function(e) sym(r_val)
  48. )
  49. }
  50. translate_to_r.keyword_node <- function(node, envir) {
  51. node
  52. }
  53. translate_to_r.llr_boolean <- function(node, envir) {
  54. node
  55. }
  56. translate_to_r.symbolic_value_inf_node <- function(node, envir) {
  57. Inf
  58. }
  59. translate_to_r.symbolic_value_minf_node <- function(node, envir) {
  60. -Inf
  61. }
  62. translate_to_r.symbolic_value_nan_node <- function(node, envir) {
  63. NaN
  64. }
  65. translate_to_r.def_call <- function(node, envir) {
  66. target <- node[[2]]
  67. expr({
  68. `*ns_manager*`$get_current_ns()$set(
  69. !!target,
  70. !!translate_to_r(node[[3]], envir)
  71. )
  72. })
  73. }
  74. translate_to_r.if_call <- function(node, envir) {
  75. yes <- translate_to_r(node[[3]], envir)
  76. no <- if (length(node) > 3) {
  77. translate_to_r(node[[4]], envir)
  78. } else {
  79. NULL # TODO: replace with nil once there is a nil
  80. }
  81. expr(
  82. (function() {
  83. test <- !!translate_to_r(node[[2]], envir)
  84. `if`(
  85. !( # NULL (later nil) and false are the only values that evaluate to false
  86. is.null(test) ||
  87. (is.logical(test) && length(test) == 1 && !is.na(test) && !test)
  88. )
  89. ,
  90. !!!base::list(yes, no)
  91. )
  92. })()
  93. )
  94. }
  95. translate_to_r.meta_node <- function(node, envir) {
  96. expr((function() {
  97. val <- quote(!!translate_to_r(node$value, envir))
  98. meta <- !!translate_to_r(node$meta_data, envir)
  99. attr(val, "ral_meta_data") <- meta
  100. val
  101. })())
  102. }
  103. translate_to_r.fn_call <- function(node, envir) {
  104. stopifnot(length(node) > 2)
  105. has_name <- is_symbol(node[[2]])
  106. fun_name <- if (has_name) {
  107. node[[2]]
  108. }
  109. # here is a break point, either we observe a vector, then we have
  110. # case 1 or we observe a list, then we can expect case 2
  111. # at the moment we just implement case 1
  112. is_multi_fun <- inherits(node[[has_name + 2]], "ral_list")
  113. if (is_multi_fun) {
  114. fun_defs <- if (has_name) node[-2] else node
  115. code <- lapply(fun_defs[-1], function(fun_def) {
  116. fun_node <- ral_list(.data = fun_def, .subclass = "fn_call")
  117. create_fun_r_ast(FALSE, fun_name, fun_node)
  118. })
  119. # TODO: assumes that dots are last
  120. code <- lapply(code, function(x) {
  121. if (is.finite(x$len_args)) {
  122. expr(
  123. if (arg_len == !!x$len_args) {
  124. return(
  125. (!!x$fun)(...)
  126. )
  127. }
  128. )
  129. } else {
  130. expr(
  131. return(
  132. (!!x$fun)(...)
  133. )
  134. )
  135. }
  136. })
  137. recur <- if (has_name) {
  138. fun_name
  139. } else {
  140. quote(wat________) # TODO
  141. }
  142. expr((function() {
  143. `<-`(!!recur, function(...) {
  144. arg_len <- ...length()
  145. !!!code
  146. stop("Invalid arity provided")
  147. })
  148. })())
  149. } else {
  150. create_fun_r_ast(has_name, fun_name, node[-1])[["fun"]]
  151. }
  152. }
  153. create_fun_r_ast <- function(has_name, fun_name, node) {
  154. has_condition_map <- inherits(node[[has_name + 2]], "map_node")
  155. body <- translate_to_r(node[[has_name + has_condition_map + 2]], envir)
  156. args <- node[[has_name + 1]]
  157. has_any_ampand <- length(args) > 1 && args[[length(args) - 1]] == "&"
  158. if (has_any_ampand) {
  159. args <- args[-(length(args) - 1)]
  160. dot_name <- sym(args[[length(args)]])
  161. args[[length(args)]] <- quote(`...`)
  162. body <- expr({
  163. `<-`(!!dot_name, base::list(...))
  164. !!body
  165. })
  166. }
  167. if (has_name) {
  168. body <- expr({
  169. `<-`(!!fun_name, Recall)
  170. !!body
  171. })
  172. }
  173. if (has_condition_map) {
  174. stop("not implemented")
  175. }
  176. # args are symbols at compile time
  177. stopifnot(
  178. all(
  179. vapply(args, inherits, logical(1), "name")
  180. )
  181. )
  182. arg_names <- vapply(args, function(x) {
  183. paste0(deparse(x), collapse = "")
  184. }, character(1))
  185. arg_values <- lapply(args, function(x) {
  186. quote(alist(a = ))[[2]]
  187. })
  188. names(arg_values) <- arg_names
  189. len_params <- if (has_any_ampand) Inf else length(args)
  190. list(
  191. len_args = len_params,
  192. fun = expr(rlang::new_function(!!arg_values, quote(!!body)))
  193. )
  194. }
  195. translate_to_r.let_call <- function(node, envir) {
  196. args <- node[[2]]
  197. body_exprs <- lapply(node[-(1:2)], function(x) {
  198. translate_to_r(x, envir)
  199. })
  200. stopifnot(length(args) %% 2 == 0)
  201. var_def <- mapply(
  202. function(name, value) {
  203. stopifnot(is.name(name))
  204. expr(`<-`(!!name, !!translate_to_r(value, envir)))
  205. },
  206. as.list(args[seq(1, (length(args) - 1), 2)]),
  207. as.list(args[seq(2, length(args), 2)])
  208. )
  209. expr(
  210. (function() {
  211. !!!var_def
  212. !!!body_exprs
  213. })()
  214. )
  215. }
  216. translate_to_r.squote_call <- function(node, envir) {
  217. expr(squote(!!node[[2]]))
  218. }
  219. translate_to_r.quote_call <- function(node, envir) {
  220. expr(quote(!!node[[2]]))
  221. }
  222. translate_to_r.ral_vector <- function(node, envir) {
  223. vals <- lapply(node, function(x) {
  224. translate_to_r(x, envir)
  225. })
  226. expr(ral_vector(!!!vals, .meta = !!meta_data(node)))
  227. }
  228. translate_to_r.ral_map <- function(node, envir) {
  229. keys <- lapply(node$keys(), function(x) {
  230. translate_to_r(x, envir)
  231. })
  232. vals <- lapply(node$values(), function(x) {
  233. translate_to_r(x, envir)
  234. })
  235. expr(
  236. ral_map(
  237. keys = base::list(!!!keys),
  238. values = base::list(!!!vals)
  239. )
  240. )
  241. }
  242. translate_to_r.ral_list <- function(node, envir) {
  243. if (length(node) >= 1 && inherits(node[[1]], "r_name")) {
  244. return(translate_to_r.r_call(node, envir))
  245. }
  246. x <- lapply(node, function(x) {
  247. translate_to_r(x, envir)
  248. })
  249. if (length(x) >= 1) {
  250. return(expr((!!x[[1]])(!!!x[-1])))
  251. }
  252. expr(!!ral_list())
  253. }
  254. translate_to_r.list <- translate_to_r.ral_list
  255. translate_to_r.loop_call <- function(node, envir) {
  256. args <- node[[2]]
  257. body_exprs <- lapply(node[-(1:2)], function(x) {
  258. translate_to_r(x, envir)
  259. })
  260. stopifnot(length(args) %% 2 == 0)
  261. names <- as.list(args[seq(1, (length(args) - 1), 2)])
  262. init_vals <- as.list(args[seq(2, length(args), 2)])
  263. var_assigns <- mapply(function(name, value) {
  264. stopifnot(is.name(name))
  265. expr(assign(!!as.character(name), !!translate_to_r(value, envir), envir = ral_______eval_env))
  266. }, names, init_vals)
  267. var_gets <- lapply(names, function(name) {
  268. expr(`<-`(!!name, get0(!!as.character(name), envir = ral_______eval_env)))
  269. })
  270. var_assigns_idx <- mapply(function(i, name) {
  271. stopifnot(is.name(name))
  272. expr({
  273. if (i == !!i) {
  274. assign(!!as.character(name), ...elt(i), envir = ral_______eval_env)
  275. }
  276. })
  277. }, seq_along(names), names)
  278. expr(
  279. (function() {
  280. ral_______eval_env <- new.env()
  281. ral_______return_val <- NULL
  282. !!!var_assigns
  283. ral____tmp_recur_next <- FALSE
  284. ral____tmp_recur <- function(...) {
  285. for (i in seq_len(...length())) {
  286. !!!var_assigns_idx
  287. }
  288. ral____tmp_recur_next <<- TRUE
  289. }
  290. repeat {
  291. !!!var_gets
  292. !!!body_exprs[-length(body_exprs)]
  293. ral_______return_val <- {
  294. !!body_exprs[[length(body_exprs)]]
  295. }
  296. if (ral____tmp_recur_next) {
  297. ral____tmp_recur_next <- FALSE
  298. next()
  299. } else {
  300. break()
  301. }
  302. }
  303. ral_______return_val
  304. })()
  305. )
  306. }
  307. translate_to_r.recur_call <- function(node, envir) {
  308. new_values <- lapply(node[-1], function(x) {
  309. translate_to_r(x, envir)
  310. })
  311. expr({
  312. ral____tmp_recur(!!!new_values)
  313. })
  314. }
  315. #' @importFrom stats setNames
  316. translate_to_r.r_call <- function(node, envir) {
  317. r_fun <- translate_to_r(node[[1]])
  318. args <- list()
  319. free_slot <- 1
  320. i <- 2
  321. while (i <= length(node)) {
  322. val <- node[[i]]
  323. if (inherits(val, "keyword_node")) {
  324. stopifnot(i + 1 <= length(node))
  325. args[[free_slot]] <- setNames(
  326. list(expr(!!translate_to_r(node[[i + 1]]))),
  327. as.character(drop_colon(val))
  328. )
  329. i <- i + 2
  330. } else {
  331. args[[free_slot]] <- translate_to_r(val, envir)
  332. i <- i + 1
  333. }
  334. free_slot <- free_slot + 1
  335. }
  336. # TODO: revisit the next line
  337. args <- as.list(unlist(args, recursive = FALSE))
  338. rlang::call2(expr(!!r_fun), !!!args)
  339. }
  340. drop_colon <- function(keyword) {
  341. stopifnot(startsWith(keyword, ":"))
  342. sym(substr(keyword, 2, nchar(keyword)))
  343. }
  344. # translate_to_r(read_tokens(tokenize("\"abc\"")))