@@ -23,17 +23,9 @@ pre_visit <- function(pd_nested, funs) {
2323 if (length(funs ) == 0L ) {
2424 return (pd_nested )
2525 }
26- pd_nested <- visit_one(pd_nested , funs )
2726
28- children <- pd_nested $ child
29- for (i in seq_along(children )) {
30- child <- children [[i ]]
31- if (! is.null(child )) {
32- children [[i ]] <- pre_visit(child , funs )
33- }
34- }
35- pd_nested $ child <- children
36- pd_nested
27+ fun <- make_visit_one(funs )
28+ pre_visit_one(pd_nested , fun )
3729}
3830
3931# ' @rdname visit
@@ -65,16 +57,8 @@ post_visit <- function(pd_nested, funs) {
6557 return (pd_nested )
6658 }
6759
68- children <- pd_nested $ child
69- for (i in seq_along(children )) {
70- child <- children [[i ]]
71- if (! is.null(child )) {
72- children [[i ]] <- post_visit(child , funs )
73- }
74- }
75- pd_nested $ child <- children
76-
77- visit_one(pd_nested , funs )
60+ fun <- make_visit_one(funs )
61+ post_visit_one(pd_nested , fun )
7862}
7963
8064# ' @rdname visit
@@ -99,17 +83,33 @@ post_visit_one <- function(pd_nested, fun) {
9983
10084# ' Transform a flat parse table with a list of transformers
10185# '
102- # ' Uses [Reduce()] to apply each function of `funs` sequentially to
103- # ' `pd_flat`.
86+ # ' Creates a single transformer function from a list of transformer functions.
87+ # '
88+ # ' @details
89+ # ' For an input of the form `list(f1 = f1, f2 = f2)`, creates a function
90+ # '
91+ # ' ```r
92+ # ' function(pd_flat) {
93+ # ' pd_flat <- f1(pd_flat)
94+ # ' pd_flat <- f2(pd_flat)
95+ # ' pd_flat
96+ # ' }
97+ # ' ```
98+ # '
99+ # ' The function's environment is constructed from `rlang::as_environment(funs)`.
100+ # ' This makes function sequences called by visitors interpretable in profiling.
101+ # '
104102# ' @param pd_flat A flat parse table.
105- # ' @param funs A list of transformer functions.
103+ # ' @param funs A named list of transformer functions.
106104# ' @family visitors
107105# ' @keywords internal
108- visit_one <- function (pd_flat , funs ) {
109- for (f in funs ) {
110- pd_flat <- f(pd_flat )
111- }
112- pd_flat
106+ make_visit_one <- function (funs ) {
107+ calls <- map(rlang :: syms(names(funs )), ~ rlang :: expr(pd_flat <- (!! .x )(pd_flat )))
108+ all_calls <- c(calls , rlang :: expr(pd_flat ))
109+ body <- rlang :: call2(" {" , !!! all_calls )
110+
111+ env <- rlang :: as_environment(funs , rlang :: base_env())
112+ rlang :: new_function(rlang :: pairlist2(pd_flat = ), body , env )
113113}
114114
115115# ' Propagate context to terminals
0 commit comments