From f2a9e30540f772f03ba670ef9a38908ac6c97246 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Wed, 10 Sep 2025 09:58:55 +0200 Subject: [PATCH 1/2] Use Air --- .Rbuildignore | 2 + .vscode/extensions.json | 5 + .vscode/settings.json | 10 + R/async.R | 6 +- R/generator.R | 299 +-- R/iterator-adapt.R | 47 +- R/iterator.R | 1 - R/parser.R | 239 +- R/step-reduce.R | 68 +- R/utils-vector.R | 6 +- air.toml | 0 tests/testthat/_snaps/async.md | 593 ++--- tests/testthat/_snaps/generator.md | 52 +- tests/testthat/_snaps/parser-block.md | 656 +++--- tests/testthat/_snaps/parser-if.md | 2022 +++++++++-------- tests/testthat/_snaps/parser-loop.md | 3003 +++++++++++++------------ tests/testthat/_snaps/parser.md | 2974 +++++++++++++----------- tests/testthat/test-async.R | 59 +- tests/testthat/test-generator.R | 76 +- tests/testthat/test-iterator-for.R | 88 +- tests/testthat/test-iterator.R | 26 +- tests/testthat/test-parser-block.R | 6 +- tests/testthat/test-parser-if.R | 4 +- tests/testthat/test-parser-loop.R | 71 +- tests/testthat/test-parser.R | 121 +- tests/testthat/test-step-reduce.R | 36 +- 26 files changed, 5785 insertions(+), 4685 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 air.toml diff --git a/.Rbuildignore b/.Rbuildignore index 5dfd416..9ae915f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -12,3 +12,5 @@ ^revdep$ ^cran-comments\.md$ ^CRAN-SUBMISSION$ +^\.vscode$ +^[.]?air[.]toml$ diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..344f76e --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "Posit.air-vscode" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a9f69fe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "[r]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "Posit.air-vscode" + }, + "[quarto]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "quarto.quarto" + } +} diff --git a/R/async.R b/R/async.R index b827d03..7b1897c 100644 --- a/R/async.R +++ b/R/async.R @@ -76,7 +76,7 @@ await <- function(x) { #' @export async_sleep <- function(seconds) { promises::promise(function(resolve, reject) { - later::later(~ resolve(NULL) , delay = seconds) + later::later(~ resolve(NULL), delay = seconds) }) } @@ -127,7 +127,9 @@ async_generator <- function(fn) { #' @inheritParams await #' @export await_each <- function(x) { - abort("`await_each()` must be called within a `for` loop of an async function.") + abort( + "`await_each()` must be called within a `for` loop of an async function." + ) } #' @export diff --git a/R/generator.R b/R/generator.R index 7bae327..fa336f9 100644 --- a/R/generator.R +++ b/R/generator.R @@ -126,161 +126,168 @@ generator0 <- function(fn, type = "generator") { # Create the generator factory (returned by `generator()` and # entered by `async()`) - factory <- new_function(fmls, quote({ - # Evaluate here so the formals of the generator factory do not - # mask our variables - `_private` <- rlang::env(`_parent`) - `_private`$generator_env <- base::environment() - `_private`$caller_env <- base::parent.frame() - - base::local(envir = `_private`, { - generator_env <- environment()$generator_env - caller_env <- environment()$caller_env - - # Prevent lints about unknown bindings - exits <- NULL - exited <- NULL - cleanup <- NULL - close_active_iterators <- NULL - - info <- machine_info(type, env = caller_env) - - # Generate the state machine lazily at runtime - if (is_null(state_machine)) { - state_machine <<- walk_states(body(fn), info = info) - } - - ops <- info$async_ops - if (!is_null(ops) && !is_installed(ops$package)) { - abort(sprintf("The %s package must be installed.", ops$package)) - } - - env <- new_generator_env(env, info) - user_env <- env$user_env - - # The compiler caches function bodies, so inline a weak reference to avoid - # leaks (#36). This weak reference is injected inside the body of the - # generator instance to work around a scoping issue. See where we install - # the user's exit handlers. - weak_env <- new_weakref(env) - - # Forward arguments inside the user space of the state machine - lapply(names(fmls), function(arg) env_bind_arg(user_env, arg, frame = generator_env)) - - # Flipped when `f` is pressed in the browser - undebugged <- FALSE - - # Called on cleanup to close all iterators active in - # ongoing `for` loops - close_active_iterators <- function() { - # The list is ordered from outermost to innermost for loops. Close them - # in reverse order, from most nested to least nested. - for (iter in rev(env$iterators)) { - if (!is_null(iter)) { - iter_close(iter) - } + factory <- new_function( + fmls, + quote({ + # Evaluate here so the formals of the generator factory do not + # mask our variables + `_private` <- rlang::env(`_parent`) + `_private`$generator_env <- base::environment() + `_private`$caller_env <- base::parent.frame() + + base::local(envir = `_private`, { + generator_env <- environment()$generator_env + caller_env <- environment()$caller_env + + # Prevent lints about unknown bindings + exits <- NULL + exited <- NULL + cleanup <- NULL + close_active_iterators <- NULL + + info <- machine_info(type, env = caller_env) + + # Generate the state machine lazily at runtime + if (is_null(state_machine)) { + state_machine <<- walk_states(body(fn), info = info) } - } - - env$close_active_iterators <- close_active_iterators - env$cleanup <- function() { - env$close_active_iterators() - - # Prevent user exit handlers from running again - env$exits <- NULL - } + ops <- info$async_ops + if (!is_null(ops) && !is_installed(ops$package)) { + abort(sprintf("The %s package must be installed.", ops$package)) + } + env <- new_generator_env(env, info) + user_env <- env$user_env - # Create the generator instance. This is a function that resumes - # a state machine. - instance <- inject(function(arg, close = FALSE) { - # Forward generator argument inside the state machine environment - delayedAssign("arg", arg, assign.env = env) - delayedAssign("close", close, assign.env = env) + # The compiler caches function bodies, so inline a weak reference to avoid + # leaks (#36). This weak reference is injected inside the body of the + # generator instance to work around a scoping issue. See where we install + # the user's exit handlers. + weak_env <- new_weakref(env) - if (!undebugged && (debugged || is_true(peek_option("coro_debug")))) { - env_browse(user_env) + # Forward arguments inside the user space of the state machine + lapply(names(fmls), function(arg) { + env_bind_arg(user_env, arg, frame = generator_env) + }) - defer({ - # `f` was pressed, disable debugging for this generator - if (!env_is_browsed(user_env)) { - undebugged <<- TRUE + # Flipped when `f` is pressed in the browser + undebugged <- FALSE + + # Called on cleanup to close all iterators active in + # ongoing `for` loops + close_active_iterators <- function() { + # The list is ordered from outermost to innermost for loops. Close them + # in reverse order, from most nested to least nested. + for (iter in rev(env$iterators)) { + if (!is_null(iter)) { + iter_close(iter) } - }) + } } - if (is_true(env$exhausted)) { - return(exhausted()) + env$close_active_iterators <- close_active_iterators + + env$cleanup <- function() { + env$close_active_iterators() + + # Prevent user exit handlers from running again + env$exits <- NULL } - if (close) { - # Prevent returning here as closing should be idempotent. We set - # ourselves as exhausted _before_ running any cleanup in case of - # failures. An exit handler shouldn't fail and it's expected that any - # failure prevents other handlers from running, including when an - # attempt is made at resuming the closed generator. - env$exhausted <- TRUE - - # First close active iterators. Should be first since they might be - # relying on resources set by the user. - close_active_iterators() - - # Now run the user's exit expressions. Achieved by running restoring - # user exits in the user environment and running an empty eval there. - # Unlike in the state machine path, where these expressions are meant - # to only run in case of unexpected exits, we don't disable them - # before exiting so they will actually run here. - evalq(envir = user_env, - base::evalq(envir = rlang::wref_key(!!weak_env), { - env_poke_exits(user_env, exits) + # Create the generator instance. This is a function that resumes + # a state machine. + instance <- inject(function(arg, close = FALSE) { + # Forward generator argument inside the state machine environment + delayedAssign("arg", arg, assign.env = env) + delayedAssign("close", close, assign.env = env) + + if (!undebugged && (debugged || is_true(peek_option("coro_debug")))) { + env_browse(user_env) + + defer({ + # `f` was pressed, disable debugging for this generator + if (!env_is_browsed(user_env)) { + undebugged <<- TRUE + } }) - ) + } - return(exhausted()) - } + if (is_true(env$exhausted)) { + return(exhausted()) + } - # Disable generator on error, interrupt, debugger quit, etc. - # There is no safe way of resuming a generator that didn't - # suspend normally. - if (is_true(env$jumped)) { - # In case a scheduler calls back the generator for error - # handling or cleanup - if (!missing(arg)) { - force(arg) + if (close) { + # Prevent returning here as closing should be idempotent. We set + # ourselves as exhausted _before_ running any cleanup in case of + # failures. An exit handler shouldn't fail and it's expected that any + # failure prevents other handlers from running, including when an + # attempt is made at resuming the closed generator. + env$exhausted <- TRUE + + # First close active iterators. Should be first since they might be + # relying on resources set by the user. + close_active_iterators() + + # Now run the user's exit expressions. Achieved by running restoring + # user exits in the user environment and running an empty eval there. + # Unlike in the state machine path, where these expressions are meant + # to only run in case of unexpected exits, we don't disable them + # before exiting so they will actually run here. + evalq( + envir = user_env, + base::evalq(envir = rlang::wref_key(!!weak_env), { + env_poke_exits(user_env, exits) + }) + ) + + return(exhausted()) + } + + # Disable generator on error, interrupt, debugger quit, etc. + # There is no safe way of resuming a generator that didn't + # suspend normally. + if (is_true(env$jumped)) { + # In case a scheduler calls back the generator for error + # handling or cleanup + if (!missing(arg)) { + force(arg) + } + abort( + "This function has been disabled because of an unexpected exit." + ) } - abort("This function has been disabled because of an unexpected exit.") - } - # Resume state machine. Set up an execution env in the user - # environment first to serve as a target for on.exit() - # expressions. Then evaluate state machine in its private - # environment. - env$jumped <- TRUE - env$exited <- TRUE - - out <- evalq(envir = user_env, { - base::evalq(envir = rlang::wref_key(!!weak_env), { - defer(if (exited) cleanup()) - env_poke_exits(user_env, exits) - !!state_machine + # Resume state machine. Set up an execution env in the user + # environment first to serve as a target for on.exit() + # expressions. Then evaluate state machine in its private + # environment. + env$jumped <- TRUE + env$exited <- TRUE + + out <- evalq(envir = user_env, { + base::evalq(envir = rlang::wref_key(!!weak_env), { + defer(if (exited) cleanup()) + env_poke_exits(user_env, exits) + !!state_machine + }) }) - }) - env$jumped <- FALSE + env$jumped <- FALSE - out - }) + out + }) - env$.self <- instance + env$.self <- instance - if (is_string(type, "async")) { - # Step into the generator right away - invisible(instance(NULL)) - } else { - structure(instance, class = "coro_generator_instance") - } + if (is_string(type, "async")) { + # Step into the generator right away + invisible(instance(NULL)) + } else { + structure(instance, class = "coro_generator_instance") + } + }) }) - })) + ) structure(factory, class = c(paste0("coro_", type), "function")) } @@ -324,7 +331,12 @@ new_generator_env <- function(parent, info) { env_bind_arg <- function(env, arg, frame = caller_env()) { if (identical(arg, "...")) { - env[["..."]] <- env_get(frame, "...", inherit = TRUE, default = missing_arg()) + env[["..."]] <- env_get( + frame, + "...", + inherit = TRUE, + default = missing_arg() + ) } else { env_bind_lazy(env, !!arg := !!sym(arg), .eval_env = frame) } @@ -415,18 +427,23 @@ yield <- function(x) { #' @export coro_debug <- function(fn, value = TRUE) { if (!is_generator_factory(fn)) { - abort("`fn` must be a `generator()`, `async()`, or `async_generator()` function.") + abort( + "`fn` must be a `generator()`, `async()`, or `async_generator()` function." + ) } env_poke(fn_env(fn), "debugged", value, create = FALSE) } is_generator_factory <- function(x) { - inherits_any(x, c( - "coro_generator", - "coro_async", - "coro_async_generator" - )) + inherits_any( + x, + c( + "coro_generator", + "coro_async", + "coro_async_generator" + ) + ) } with_try_catch <- function(handlers, expr) { diff --git a/R/iterator-adapt.R b/R/iterator-adapt.R index 6fc27f4..93d94a9 100644 --- a/R/iterator-adapt.R +++ b/R/iterator-adapt.R @@ -79,33 +79,36 @@ iter_builder <- function(result, input) { #' @rdname iter_adapt #' @name async_adapt #' @usage async_adapt(iter, steps) -on_load(async_adapt %<~% async_generator(function(iter, steps) { - force(iter) +on_load( + async_adapt %<~% + async_generator(function(iter, steps) { + force(iter) - reducer <- steps(iter_builder) + reducer <- steps(iter_builder) - # Initialise the adaptors - reducer() + # Initialise the adaptors + reducer() - flag <- "_coro_iter_adapt_result" + flag <- "_coro_iter_adapt_result" - while (TRUE) { - out <- await(iter()) + while (TRUE) { + out <- await(iter()) - if (is_exhausted(out)) { - # Finalise adaptors and signal exhaustion - reducer(NULL) - return(exhausted()) - } + if (is_exhausted(out)) { + # Finalise adaptors and signal exhaustion + reducer(NULL) + return(exhausted()) + } - last <- reducer(flag, out) + last <- reducer(flag, out) - # If we get `flag` back, it means a transducer has skipped this - # input. Continue until we get an actual result. - if (identical(last, flag)) { - next - } + # If we get `flag` back, it means a transducer has skipped this + # input. Continue until we get an actual result. + if (identical(last, flag)) { + next + } - yield(last) - } -})) + yield(last) + } + }) +) diff --git a/R/iterator.R b/R/iterator.R index 675221f..eccac5b 100644 --- a/R/iterator.R +++ b/R/iterator.R @@ -152,7 +152,6 @@ as_iterator.default <- function(x) { } - #' @export as_iterator.python.builtin.object <- function(x) { x <- reticulate::as_iterator(x) diff --git a/R/parser.R b/R/parser.R index cca876a..e47c704 100644 --- a/R/parser.R +++ b/R/parser.R @@ -16,7 +16,9 @@ walk_states <- function(expr, info) { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], !!!states) + repeat { + switch(state[[1L]], !!!states) + } exhausted <- TRUE invisible(exhausted()) @@ -40,16 +42,22 @@ walk_loop_states <- function(body, states, counter, info) { ) states <- node_list_poke_cdr(states, nested_states) - expr(repeat switch(state[[!!loop_depth]], !!!states)) + expr( + repeat { + switch(state[[!!loop_depth]], !!!states) + } + ) } -walk_branch_states <- function(body, - offset, - counter, - continue, - last, - return, - info, - new_machine = machine_call) { +walk_branch_states <- function( + body, + offset, + counter, + continue, + last, + return, + info, + new_machine = machine_call +) { nested_continue <- function(counter, last) { counter() + 1L } @@ -68,7 +76,13 @@ walk_branch_states <- function(body, info = info ) - breaking_state <- new_state(quote({ break }), NULL, nested_counter()) + breaking_state <- new_state( + quote({ + break + }), + NULL, + nested_counter() + ) states <- node_list_poke_cdr(states, breaking_state) nested_counter(inc = 1L) @@ -82,7 +96,9 @@ walk_branch_states <- function(body, } machine_call <- function(states, depth, prev_depth, next_i) { expr({ - repeat switch(state[[!!depth]], !!!states) + repeat { + switch(state[[!!depth]], !!!states) + } n <- length(state) if (n < !!prev_depth) { !!break_call() @@ -102,7 +118,8 @@ expr_states <- function(expr, counter, continue, last, return, info) { type <- expr_info$type assign <- expr_info$assign - switch(type, + switch( + type, `{` = block_states( block = expr, counter = counter, @@ -204,7 +221,9 @@ expr_states <- function(expr, counter, continue, last, return, info) { info = info, assign = assign ), - `withCallingHandlers` = stop_unimplemented("Support for `withCallingHandlers()`"), + `withCallingHandlers` = stop_unimplemented( + "Support for `withCallingHandlers()`" + ), stop_internal("expr_states", sprintf("Unexpected operation `%s`", type)) ) } @@ -253,7 +272,8 @@ expr_type_impl <- function(expr) { } head <- as_string(head) - switch(head, + switch( + head, `{` = , `yield` = , `await` = , @@ -274,7 +294,8 @@ expr_type_impl <- function(expr) { # expressions unless the argument is a potentially yielding control # flow expression with_handlers_type <- function(expr, fn_name) { - fn <- switch(fn_name, + fn <- switch( + fn_name, tryCatch = tryCatch, withCallingHandlers = withCallingHandlers, stop_internal("Unexpected state in `handler_type()`.") @@ -382,7 +403,8 @@ block_states <- function(block, counter, continue, last, return, info) { type <- expr_info$type assign <- expr_info$assign - switch(type, + switch( + type, # Collect as many user expressions as possible `expr` = { accum() @@ -519,7 +541,9 @@ block_states <- function(block, counter, continue, last, return, info) { )) next }, - `withCallingHandlers` = stop_unimplemented("Support for `withCallingHandlers()`") + `withCallingHandlers` = stop_unimplemented( + "Support for `withCallingHandlers()`" + ) ) stop_internal("block_states", sprintf("Unexpected operation `%s`", type)) @@ -592,13 +616,15 @@ continue_state <- function(expr, counter, continue, last, return, info) { state } -yield_state <- function(expr, - counter, - continue, - last, - return, - info, - assign_var = NULL) { +yield_state <- function( + expr, + counter, + continue, + last, + return, + info, + assign_var = NULL +) { if (is_string(info$type, "async")) { abort("Can't use `yield()` within an async function.") } @@ -618,13 +644,15 @@ yield_state <- function(expr, ) } -await_state <- function(expr, - counter, - continue, - last, - return, - info, - assign_var = NULL) { +await_state <- function( + expr, + counter, + continue, + last, + return, + info, + assign_var = NULL +) { if (is_string(info$type, "generator")) { stop_non_async_generator("await") } @@ -642,13 +670,15 @@ await_state <- function(expr, ) } -suspend_state <- function(expr, - counter, - continue, - last, - return, - info, - assign_var) { +suspend_state <- function( + expr, + counter, + continue, + last, + return, + info, + assign_var +) { assign <- !is_null(assign_var) return_last <- last && return && !assign @@ -696,7 +726,10 @@ suspend_state <- function(expr, # proper context. This is how generators can be cancelled and cleaned up. force_block <- expr({ .last_value <- !!arg_expr - !!continue_call(continue(counter, saved_last && !return_last), machine_depth(counter)) + !!continue_call( + continue(counter, saved_last && !return_last), + machine_depth(counter) + ) }) force_state <- new_state(force_block, NULL, counter()) node_list_poke_cdr(states, force_state) @@ -711,15 +744,17 @@ suspend_state <- function(expr, states } -if_states <- function(preamble, - condition, - then_body, - else_body, - counter, - continue, - last, - return, - info) { +if_states <- function( + preamble, + condition, + then_body, + else_body, + counter, + continue, + last, + return, + info +) { i <- counter() i_then <- i + 1L i_else <- i_then + 1L @@ -739,13 +774,29 @@ if_states <- function(preamble, counter(inc = 1L) offset <- if (is_null(else_body)) 0L else 1L - then_machine <- walk_branch_states(then_body, offset, counter, continue, last, return, info) + then_machine <- walk_branch_states( + then_body, + offset, + counter, + continue, + last, + return, + info + ) then_state <- new_state(then_machine, NULL, i_then) states <- node_list_poke_cdr(states, then_state) counter(inc = 1L) if (!is_null(else_body)) { - else_machine <- walk_branch_states(else_body, 0L, counter, continue, last, return, info) + else_machine <- walk_branch_states( + else_body, + 0L, + counter, + continue, + last, + return, + info + ) else_state <- new_state(else_machine, NULL, i_else) states <- node_list_poke_cdr(states, else_state) counter(inc = 1L) @@ -761,16 +812,18 @@ if_states <- function(preamble, states } -loop_states <- function(preamble, - init, - body, - cleanup, - counter, - nested_counter, - nested_states, - continue, - last, - info) { +loop_states <- function( + preamble, + init, + body, + cleanup, + counter, + nested_counter, + nested_states, + continue, + last, + info +) { states <- NULL i <- counter() next_i <- i + 1L @@ -789,7 +842,8 @@ loop_states <- function(preamble, next_i <- continue(counter, last) loop_depth <- depth + 1L - nested_counter <- nested_counter %||% new_counter(loop_depth, loop_depth = loop_depth) + nested_counter <- nested_counter %||% + new_counter(loop_depth, loop_depth = loop_depth) nested_machine_block <- expr({ !!walk_loop_states(body, nested_states, nested_counter, info = info) @@ -804,13 +858,15 @@ loop_states <- function(preamble, states } -while_states <- function(preamble, - condition, - body, - counter, - continue, - last, - info) { +while_states <- function( + preamble, + condition, + body, + counter, + continue, + last, + info +) { nested_counter <- new_loop_counter(counter) nested_states <- condition_state(condition, nested_counter) @@ -828,14 +884,16 @@ while_states <- function(preamble, ) } -for_states <- function(preamble, - var, - iterator, - body, - counter, - continue, - last, - info) { +for_states <- function( + preamble, + var, + iterator, + body, + counter, + continue, + last, + info +) { loop_depth <- machine_depth(counter) + 1L async <- is_call(iterator, "await_each", ns = c("", "coro")) @@ -857,7 +915,14 @@ for_states <- function(preamble, iterator <- iterators[[!!loop_depth]] iterator() }) - nested_states <- await_state(await_block, nested_counter, continue, FALSE, FALSE, info) + nested_states <- await_state( + await_block, + nested_counter, + continue, + FALSE, + FALSE, + info + ) condition <- expr({ if (is_exhausted(arg)) { @@ -967,14 +1032,16 @@ next_state <- function(preamble, counter, info) { state } -try_catch_states <- function(preamble, - expr, - counter, - continue, - last, - return, - info, - assign = FALSE) { +try_catch_states <- function( + preamble, + expr, + counter, + continue, + last, + return, + info, + assign = FALSE +) { if (assign) { var <- call_lhs(expr) expr <- call_rhs(expr) diff --git a/R/step-reduce.R b/R/step-reduce.R index 8ff4934..4f5b8c7 100644 --- a/R/step-reduce.R +++ b/R/step-reduce.R @@ -336,44 +336,50 @@ iter_reduce_impl <- function(.x, .f, ..., .init, .left = TRUE) { out } -on_load(async_reduce_steps %<~% async(function(x, steps, builder, init) { - builder <- as_closure(builder) +on_load( + async_reduce_steps %<~% + async(function(x, steps, builder, init) { + builder <- as_closure(builder) - if (is_null(steps)) { - reducer <- builder - } else { - reducer <- steps(builder) - } - stopifnot(is_closure(reducer)) + if (is_null(steps)) { + reducer <- builder + } else { + reducer <- steps(builder) + } + stopifnot(is_closure(reducer)) - if (missing(init)) { - identity <- reducer() - } else { - identity <- init - } + if (missing(init)) { + identity <- reducer() + } else { + identity <- init + } - result <- await(async_reduce(x, reducer)) + result <- await(async_reduce(x, reducer)) - reducer(result) -})) + reducer(result) + }) +) -on_load(async_reduce %<~% async(function(.x, .f, ...) { - out <- NULL +on_load( + async_reduce %<~% + async(function(.x, .f, ...) { + out <- NULL - while (TRUE) { - new <- await(.x()) + while (TRUE) { + new <- await(.x()) - if (is_exhausted(new)) { - break - } + if (is_exhausted(new)) { + break + } - out <- .f(out, new, ...) + out <- .f(out, new, ...) - # Return early if we get a reduced result - if (is_done_box(out)) { - return(unbox(out)) - } - } + # Return early if we get a reduced result + if (is_done_box(out)) { + return(unbox(out)) + } + } - out -})) + out + }) +) diff --git a/R/utils-vector.R b/R/utils-vector.R index 65325a3..daa0efd 100644 --- a/R/utils-vector.R +++ b/R/utils-vector.R @@ -11,7 +11,8 @@ as_vector_fn <- function(type) { if (!type %in% vec_types) { abort("`type` must be a vector type") } - switch(type, + switch( + type, logical = as.logical, integer = as.integer, double = as.double, @@ -32,7 +33,8 @@ new_vector_fn <- function(type) { if (!type %in% vec_types) { abort("`type` must be a vector type") } - switch(type, + switch( + type, logical = new_logical, integer = new_integer, double = new_double, diff --git a/air.toml b/air.toml new file mode 100644 index 0000000..e69de29 diff --git a/tests/testthat/_snaps/async.md b/tests/testthat/_snaps/async.md index 5a21a20..acc3f74 100644 --- a/tests/testthat/_snaps/async.md +++ b/tests/testthat/_snaps/async.md @@ -7,36 +7,13 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user("value") - exhausted <- TRUE - return(as_promise(last_value())) - }) - exhausted <- TRUE - invisible(exhausted()) - } - ---- - - Code - async_body(function() await("value")) - Output - { - if (exhausted) { - return(invisible(exhausted())) + repeat { + switch(state[[1L]], `1` = { + user("value") + exhausted <- TRUE + return(as_promise(last_value())) + }) } - repeat switch(state[[1L]], `1` = { - .last_value <- then(as_promise(user("value")), callback = .self) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(as_promise(last_value())) - }) exhausted <- TRUE invisible(exhausted()) } @@ -44,65 +21,26 @@ --- Code - async_body(function() if (1) await("value") else "else") + async_body(function() await("value")) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - if (user(1)) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { .last_value <- then(as_promise(user("value")), callback = .self) - state[[2L]] <- 2L + state[[1L]] <- 2L suspend() return(last_value()) }, `2` = { .last_value <- if (missing(arg)) exhausted() else arg - state[[2L]] <- 3L + state[[1L]] <- 3L }, `3` = { exhausted <- TRUE return(as_promise(last_value())) - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `3` = { - repeat switch(state[[2L]], `1` = { - user("else") - exhausted <- TRUE - return(as_promise(last_value())) - }, `2` = { - break }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `4` = { - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -110,58 +48,72 @@ --- Code - async_body(function() while (1) if (2) await("value")) + async_body(function() if (1) await("value") else "else") Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { if (user(1)) { - state[[2L]] <- 2L + state[[1L]] <- 2L } else { - break + state[[1L]] <- 3L } + state[[2L]] <- 1L }, `2` = { - if (user(2)) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L + repeat { + switch(state[[2L]], `1` = { + .last_value <- then(as_promise(user("value")), + callback = .self) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[2L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(as_promise(last_value())) + }, `4` = { + break + }) } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - .last_value <- then(as_promise(user("value")), - callback = .self) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { + n <- length(state) + if (n < 1L) { break - }) + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + break + }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user("else") + exhausted <- TRUE + return(as_promise(last_value())) + }, `2` = { + break + }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 1L + length(state) <- 1L + break }, `4` = { - state[[2L]] <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -169,34 +121,119 @@ --- Code - async_body(function() while (1) foo <- await("value")) + async_body(function() { + while (1) { + if (2) await("value") + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(1)) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - .last_value <- then(as_promise(user("value")), callback = .self) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - user_env[["foo"]] <- if (missing(arg)) NULL else arg + repeat { + switch(state[[2L]], `1` = { + if (user({ + 1 + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + if (user({ + 2 + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + .last_value <- then(as_promise(user("value")), + callback = .self) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break + }) + } + exhausted <- TRUE + invisible(exhausted()) + } + +--- + + Code + async_body(function() { + while (1) { + foo <- await("value") + } + }) + Output + { + if (exhausted) { + return(invisible(exhausted())) + } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + 1 + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + .last_value <- then(as_promise(user({ + "value" + })), callback = .self) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + user_env[["foo"]] <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -217,87 +254,93 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(s1)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - .last_value <- then(as_promise({ - iterator <- iterators[[2L]] - iterator() - }), callback = .self) - state[[2L]] <- 2L - suspend() - return(last_value()) + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(s1)) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - if ({ - if (is_exhausted(arg)) { - FALSE - } else { - user_env[["x"]] <- arg - TRUE - } - }) { - state[[2L]] <- 4L - } else { - break - } - }, `4` = { - user({ - values <<- c(values, x) - }) - iterators[[3L]] <- as_iterator(user(s2)) - state[[2L]] <- 5L - state[[3L]] <- 1L - }, `5` = { - repeat switch(state[[3L]], `1` = { - .last_value <- then(as_promise({ - iterator <- iterators[[3L]] - iterator() - }), callback = .self) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - if ({ - if (is_exhausted(arg)) { - FALSE + repeat { + switch(state[[2L]], `1` = { + .last_value <- then(as_promise({ + iterator <- iterators[[2L]] + iterator() + }), callback = .self) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + if ({ + if (is_exhausted(arg)) { + FALSE + } else { + user_env[["x"]] <- arg + TRUE + } + }) { + state[[2L]] <- 4L } else { - user_env[["y"]] <- arg - TRUE + break } - }) { - state[[3L]] <- 4L - } else { - break - } - }, `4` = { - user({ - values <<- c(values, y) + }, `4` = { + user({ + values <<- c(values, x) + }) + iterators[[3L]] <- as_iterator(user(s2)) + state[[2L]] <- 5L + state[[3L]] <- 1L + }, `5` = { + repeat { + switch(state[[3L]], `1` = { + .last_value <- then(as_promise({ + iterator <- iterators[[3L]] + iterator() + }), callback = .self) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + if ({ + if (is_exhausted(arg)) { + FALSE + } else { + user_env[["y"]] <- arg + TRUE + } + }) { + state[[3L]] <- 4L + } else { + break + } + }, `4` = { + user({ + values <<- c(values, y) + }) + state[[3L]] <- 1L + }) + } + { + iter_close(iterators[[3L]]) + iterators[[3L]] <- NULL + } + length(state) <- 2L + state[[2L]] <- 1L }) - state[[3L]] <- 1L - }) + } { - iter_close(iterators[[3L]]) - iterators[[3L]] <- NULL + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL } - length(state) <- 2L - state[[2L]] <- 1L + length(state) <- 1L + break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -322,18 +365,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - .last_value <- then(as_promise(user(NULL)), callback = .self) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(as_promise(last_value())) - }) + repeat { + switch(state[[1L]], `1` = { + .last_value <- then(as_promise(user(NULL)), callback = .self) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(as_promise(last_value())) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -344,7 +389,10 @@ print(factory, reproducible = TRUE) Output - function() { await(NULL); yield(NULL) } + function() { + await(NULL) + yield(NULL) + } --- @@ -352,36 +400,41 @@ print(factory, internals = TRUE, reproducible = TRUE) Output - function() { await(NULL); yield(NULL) } + function() { + await(NULL) + yield(NULL) + } State machine: { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - .last_value <- then(as_promise(user({ - NULL - })), callback = .self) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - .last_value <- as_promise(user({ - NULL - })) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 5L - }, `5` = { - exhausted <- TRUE - return(as_promise(last_value())) - }) + repeat { + switch(state[[1L]], `1` = { + .last_value <- then(as_promise(user({ + NULL + })), callback = .self) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + .last_value <- as_promise(user({ + NULL + })) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 5L + }, `5` = { + exhausted <- TRUE + return(as_promise(last_value())) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -392,7 +445,10 @@ print(instance, reproducible = TRUE) Output - function() { await(NULL); yield(NULL) } + function() { + await(NULL) + yield(NULL) + } --- @@ -400,36 +456,41 @@ print(instance, internals = TRUE, reproducible = TRUE) Output - function() { await(NULL); yield(NULL) } + function() { + await(NULL) + yield(NULL) + } State machine: { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - .last_value <- then(as_promise(user({ - NULL - })), callback = .self) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - .last_value <- as_promise(user({ - NULL - })) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 5L - }, `5` = { - exhausted <- TRUE - return(as_promise(last_value())) - }) + repeat { + switch(state[[1L]], `1` = { + .last_value <- then(as_promise(user({ + NULL + })), callback = .self) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + .last_value <- as_promise(user({ + NULL + })) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 5L + }, `5` = { + exhausted <- TRUE + return(as_promise(last_value())) + }) + } exhausted <- TRUE invisible(exhausted()) } diff --git a/tests/testthat/_snaps/generator.md b/tests/testthat/_snaps/generator.md index 3907a5f..480afc0 100644 --- a/tests/testthat/_snaps/generator.md +++ b/tests/testthat/_snaps/generator.md @@ -18,18 +18,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user(NULL) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user(NULL) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -54,18 +56,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user(NULL) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user(NULL) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } diff --git a/tests/testthat/_snaps/parser-block.md b/tests/testthat/_snaps/parser-block.md index 691c5ce..bc35dd8 100644 --- a/tests/testthat/_snaps/parser-block.md +++ b/tests/testthat/_snaps/parser-block.md @@ -9,20 +9,22 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - 1L + repeat { + switch(state[[1L]], `1` = { + user({ + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -42,26 +44,28 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before1" - "before2" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after1" - "after2" + repeat { + switch(state[[1L]], `1` = { + user({ + "before1" + "before2" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after1" + "after2" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -78,23 +82,25 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -114,35 +120,37 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "during" - 2L - }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 5L - }, `5` = { - user({ - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "during" + 2L + }) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 5L + }, `5` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -161,34 +169,36 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - 2L - }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 5L - }, `5` = { - user({ - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + 2L + }) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 5L + }, `5` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -206,24 +216,26 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - user_env[["value"]] <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + user_env[["value"]] <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -239,20 +251,22 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - 1L + repeat { + switch(state[[1L]], `1` = { + user({ + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -269,30 +283,32 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - 2L + repeat { + switch(state[[1L]], `1` = { + user({ + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + 2L + }) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 5L + }, `5` = { + exhausted <- TRUE + return(exhausted()) }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 5L - }, `5` = { - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -316,28 +332,30 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before1" - "before2" - "before-inner" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after-inner" - "after1" - "after2" + repeat { + switch(state[[1L]], `1` = { + user({ + "before1" + "before2" + "before-inner" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after-inner" + "after1" + "after2" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -359,26 +377,28 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before-inner" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after-inner" - "after1" - "after2" + repeat { + switch(state[[1L]], `1` = { + user({ + "before-inner" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after-inner" + "after1" + "after2" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -399,25 +419,27 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before-inner" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after1" - "after2" + repeat { + switch(state[[1L]], `1` = { + user({ + "before-inner" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after1" + "after2" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -443,46 +465,48 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "before-inner" - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - 2L - }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 5L - }, `5` = { - user({ - 3L - }) - state[[1L]] <- 6L - suspend() - return(last_value()) - }, `6` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 7L - }, `7` = { - user({ - "after-inner" - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + "before-inner" + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + 2L + }) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 5L + }, `5` = { + user({ + 3L + }) + state[[1L]] <- 6L + suspend() + return(last_value()) + }, `6` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 7L + }, `7` = { + user({ + "after-inner" + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -504,24 +528,26 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after-inner-inner" - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after-inner-inner" + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -543,24 +569,26 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - 1L - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "after-inner" - "after" + repeat { + switch(state[[1L]], `1` = { + user({ + 1L + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "after-inner" + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -568,34 +596,46 @@ # yield assignment in a loop Code - generator_body(function() while (1) var <- yield("value")) + generator_body(function() { + while (1) { + var <- yield("value") + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(1)) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user("value") - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - user_env[["var"]] <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + 1 + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "value" + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + user_env[["var"]] <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } diff --git a/tests/testthat/_snaps/parser-if.md b/tests/testthat/_snaps/parser-if.md index eecbf3c..131aff7 100644 --- a/tests/testthat/_snaps/parser-if.md +++ b/tests/testthat/_snaps/parser-if.md @@ -17,74 +17,80 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "if-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "if-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - user({ - "if-after" - }) - state[[2L]] <- 4L + repeat { + switch(state[[2L]], `1` = { + user({ + FALSE + }) + state[[2L]] <- 2L + }, `2` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { user({ - FALSE + "after" }) - state[[2L]] <- 2L - }, `2` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -108,74 +114,80 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - FALSE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user({ - FALSE - }) - state[[2L]] <- 2L - }, `2` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "else-before" - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + FALSE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + FALSE + }) + state[[2L]] <- 2L + }, `2` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "else-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "else-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L + }, `4` = { user({ - "else-after" + "after" }) - state[[2L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -203,76 +215,82 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" - "inner-before" - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "if-before" + "inner-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "inner-after" + "if-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - user({ - "inner-after" - "if-after" - }) - state[[2L]] <- 4L + repeat { + switch(state[[2L]], `1` = { + user({ + FALSE + }) + state[[2L]] <- 2L + }, `2` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { user({ - FALSE + "after" }) - state[[2L]] <- 2L - }, `2` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -284,7 +302,9 @@ "before" if (TRUE) { "if-before" - if (FALSE) yield(1L) + if (FALSE) { + yield(1L) + } "if-after" } else { "foo" @@ -295,95 +315,105 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" + "before" }) if (user({ - FALSE + TRUE })) { - state[[2L]] <- 2L + state[[1L]] <- 2L } else { - state[[2L]] <- 3L + state[[1L]] <- 3L } - state[[3L]] <- 1L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) + repeat { + switch(state[[2L]], `1` = { + user({ + "if-before" + }) + if (user({ + FALSE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + 1L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + "if-after" + }) + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { - user({ - "if-after" - }) - exhausted <- TRUE - return(exhausted()) - }, `4` = { + length(state) <- 1L break - }) - n <- length(state) - if (n < 1L) { + }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "foo" + }) + exhausted <- TRUE + return(exhausted()) + }, `2` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - "foo" - }) - exhausted <- TRUE - return(exhausted()) - }, `2` = { + }, `4` = { break }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `4` = { - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -405,94 +435,102 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" + "before" }) if (user({ - FALSE + TRUE })) { - state[[2L]] <- 2L + state[[1L]] <- 2L } else { - state[[2L]] <- 3L + state[[1L]] <- 3L } - state[[3L]] <- 1L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[3L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }, `4` = { - break - }) + repeat { + switch(state[[2L]], `1` = { + user({ + "if-before" + }) + if (user({ + FALSE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user(1L) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[3L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + state[[2L]] <- 4L + }, `4` = { + break + }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { - state[[2L]] <- 4L - }, `4` = { + length(state) <- 1L break - }) - n <- length(state) - if (n < 1L) { + }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "foo" + }) + exhausted <- TRUE + return(exhausted()) + }, `2` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - "foo" - }) - exhausted <- TRUE - return(exhausted()) - }, `2` = { + }, `4` = { break }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `4` = { - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -520,127 +558,137 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" + "before" }) if (user({ - FALSE + TRUE })) { - state[[2L]] <- 2L + state[[1L]] <- 2L } else { - state[[2L]] <- 3L + state[[1L]] <- 3L } - state[[3L]] <- 1L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - if (user({ - FALSE - })) { - state[[3L]] <- 2L - } else { - state[[3L]] <- 3L - } - state[[4L]] <- 1L - }, `2` = { - repeat switch(state[[4L]], `1` = { + repeat { + switch(state[[2L]], `1` = { user({ - 1L + "if-before" }) - state[[4L]] <- 2L - suspend() - return(last_value()) + if (user({ + FALSE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[4L]] <- 3L + repeat { + switch(state[[3L]], `1` = { + if (user({ + FALSE + })) { + state[[3L]] <- 2L + } else { + state[[3L]] <- 3L + } + state[[4L]] <- 1L + }, `2` = { + repeat { + switch(state[[4L]], `1` = { + user({ + 1L + }) + state[[4L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[4L]] <- 3L + }, `3` = { + user({ + "if-3-after" + }) + state[[4L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 3L + }, `3` = { + user({ + "if-2-after" + }) + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L }, `3` = { - user({ - "if-3-after" - }) - state[[4L]] <- 4L + state[[2L]] <- 4L }, `4` = { break }) - n <- length(state) - if (n < 3L) { + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + break + }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + FALSE + }) + exhausted <- TRUE + return(exhausted()) + }, `2` = { break - } - if (n == 3L) { - state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 3L - }, `3` = { - user({ - "if-2-after" }) - exhausted <- TRUE - return(exhausted()) - }, `4` = { - break - }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { - state[[2L]] <- 4L - }, `4` = { + length(state) <- 1L break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - FALSE - }) - exhausted <- TRUE - return(exhausted()) - }, `2` = { + }, `4` = { break }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `4` = { - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -665,83 +713,89 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - user({ - "if-after" - }) - exhausted <- TRUE - return(exhausted()) - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { + repeat { + switch(state[[2L]], `1` = { + user({ + "if-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "if-after" + }) + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - "else-before" - 2L - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L }, `3` = { - user({ - "else-after" - }) - exhausted <- TRUE - return(exhausted()) + repeat { + switch(state[[2L]], `1` = { + user({ + "else-before" + 2L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "else-after" + }) + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + break }, `4` = { break }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `4` = { - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -767,85 +821,91 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - user({ - "if-after" - }) - state[[2L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - "else-before" - 2L - }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "if-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "if-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "else-before" + 2L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "else-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L + }, `4` = { user({ - "else-after" + "after" }) - state[[2L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -867,73 +927,79 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[2L]], `1` = { + user({ + 2L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L + }, `4` = { user({ - 2L + "after" }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -956,78 +1022,84 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - 1L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "if-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - user({ - "if-after" - }) - state[[2L]] <- 4L + repeat { + switch(state[[2L]], `1` = { + user({ + 2L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { user({ - 2L + "after" }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1050,78 +1122,84 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user({ - 1L - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - 2L + "before" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + 2L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "else-after" + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L + }, `4` = { user({ - "else-after" + "after" }) - state[[2L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1143,74 +1221,80 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { if (user({ TRUE })) { - state[[2L]] <- 2L + state[[1L]] <- 2L } else { - state[[2L]] <- 3L + state[[1L]] <- 3L } - state[[3L]] <- 1L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user({ - 1L - }) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - user({ - "if-3-after" + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + 1L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + user({ + "if-3-after" + }) + state[[3L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + break }) - state[[3L]] <- 4L - }, `4` = { - break - }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 3L + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1245,193 +1329,209 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - if (user({ - TRUE - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "if-before" + "before" }) if (user({ TRUE })) { - state[[2L]] <- 2L + state[[1L]] <- 2L } else { - state[[2L]] <- 3L + state[[1L]] <- 3L } - state[[3L]] <- 1L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - if (user({ - TRUE - })) { - state[[3L]] <- 2L - } else { - state[[3L]] <- 3L - } - state[[4L]] <- 1L - }, `2` = { - repeat switch(state[[4L]], `1` = { + repeat { + switch(state[[2L]], `1` = { user({ - 1L + "if-before" }) - state[[4L]] <- 2L - suspend() - return(last_value()) + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[4L]] <- 3L + repeat { + switch(state[[3L]], `1` = { + if (user({ + TRUE + })) { + state[[3L]] <- 2L + } else { + state[[3L]] <- 3L + } + state[[4L]] <- 1L + }, `2` = { + repeat { + switch(state[[4L]], `1` = { + user({ + 1L + }) + state[[4L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[4L]] <- 3L + }, `3` = { + user({ + "if-3-after" + }) + state[[4L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 3L + }, `3` = { + user({ + "if-2-after" + }) + state[[3L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 4L }, `3` = { - user({ - "if-3-after" - }) - state[[4L]] <- 4L + repeat { + switch(state[[3L]], `1` = { + if (user({ + FALSE + })) { + state[[3L]] <- 2L + } else { + state[[3L]] <- 3L + } + state[[4L]] <- 1L + }, `2` = { + repeat { + switch(state[[4L]], `1` = { + user({ + FALSE + }) + state[[4L]] <- 2L + }, `2` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 4L + }, `3` = { + repeat { + switch(state[[4L]], `1` = { + user({ + 2L + }) + state[[4L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[4L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 4L }, `4` = { break }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { - state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 3L - }, `3` = { - user({ - "if-2-after" - }) - state[[3L]] <- 4L - }, `4` = { - break - }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 4L + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - repeat switch(state[[3L]], `1` = { - if (user({ - FALSE - })) { - state[[3L]] <- 2L - } else { - state[[3L]] <- 3L - } - state[[4L]] <- 1L - }, `2` = { - repeat switch(state[[4L]], `1` = { + repeat { + switch(state[[2L]], `1` = { user({ FALSE }) - state[[4L]] <- 2L - }, `2` = { - break - }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { - state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 4L - }, `3` = { - repeat switch(state[[4L]], `1` = { - user({ - 2L - }) - state[[4L]] <- 2L - suspend() - return(last_value()) + state[[2L]] <- 2L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[4L]] <- 3L - }, `3` = { break }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { - state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 4L - }, `4` = { - break - }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 4L + length(state) <- 1L + state[[1L]] <- 4L }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { user({ - FALSE + "after" }) - state[[2L]] <- 2L - }, `2` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } diff --git a/tests/testthat/_snaps/parser-loop.md b/tests/testthat/_snaps/parser-loop.md index 0f0add7..1b5bedd 100644 --- a/tests/testthat/_snaps/parser-loop.md +++ b/tests/testthat/_snaps/parser-loop.md @@ -15,40 +15,44 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-before" - 1L + "before" + "repeat" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "loop-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "loop-after" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { user({ - "loop-after" + "after" }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -58,7 +62,9 @@ Code generator_body(function() { "before" - repeat yield(1L) + repeat { + yield(1L) + } "after" }) Output @@ -66,32 +72,38 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user(1L) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + "repeat" + }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" - }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -113,34 +125,38 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - 1L + "before" + "repeat" }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" - }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -152,7 +168,9 @@ "before" repeat { "loop-before" - if (TRUE) yield(1L) + if (TRUE) { + yield(1L) + } "loop-after" } "after" @@ -162,63 +180,71 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-before" + "before" + "repeat" }) - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next + repeat { + switch(state[[2L]], `1` = { + user({ + "loop-before" + }) + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + 1L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + "loop-after" + }) + state[[2L]] <- 1L + }) } - length(state) <- 2L - state[[2L]] <- 3L + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { user({ - "loop-after" + "after" }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -230,7 +256,9 @@ "before" repeat { "loop-before" - repeat yield(1L) + repeat { + yield(1L) + } "loop-after" } "after" @@ -240,48 +268,56 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-before" + "before" "repeat" }) - state[[2L]] <- 2L - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L - }) - length(state) <- 2L - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "loop-before" + "repeat" + }) + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + 1L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + "loop-after" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { user({ - "loop-after" + "after" }) - state[[2L]] <- 1L + exhausted <- TRUE + return(exhausted()) }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" - }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -291,7 +327,9 @@ Code generator_body(function() { "before" - repeat NULL + repeat { + NULL + } yield(1L) "after" }) @@ -300,37 +338,43 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user(NULL) + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + "repeat" + }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + NULL + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { + user({ + 1L + }) + state[[1L]] <- 4L + suspend() + return(last_value()) + }, `4` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 5L + }, `5` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - 1L - }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 5L - }, `5` = { - user({ - "after" - }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -340,7 +384,9 @@ Code generator_body(function() { "before" - repeat if (TRUE) break else next + repeat { + if (TRUE) break else next + } yield(1L) "after" }) @@ -349,77 +395,87 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(TRUE)) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - length(state) <- 1L - break - }, `2` = { - break + repeat { + switch(state[[1L]], `1` = { + user({ + "before" + "repeat" }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + length(state) <- 2L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - repeat switch(state[[3L]], `1` = { - length(state) <- 2L - break - }, `2` = { - break + user({ + 1L }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 1L + state[[1L]] <- 4L + suspend() + return(last_value()) }, `4` = { - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - 1L - }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 5L - }, `5` = { - user({ - "after" + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 5L + }, `5` = { + user({ + "after" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -438,32 +494,36 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "next" + "repeat" }) + state[[1L]] <- 2L state[[2L]] <- 1L }, `2` = { - user({ - 1L - }) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 1L + repeat { + switch(state[[2L]], `1` = { + user({ + "next" + }) + state[[2L]] <- 1L + }, `2` = { + user({ + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -487,50 +547,54 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user({ - "loop-before" - 1L - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - user({ - "loop-after" - "next" - }) - state[[2L]] <- 1L - }, `4` = { + repeat { + switch(state[[1L]], `1` = { user({ - "next-after" - 2L - }) - state[[2L]] <- 5L - suspend() - return(last_value()) - }, `5` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 6L - }, `6` = { - user({ - "loop-final" + "repeat" }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "loop-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "loop-after" + "next" + }) + state[[2L]] <- 1L + }, `4` = { + user({ + "next-after" + 2L + }) + state[[2L]] <- 5L + suspend() + return(last_value()) + }, `5` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 6L + }, `6` = { + user({ + "loop-final" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -549,32 +613,36 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "break" - }) - break - }, `2` = { - user({ - 1L + "repeat" }) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "break" + }) + break + }, `2` = { + user({ + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -585,7 +653,11 @@ generator_body(function() { repeat { "loop-after" - if (TRUE) break else next + if (TRUE) { + break + } else { + next + } "next-after" } }) @@ -594,68 +666,82 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-after" + "repeat" }) - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 4L - }, `3` = { - repeat switch(state[[3L]], `1` = { - length(state) <- 2L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next + repeat { + switch(state[[2L]], `1` = { + user({ + "loop-after" + }) + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 4L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "next" + }) + length(state) <- 2L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 4L + }, `4` = { + user({ + "next-after" + }) + state[[2L]] <- 1L + }) } - length(state) <- 2L - state[[2L]] <- 4L - }, `4` = { - user({ - "next-after" - }) - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -681,56 +767,60 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-before" - 1L + "repeat" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - user({ - "loop-after" - "break" - }) + repeat { + switch(state[[2L]], `1` = { + user({ + "loop-before" + 1L + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "loop-after" + "break" + }) + break + }, `4` = { + user({ + "break-after" + "next" + }) + state[[2L]] <- 1L + }, `5` = { + user({ + "next-after" + 2L + }) + state[[2L]] <- 6L + suspend() + return(last_value()) + }, `6` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 7L + }, `7` = { + user({ + "loop-final" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L break - }, `4` = { - user({ - "break-after" - "next" - }) - state[[2L]] <- 1L - }, `5` = { - user({ - "next-after" - 2L - }) - state[[2L]] <- 6L - suspend() - return(last_value()) - }, `6` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 7L - }, `7` = { - user({ - "loop-final" - }) - state[[2L]] <- 1L }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -739,55 +829,65 @@ Code generator_body(function() { - repeat if (TRUE) yield() + repeat { + if (TRUE) yield() + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(TRUE)) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - user(NULL) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 1L - }, `3` = { + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user(NULL) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `3` = { + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -796,72 +896,84 @@ Code generator_body(function() { - repeat if (TRUE) yield(1L) else FALSE + repeat { + if (TRUE) yield(1L) else FALSE + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(TRUE)) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L + state[[1L]] <- 2L state[[2L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user(FALSE) - state[[3L]] <- 2L - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user(1L) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user(FALSE) + state[[3L]] <- 2L + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + state[[2L]] <- 1L + }) } - length(state) <- 2L - state[[2L]] <- 1L - }, `4` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -870,37 +982,45 @@ Code generator_body(function() { - while (TRUE) yield(1L) + while (TRUE) { + yield(1L) + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user(1L) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -918,55 +1038,61 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - if (user({ - FALSE - })) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + if (user({ + FALSE + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user(1L) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + state[[2L]] <- 1L + }) } - length(state) <- 2L - state[[2L]] <- 1L - }, `4` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -987,62 +1113,68 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - if (user({ - FALSE - })) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user({ - 1L - }) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - user({ - "after-pause" + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + if (user({ + FALSE + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user({ + 1L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + user({ + "after-pause" + }) + state[[3L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + state[[2L]] <- 1L }) - state[[3L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next } - length(state) <- 2L - state[[2L]] <- 1L - }, `4` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1063,41 +1195,45 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user({ - "loop-before" - 1L - }) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 4L - }, `4` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-after" + "before" }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "loop-before" + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 4L + }, `4` = { + user({ + "loop-after" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1117,50 +1253,54 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 4L + }, `4` = { + user({ + "loop-after" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { user({ - 1L + 2L }) - state[[2L]] <- 3L + state[[1L]] <- 4L suspend() return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 4L }, `4` = { - user({ - "loop-after" - }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - 2L + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 5L + }, `5` = { + exhausted <- TRUE + return(exhausted()) }) - state[[1L]] <- 4L - suspend() - return(last_value()) - }, `4` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 5L - }, `5` = { - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1170,7 +1310,9 @@ Code generator_body(function() { "before" - while (TRUE) break + while (TRUE) { + break + } while (TRUE) { "loop-before" yield(1L) @@ -1195,138 +1337,151 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - break - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - state[[1L]] <- 4L - state[[2L]] <- 1L - }, `4` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user({ - "loop-before" - 1L - }) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 4L - }, `4` = { + repeat { + switch(state[[1L]], `1` = { user({ - "loop-after" + "before" }) - if (user({ - TRUE - })) { - state[[2L]] <- 5L - } else { - state[[2L]] <- 6L - } - state[[3L]] <- 1L - }, `5` = { - repeat switch(state[[3L]], `1` = { - user({ - "break-before" - "break" - }) - length(state) <- 1L - break - }, `2` = { - user({ - "break-after" + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "break" + }) + break }) - state[[3L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 2L) { - break } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 7L - }, `6` = { - repeat switch(state[[3L]], `1` = { - user({ - "yield-2-before" - 2L - }) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - user({ - "yield-2-after" + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { + state[[1L]] <- 4L + state[[2L]] <- 1L + }, `4` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "loop-before" + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 4L + }, `4` = { + user({ + "loop-after" + }) + if (user({ + TRUE + })) { + state[[2L]] <- 5L + } else { + state[[2L]] <- 6L + } + state[[3L]] <- 1L + }, `5` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break-before" + "break" + }) + length(state) <- 1L + break + }, `2` = { + user({ + "break-after" + }) + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 7L + }, `6` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "yield-2-before" + 2L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + user({ + "yield-2-after" + }) + state[[3L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 7L + }, `7` = { + user({ + "next-before" + "next" + }) + state[[2L]] <- 1L + }, `8` = { + user({ + "loop-end" + }) + state[[2L]] <- 1L }) - state[[3L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 2L) { - break } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 7L - }, `7` = { - user({ - "next-before" - "next" - }) - state[[2L]] <- 1L - }, `8` = { + length(state) <- 1L + state[[1L]] <- 5L + }, `5` = { user({ - "loop-end" + "after" }) - state[[2L]] <- 1L + exhausted <- TRUE + return(exhausted()) }) - length(state) <- 1L - state[[1L]] <- 5L - }, `5` = { - user({ - "after" - }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1345,28 +1500,32 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - user({ - "before-break" - "break" - }) + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "before-break" + "break" + }) + break + }) + } + length(state) <- 1L break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1375,42 +1534,51 @@ Code generator_body(function() { - for (i in x) break + for (i in x) { + break + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(x)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["i"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(x)) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["i"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "break" + }) + break + }) + } + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL + } + length(state) <- 1L break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1419,48 +1587,56 @@ Code generator_body(function() { - for (i in x) yield(1L) + for (i in x) { + yield(1L) + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(x)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["i"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user(1L) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(x)) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["i"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL + } + length(state) <- 1L + break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1482,58 +1658,62 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - iterators[[2L]] <- as_iterator(user(x)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["i"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { + repeat { + switch(state[[1L]], `1` = { user({ - "for-before" - 1L + "before" }) - state[[2L]] <- 3L - suspend() - return(last_value()) + iterators[[2L]] <- as_iterator(user(x)) + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["i"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "for-before" + 1L + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 4L + }, `4` = { + user({ + "for-after" + }) + state[[2L]] <- 1L + }) + } + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 4L - }, `4` = { user({ - "for-after" + "after" }) - state[[2L]] <- 1L + exhausted <- TRUE + return(exhausted()) }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" - }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1544,7 +1724,11 @@ generator_body(function() { for (i in x) { "for-before" - if (TRUE) yield(1L) else break + if (TRUE) { + yield(1L) + } else { + break + } "if-after" next "for-after" @@ -1555,95 +1739,108 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(x)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["i"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(x)) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - user({ - "for-before" - }) - if (user({ - TRUE - })) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user(1L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 5L - }, `4` = { - repeat switch(state[[3L]], `1` = { - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["i"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "for-before" + }) + if (user({ + TRUE + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user({ + 1L + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 5L + }, `4` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 5L + }, `5` = { + user({ + "if-after" + "next" + }) + state[[2L]] <- 1L + }, `6` = { + user({ + "for-after" + }) + state[[2L]] <- 1L + }) } - if (n == 2L) { - state[[2L]] <- 1L - next + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL } - length(state) <- 2L - state[[2L]] <- 5L - }, `5` = { - user({ - "if-after" - "next" - }) - state[[2L]] <- 1L - }, `6` = { - user({ - "for-after" - }) - state[[2L]] <- 1L + length(state) <- 1L + break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1652,78 +1849,90 @@ Code generator_body(function() { - while (TRUE) if (TRUE) return(1L) else yield(2L) + while (TRUE) { + if (TRUE) return(1L) else yield(2L) + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - if (user(TRUE)) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user(1L) - exhausted <- TRUE - return(exhausted()) - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L state[[2L]] <- 1L - }, `4` = { - repeat switch(state[[3L]], `1` = { - user(2L) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + if (user({ + TRUE + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user(1L) + exhausted <- TRUE + return(exhausted()) + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + repeat { + switch(state[[3L]], `1` = { + user(2L) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `5` = { + state[[2L]] <- 1L + }) } - length(state) <- 2L - state[[2L]] <- 1L - }, `5` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1757,125 +1966,135 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user({ - "while before if" - }) - if (user({ - i > 3 - })) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user({ - "while-if before break" - "break" - }) - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 4L - }, `4` = { + repeat { + switch(state[[1L]], `1` = { user({ - "while after if" + "before" }) - state[[2L]] <- 5L - state[[3L]] <- 1L - }, `5` = { - repeat switch(state[[3L]], `1` = { - if (user({ - TRUE - })) { - state[[3L]] <- 2L - } else { - break - } - }, `2` = { - user({ - "while-while before if" - }) - if (user({ - j > 3 - })) { - state[[3L]] <- 3L - } else { - state[[3L]] <- 4L - } - state[[4L]] <- 1L - }, `3` = { - repeat switch(state[[4L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { user({ - "while-while-if before break" - "break" + "while before if" }) + if (user({ + i > 3 + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "while-if before break" + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } length(state) <- 2L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { + state[[2L]] <- 4L + }, `4` = { + user({ + "while after if" + }) + state[[2L]] <- 5L state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 4L - }, `4` = { - user({ - "while-while after if" + }, `5` = { + repeat { + switch(state[[3L]], `1` = { + if (user({ + TRUE + })) { + state[[3L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "while-while before if" + }) + if (user({ + j > 3 + })) { + state[[3L]] <- 3L + } else { + state[[3L]] <- 4L + } + state[[4L]] <- 1L + }, `3` = { + repeat { + switch(state[[4L]], `1` = { + user({ + "while-while-if before break" + "break" + }) + length(state) <- 2L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 4L + }, `4` = { + user({ + "while-while after if" + }) + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 6L + }, `6` = { + user({ + "while after while" + }) + state[[2L]] <- 1L }) - state[[3L]] <- 1L - }) - length(state) <- 2L - state[[2L]] <- 6L - }, `6` = { + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { user({ - "while after while" + "after" }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1908,120 +2127,130 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "before" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user({ - "while before if" - }) - if (user({ - i > 3 - })) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - user({ - "while-if before break" - "break" - }) - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 4L - }, `4` = { + repeat { + switch(state[[1L]], `1` = { user({ - "while after if" + "before" }) - state[[2L]] <- 5L - state[[3L]] <- 1L - }, `5` = { - repeat switch(state[[3L]], `1` = { - if (user({ - TRUE - })) { - state[[3L]] <- 2L - } else { - break - } - }, `2` = { - user({ - "while-while before if" - }) - if (user({ - j > 3 - })) { - state[[3L]] <- 3L - } else { - state[[3L]] <- 4L - } - state[[4L]] <- 1L - }, `3` = { - repeat switch(state[[4L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { user({ - "while-while-if before break" - "break" + "while before if" }) + if (user({ + i > 3 + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "while-if before break" + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } length(state) <- 2L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { + state[[2L]] <- 4L + }, `4` = { + user({ + "while after if" + }) + state[[2L]] <- 5L state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 4L - }, `4` = { - user({ - "while-while after if" + }, `5` = { + repeat { + switch(state[[3L]], `1` = { + if (user({ + TRUE + })) { + state[[3L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "while-while before if" + }) + if (user({ + j > 3 + })) { + state[[3L]] <- 3L + } else { + state[[3L]] <- 4L + } + state[[4L]] <- 1L + }, `3` = { + repeat { + switch(state[[4L]], `1` = { + user({ + "while-while-if before break" + "break" + }) + length(state) <- 2L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 4L + }, `4` = { + user({ + "while-while after if" + }) + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 1L }) - state[[3L]] <- 1L + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { + user({ + "after" }) - length(state) <- 2L - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - "after" + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2042,52 +2271,58 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - 1 - })) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - state[[2L]] <- 3L - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - if (user({ - 2 - })) { - state[[3L]] <- 2L - } else { - break - } - }, `2` = { - user({ - 1 - }) - state[[3L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 4L - }, `4` = { - user({ - "break" + repeat { + switch(state[[2L]], `1` = { + if (user({ + 1 + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + state[[2L]] <- 3L + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + if (user({ + 2 + })) { + state[[3L]] <- 2L + } else { + break + } + }, `2` = { + user({ + 1 + }) + state[[3L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 4L + }, `4` = { + user({ + "break" + }) + break + }) + } + length(state) <- 2L + state[[2L]] <- 1L }) - break - }) - length(state) <- 2L - state[[2L]] <- 1L + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } diff --git a/tests/testthat/_snaps/parser.md b/tests/testthat/_snaps/parser.md index 4ee4e21..bc63464 100644 --- a/tests/testthat/_snaps/parser.md +++ b/tests/testthat/_snaps/parser.md @@ -7,11 +7,13 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user("foo") - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user("foo") + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -25,11 +27,13 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user("foo") - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user("foo") + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -43,18 +47,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user("foo") - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user("foo") + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -68,18 +74,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user("foo") - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user("foo") + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -96,14 +104,16 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "foo" - "bar" + repeat { + switch(state[[1L]], `1` = { + user({ + "foo" + "bar" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -120,21 +130,23 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "foo" - "value" + repeat { + switch(state[[1L]], `1` = { + user({ + "foo" + "value" + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -151,14 +163,16 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "foo" - "value" + repeat { + switch(state[[1L]], `1` = { + user({ + "foo" + "value" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -176,24 +190,26 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "foo" - "value" - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "bar" + repeat { + switch(state[[1L]], `1` = { + user({ + "foo" + "value" + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "bar" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -211,24 +227,26 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "foo" - "value" - }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[1L]] <- 3L - }, `3` = { - user({ - "bar" + repeat { + switch(state[[1L]], `1` = { + user({ + "foo" + "value" + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[1L]] <- 3L + }, `3` = { + user({ + "bar" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -237,32 +255,40 @@ Code generator_body(function() { - repeat yield("value") + repeat { + yield("value") + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user("value") - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" + }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "value" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -283,39 +309,43 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "value" + body1() + "repeat" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "value" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + "break" + }) + break + }) + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { user({ - "break" + body2() }) - break - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body2() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -337,40 +367,44 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - body2() - "value" + body1() + "repeat" }) - state[[2L]] <- 2L - suspend() - return(last_value()) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + body2() + "value" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + body3() + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { user({ - body3() + body4() }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body4() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -379,26 +413,35 @@ Code generator_body(function() { - repeat next + repeat { + next + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" + }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "next" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -420,35 +463,39 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - body2() - "next" + body1() + "repeat" }) + state[[1L]] <- 2L state[[2L]] <- 1L }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + body2() + "next" + }) + state[[2L]] <- 1L + }, `2` = { + user({ + body3() + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + state[[1L]] <- 3L + }, `3` = { user({ - body3() + body4() }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body4() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -468,38 +515,42 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - loop_condition - })) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user({ - body2() - "value" - }) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 4L - }, `4` = { - user({ - body3() - }) + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + loop_condition + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + body2() + "value" + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 4L + }, `4` = { + user({ + body3() + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -509,7 +560,9 @@ Code generator_body(function() { repeat { - repeat yield("foo") + repeat { + yield("foo") + } } }) Output @@ -517,76 +570,99 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ "repeat" }) - state[[2L]] <- 2L - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - user("foo") - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L - }) - length(state) <- 2L + state[[1L]] <- 2L state[[2L]] <- 1L - }) - length(state) <- 1L - break - }) - exhausted <- TRUE - invisible(exhausted()) + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "repeat" + }) + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "foo" + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break + }) + } + exhausted <- TRUE + invisible(exhausted()) } --- Code generator_body(function() { - repeat repeat yield("foo") + repeat { + repeat { + yield("foo") + } + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - state[[2L]] <- 2L - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - user("foo") - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" }) - length(state) <- 2L + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "repeat" + }) + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "foo" + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -595,45 +671,59 @@ Code generator_body(function() { - repeat while (TRUE) yield("foo") + repeat { + while (TRUE) { + yield("foo") + } + } }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - state[[2L]] <- 2L - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - if (user(TRUE)) { - state[[3L]] <- 2L - } else { - break - } - }, `2` = { - user("foo") - state[[3L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" }) - length(state) <- 2L + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + if (user({ + TRUE + })) { + state[[3L]] <- 2L + } else { + break + } + }, `2` = { + user({ + "foo" + }) + state[[3L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -643,7 +733,9 @@ Code generator_body(function() { repeat { - repeat yield("foo") + repeat { + yield("foo") + } "after" } }) @@ -652,40 +744,48 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ "repeat" }) - state[[2L]] <- 2L - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - user("foo") - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L - }) - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { - user({ - "after" - }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "repeat" + }) + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "foo" + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + "after" + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -695,7 +795,9 @@ Code generator_body(function() { repeat { - repeat yield("foo") + repeat { + yield("foo") + } break } }) @@ -704,40 +806,48 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ "repeat" }) - state[[2L]] <- 2L - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user("foo") - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L - }) - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { - user({ - "break" - }) + repeat { + switch(state[[2L]], `1` = { + user({ + "repeat" + }) + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "foo" + }) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + "break" + }) + break + }) + } + length(state) <- 1L break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -747,7 +857,9 @@ Code generator_body(function() { repeat { - repeat break + repeat { + break + } break } }) @@ -756,34 +868,43 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ "repeat" }) - state[[2L]] <- 2L - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - break - }) - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { - user({ - "break" - }) + repeat { + switch(state[[2L]], `1` = { + user({ + "repeat" + }) + state[[2L]] <- 2L + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + break + }) + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + "break" + }) + break + }) + } + length(state) <- 1L break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -803,49 +924,53 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - }) - if (user({ - condition - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "then" + body1() }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + condition + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "then" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body2() + user({ + body2() + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -867,73 +992,79 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - }) - if (user({ - condition - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - "then" + body1() }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + condition + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + "then" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "else" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L + }, `4` = { user({ - "else" + body2() }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - body2() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -959,85 +1090,91 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - }) - if (user({ - condition - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - then1() - "then" + body1() }) - state[[2L]] <- 2L - suspend() - return(last_value()) + if (user({ + condition + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L + repeat { + switch(state[[2L]], `1` = { + user({ + then1() + "then" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + then2() + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `3` = { - user({ - then2() - }) - state[[2L]] <- 4L + repeat { + switch(state[[2L]], `1` = { + user({ + else1() + "else" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + user({ + else2() + }) + state[[2L]] <- 4L + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 4L }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - else1() - "else" - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { user({ - else2() + body2() }) - state[[2L]] <- 4L - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 4L - }, `4` = { - user({ - body2() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1057,65 +1194,71 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - if (user({ - condition - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - user({ - "then" - }) - state[[2L]] <- 2L - suspend() - return(last_value()) + repeat { + switch(state[[1L]], `1` = { + if (user({ + condition + })) { + state[[1L]] <- 2L + } else { + state[[1L]] <- 3L + } + state[[2L]] <- 1L }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[2L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }, `4` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "then" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[2L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L break - }) - n <- length(state) - if (n < 1L) { + }, `3` = { + repeat { + switch(state[[2L]], `1` = { + user({ + "else" + }) + exhausted <- TRUE + return(exhausted()) + }, `2` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `3` = { - repeat switch(state[[2L]], `1` = { - user({ - "else" - }) - exhausted <- TRUE - return(exhausted()) - }, `2` = { + }, `4` = { break }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - }, `4` = { - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1136,49 +1279,55 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - condition - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L + repeat { + switch(state[[1L]], `1` = { + user({ + body1() + "repeat" + }) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user({ - "break" + repeat { + switch(state[[2L]], `1` = { + if (user({ + condition + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `3` = { + state[[2L]] <- 1L }) - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next } - length(state) <- 2L - state[[2L]] <- 1L - }, `3` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1200,52 +1349,58 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - condition - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L - }, `2` = { - repeat switch(state[[3L]], `1` = { - user({ - "break" - }) - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 3L - }, `3` = { + repeat { + switch(state[[1L]], `1` = { user({ - body2() + body1() + "repeat" }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if (user({ + condition + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + body2() + }) + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1255,7 +1410,9 @@ Code generator_body(function() { body1() - if (truth1) if (truth2) yield("value") + if (truth1) { + if (truth2) yield("value") + } body2() }) Output @@ -1263,68 +1420,76 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - }) - if (user({ - truth1 - })) { - state[[1L]] <- 2L - } else { - state[[1L]] <- 3L - } - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(truth2)) { - state[[2L]] <- 2L + repeat { + switch(state[[1L]], `1` = { + user({ + body1() + }) + if (user({ + truth1 + })) { + state[[1L]] <- 2L } else { - state[[2L]] <- 3L + state[[1L]] <- 3L } - state[[3L]] <- 1L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user("value") - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) + repeat { + switch(state[[2L]], `1` = { + if (user({ + truth2 + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user("value") + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + break + }) + } n <- length(state) - if (n < 2L) { + if (n < 1L) { break } - if (n == 2L) { - state[[2L]] <- 1L + if (n == 1L) { + state[[1L]] <- 1L next } - length(state) <- 2L - state[[2L]] <- 3L + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body2() + user({ + body2() + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1344,48 +1509,54 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" + }) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user({ - "break" + repeat { + switch(state[[2L]], `1` = { + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `3` = { + state[[2L]] <- 1L }) - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next } - length(state) <- 2L - state[[2L]] <- 1L - }, `3` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1410,80 +1581,88 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - body1() + "repeat" }) - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - user({ - "break" + repeat { + switch(state[[2L]], `1` = { + user({ + body1() + }) + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } + state[[3L]] <- 1L + }, `2` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 4L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + user({ + "next" + }) + length(state) <- 2L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 4L + }, `4` = { + user({ + body2() + }) + state[[2L]] <- 1L }) - length(state) <- 1L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next } - length(state) <- 2L - state[[2L]] <- 4L + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - repeat switch(state[[3L]], `1` = { - user({ - "next" - }) - length(state) <- 2L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 4L - }, `4` = { user({ - body2() + body3() }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body3() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1495,7 +1674,11 @@ repeat { body1() if (TRUE) { - if (TRUE) next else break + if (TRUE) { + next + } else { + break + } body2() } body3() @@ -1507,102 +1690,118 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "repeat" - }) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { + repeat { + switch(state[[1L]], `1` = { user({ - body1() + "repeat" }) - if (user({ - TRUE - })) { - state[[2L]] <- 2L - } else { - state[[2L]] <- 3L - } - state[[3L]] <- 1L + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - repeat switch(state[[3L]], `1` = { - if (user({ - TRUE - })) { - state[[3L]] <- 2L - } else { - state[[3L]] <- 3L - } - state[[4L]] <- 1L - }, `2` = { - repeat switch(state[[4L]], `1` = { - length(state) <- 2L - break - }, `2` = { - break - }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { + repeat { + switch(state[[2L]], `1` = { + user({ + body1() + }) + if (user({ + TRUE + })) { + state[[2L]] <- 2L + } else { + state[[2L]] <- 3L + } state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 4L - }, `3` = { - repeat switch(state[[4L]], `1` = { - length(state) <- 1L - break }, `2` = { - break - }) - n <- length(state) - if (n < 3L) { - break - } - if (n == 3L) { - state[[3L]] <- 1L - next - } - length(state) <- 3L - state[[3L]] <- 4L - }, `4` = { - user({ - body2() + repeat { + switch(state[[3L]], `1` = { + if (user({ + TRUE + })) { + state[[3L]] <- 2L + } else { + state[[3L]] <- 3L + } + state[[4L]] <- 1L + }, `2` = { + repeat { + switch(state[[4L]], `1` = { + user({ + "next" + }) + length(state) <- 2L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 4L + }, `3` = { + repeat { + switch(state[[4L]], `1` = { + user({ + "break" + }) + length(state) <- 1L + break + }, `2` = { + break + }) + } + n <- length(state) + if (n < 3L) { + break + } + if (n == 3L) { + state[[3L]] <- 1L + next + } + length(state) <- 3L + state[[3L]] <- 4L + }, `4` = { + user({ + body2() + }) + state[[3L]] <- 5L + }, `5` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 3L + }, `3` = { + user({ + body3() + }) + state[[2L]] <- 1L }) - state[[3L]] <- 5L - }, `5` = { - break - }) - n <- length(state) - if (n < 2L) { - break } - if (n == 2L) { - state[[2L]] <- 1L - next - } - length(state) <- 2L - state[[2L]] <- 3L + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { user({ - body3() + body4() }) - state[[2L]] <- 1L - }) - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body4() + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1610,47 +1809,57 @@ # handle for loops Code - generator_body(function() for (x in 1:3) yield(x)) + generator_body(function() { + for (x in 1:3) { + yield(x) + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(1:3)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["x"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - user(x) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(1:3)) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["x"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + x + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL + } + length(state) <- 1L + break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1658,73 +1867,87 @@ --- Code - generator_body(function() for (x in 1:3) for (y in 2:4) yield(list(x, y))) + generator_body(function() { + for (x in 1:3) { + for (y in 2:4) { + yield(list(x, y)) + } + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(1:3)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["x"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(1:3)) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - iterators[[3L]] <- as_iterator(user(2:4)) - state[[2L]] <- 3L - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - if ({ - iterator <- iterators[[3L]] - if (is_exhausted(elt <- iterator())) { - FALSE + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["x"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L } else { - user_env[["y"]] <- elt - TRUE + break } - }) { - state[[3L]] <- 2L - } else { - break - } - }, `2` = { - user(list(x, y)) - state[[3L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 1L - }) + }, `2` = { + iterators[[3L]] <- as_iterator(user(2:4)) + state[[2L]] <- 3L + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + if ({ + iterator <- iterators[[3L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["y"]] <- elt + TRUE + } + }) { + state[[3L]] <- 2L + } else { + break + } + }, `2` = { + user({ + list(x, y) + }) + state[[3L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 1L + }) + } + { + iter_close(iterators[[3L]]) + iterators[[3L]] <- NULL + } + length(state) <- 2L + state[[2L]] <- 1L + }) + } { - iter_close(iterators[[3L]]) - iterators[[3L]] <- NULL + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL } - length(state) <- 2L - state[[2L]] <- 1L + length(state) <- 1L + break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1734,7 +1957,9 @@ Code generator_body(function() { body1() - for (x in 1:3) yield(x) + for (x in 1:3) { + yield(x) + } body2() }) Output @@ -1742,50 +1967,56 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - body1() - }) - iterators[[2L]] <- as_iterator(user(1:3)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["x"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + user({ + body1() + }) + iterators[[2L]] <- as_iterator(user(1:3)) + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - user(x) - state[[2L]] <- 3L - suspend() - return(last_value()) + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["x"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + user({ + x + }) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL + } + length(state) <- 1L + state[[1L]] <- 3L }, `3` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 1L - }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - state[[1L]] <- 3L - }, `3` = { - user({ - body2() + user({ + body2() + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1799,16 +2030,18 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user(x) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- user_env[["x"]] <- if (missing(arg)) NULL else arg - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user(x) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- user_env[["x"]] <- if (missing(arg)) NULL else arg + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1824,18 +2057,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - x + repeat { + switch(state[[1L]], `1` = { + user({ + x + }) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- user_env[["x"]] <- if (missing(arg)) NULL else arg + exhausted <- TRUE + return(exhausted()) }) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- user_env[["x"]] <- if (missing(arg)) NULL else arg - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1849,11 +2084,13 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user(tryCatch(foo())) - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user(tryCatch(foo())) + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1872,49 +2109,53 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "tryCatch" - }) - handlers[[2L]] <- user(base::list(error = function(...) "handled")) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - .last_value <- with_try_catch(handlers[[2L]], { - { - repeat switch(state[[2L]], `1` = { - user({ - stop("error") - "yield" - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[2L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(exhausted()) - }, `4` = { - break - }) - n <- length(state) - if (n < 1L) { + repeat { + switch(state[[1L]], `1` = { + user({ + "tryCatch" + }) + handlers[[2L]] <- user(base::list(error = function(...) "handled")) + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + .last_value <- with_try_catch(handlers[[2L]], { + { + repeat { + switch(state[[2L]], `1` = { + user({ + stop("error") + "yield" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[2L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(exhausted()) + }, `4` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L break } - if (n == 1L) { - state[[1L]] <- 1L - next - } - length(state) <- 1L - break - } - last_value() + last_value() + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1934,51 +2175,55 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "tryCatch" - }) - handlers[[2L]] <- user(base::list(error = function(...) "handled")) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - with_try_catch(handlers[[2L]], { - { - repeat switch(state[[2L]], `1` = { - user({ - stop("error") - "yield" - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next + repeat { + switch(state[[1L]], `1` = { + user({ + "tryCatch" + }) + handlers[[2L]] <- user(base::list(error = function(...) "handled")) + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + with_try_catch(handlers[[2L]], { + { + repeat { + switch(state[[2L]], `1` = { + user({ + stop("error") + "yield" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 3L } - length(state) <- 1L - state[[1L]] <- 3L - } - last_value() - }) - state[[1L]] <- 3L - }, `3` = { - user({ - "value" + last_value() + }) + state[[1L]] <- 3L + }, `3` = { + user({ + "value" + }) + exhausted <- TRUE + return(exhausted()) }) - exhausted <- TRUE - return(exhausted()) - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -1992,11 +2237,13 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user(withCallingHandlers(expr)) - exhausted <- TRUE - return(exhausted()) - }) + repeat { + switch(state[[1L]], `1` = { + user(withCallingHandlers(expr)) + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2015,47 +2262,51 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - user({ - "tryCatch" - }) - handlers[[2L]] <- user(base::list(error = function(...) "handled")) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - .last_value <- user_env[["value"]] <- with_try_catch(handlers[[2L]], - { + repeat { + switch(state[[1L]], `1` = { + user({ + "tryCatch" + }) + handlers[[2L]] <- user(base::list(error = function(...) "handled")) + state[[1L]] <- 2L + state[[2L]] <- 1L + }, `2` = { + .last_value <- user_env[["value"]] <- with_try_catch(handlers[[2L]], { - repeat switch(state[[2L]], `1` = { - user({ - stop("error") - "yield" - }) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[2L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 1L) { - break - } - if (n == 1L) { - state[[1L]] <- 1L - next + { + repeat { + switch(state[[2L]], `1` = { + user({ + stop("error") + "yield" + }) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 1L) { + break + } + if (n == 1L) { + state[[1L]] <- 1L + next + } + length(state) <- 1L + state[[1L]] <- 3L } - length(state) <- 1L - state[[1L]] <- 3L - } - last_value() - }) - exhausted <- TRUE - return(exhausted()) - }) + last_value() + }) + exhausted <- TRUE + return(exhausted()) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2069,18 +2320,20 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - .last_value <- then(as_promise(user(x)), callback = .self) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) exhausted() else arg - state[[1L]] <- 3L - }, `3` = { - exhausted <- TRUE - return(as_promise(last_value())) - }) + repeat { + switch(state[[1L]], `1` = { + .last_value <- then(as_promise(user(x)), callback = .self) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) exhausted() else arg + state[[1L]] <- 3L + }, `3` = { + exhausted <- TRUE + return(as_promise(last_value())) + }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2088,28 +2341,41 @@ --- Code - async_body(function() repeat await(x)) + async_body(function() { + repeat { + await(x) + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - .last_value <- then(as_promise(user(x)), callback = .self) - state[[2L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + user({ + "repeat" + }) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + .last_value <- then(as_promise(user({ + x + })), callback = .self) + state[[2L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2117,57 +2383,72 @@ --- Code - async_body(function() while (x) if (y) await(z)) + async_body(function() { + while (x) { + if (y) await(z) + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if (user(x)) { - state[[2L]] <- 2L - } else { - break - } + repeat { + switch(state[[1L]], `1` = { + state[[1L]] <- 2L + state[[2L]] <- 1L }, `2` = { - if (user(y)) { - state[[2L]] <- 3L - } else { - state[[2L]] <- 4L - } - state[[3L]] <- 1L - }, `3` = { - repeat switch(state[[3L]], `1` = { - .last_value <- then(as_promise(user(z)), callback = .self) - state[[3L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- if (missing(arg)) NULL else arg - state[[3L]] <- 3L - }, `3` = { - break - }) - n <- length(state) - if (n < 2L) { - break - } - if (n == 2L) { - state[[2L]] <- 1L - next + repeat { + switch(state[[2L]], `1` = { + if (user({ + x + })) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + if (user({ + y + })) { + state[[2L]] <- 3L + } else { + state[[2L]] <- 4L + } + state[[3L]] <- 1L + }, `3` = { + repeat { + switch(state[[3L]], `1` = { + .last_value <- then(as_promise(user(z)), + callback = .self) + state[[3L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- if (missing(arg)) NULL else arg + state[[3L]] <- 3L + }, `3` = { + break + }) + } + n <- length(state) + if (n < 2L) { + break + } + if (n == 2L) { + state[[2L]] <- 1L + next + } + length(state) <- 2L + state[[2L]] <- 1L + }, `4` = { + state[[2L]] <- 1L + }) } - length(state) <- 2L - state[[2L]] <- 1L - }, `4` = { - state[[2L]] <- 1L + length(state) <- 1L + break }) - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2175,47 +2456,57 @@ --- Code - async_body(function() for (x in y) await(z)) + async_body(function() { + for (x in y) { + await(z) + } + }) Output { if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - iterators[[2L]] <- as_iterator(user(y)) - state[[1L]] <- 2L - state[[2L]] <- 1L - }, `2` = { - repeat switch(state[[2L]], `1` = { - if ({ - iterator <- iterators[[2L]] - if (is_exhausted(elt <- iterator())) { - FALSE - } else { - user_env[["x"]] <- elt - TRUE - } - }) { - state[[2L]] <- 2L - } else { - break - } - }, `2` = { - .last_value <- then(as_promise(user(z)), callback = .self) - state[[2L]] <- 3L - suspend() - return(last_value()) - }, `3` = { - .last_value <- if (missing(arg)) NULL else arg + repeat { + switch(state[[1L]], `1` = { + iterators[[2L]] <- as_iterator(user(y)) + state[[1L]] <- 2L state[[2L]] <- 1L + }, `2` = { + repeat { + switch(state[[2L]], `1` = { + if ({ + iterator <- iterators[[2L]] + if (is_exhausted(elt <- iterator())) { + FALSE + } else { + user_env[["x"]] <- elt + TRUE + } + }) { + state[[2L]] <- 2L + } else { + break + } + }, `2` = { + .last_value <- then(as_promise(user({ + z + })), callback = .self) + state[[2L]] <- 3L + suspend() + return(last_value()) + }, `3` = { + .last_value <- if (missing(arg)) NULL else arg + state[[2L]] <- 1L + }) + } + { + iter_close(iterators[[2L]]) + iterators[[2L]] <- NULL + } + length(state) <- 1L + break }) - { - iter_close(iterators[[2L]]) - iterators[[2L]] <- NULL - } - length(state) <- 1L - break - }) + } exhausted <- TRUE invisible(exhausted()) } @@ -2229,16 +2520,19 @@ if (exhausted) { return(invisible(exhausted())) } - repeat switch(state[[1L]], `1` = { - .last_value <- then(as_promise(user(async_foo())), callback = .self) - state[[1L]] <- 2L - suspend() - return(last_value()) - }, `2` = { - .last_value <- user_env[["x"]] <- if (missing(arg)) NULL else arg - exhausted <- TRUE - return(as_promise(last_value())) - }) + repeat { + switch(state[[1L]], `1` = { + .last_value <- then(as_promise(user(async_foo())), + callback = .self) + state[[1L]] <- 2L + suspend() + return(last_value()) + }, `2` = { + .last_value <- user_env[["x"]] <- if (missing(arg)) NULL else arg + exhausted <- TRUE + return(as_promise(last_value())) + }) + } exhausted <- TRUE invisible(exhausted()) } diff --git a/tests/testthat/test-async.R b/tests/testthat/test-async.R index c12ff4a..f302454 100644 --- a/tests/testthat/test-async.R +++ b/tests/testthat/test-async.R @@ -2,8 +2,16 @@ test_that("async functions construct a generator", { expect_snapshot0(async_body(function() "value")) expect_snapshot0(async_body(function() await("value"))) expect_snapshot0(async_body(function() if (1) await("value") else "else")) - expect_snapshot0(async_body(function() while (1) if (2) await("value"))) - expect_snapshot0(async_body(function() while (1) foo <- await("value"))) + expect_snapshot0(async_body(function() { + while (1) { + if (2) await("value") + } + })) + expect_snapshot0(async_body(function() { + while (1) { + foo <- await("value") + } + })) }) test_that("async() takes anonymous functions", { @@ -89,7 +97,11 @@ test_that("async_generator() creates streams", { }) test_that("can adapt async streams", { - new_stream <- async_generator(function(x) for (elt in x) yield(elt)) + new_stream <- async_generator(function(x) { + for (elt in x) { + yield(elt) + } + }) consumed <- NULL async_obs <- async(function(i) { @@ -117,7 +129,11 @@ test_that("async() functions can take dots", { }) test_that("async_collect() collects", { - new_stream <- async_generator(function(x) for (elt in x) yield(elt)) + new_stream <- async_generator(function(x) { + for (elt in x) { + yield(elt) + } + }) s1 <- new_stream(1:5) s2 <- async_adapt(s1, iter_map(`*`, 3)) @@ -125,7 +141,6 @@ test_that("async_collect() collects", { out <- wait_for(async_collect(s2)) expect_equal(out, as.list(1:5 * 3)) - s1 <- new_stream(1:5) s2 <- async_adapt(s1, iter_map(`*`, 3)) @@ -134,9 +149,17 @@ test_that("async_collect() collects", { }) test_that("for loops support await_each()", { - new_stream <- async_generator(function(x) for (elt in x) yield(elt)) + new_stream <- async_generator(function(x) { + for (elt in x) { + yield(elt) + } + }) - f <- async_generator(function(s) for (x in await_each(s)) yield(x * 2)) + f <- async_generator(function(s) { + for (x in await_each(s)) { + yield(x * 2) + } + }) out <- wait_for(async_collect(f(new_stream(1:3)))) expect_equal(out, list(2, 4, 6)) @@ -193,7 +216,14 @@ test_that("Iterators are cleaned up from most nested to least nested", { }) test_that("await_each() can't be used in generators", { - expect_error(generator(function() for (x in await_each(i)) NULL)()(), "non-async generator") + expect_error( + generator(function() { + for (x in await_each(i)) { + NULL + } + })()(), + "non-async generator" + ) }) test_that("yield() can't be used in async() functions", { @@ -234,7 +264,10 @@ test_that("async functions and async generator factories print nicely", { expect_snapshot(print(fn, reproducible = TRUE)) expect_snapshot(print(fn, internals = TRUE, reproducible = TRUE)) - factory <- async_generator(function() { await(NULL); yield(NULL) }) + factory <- async_generator(function() { + await(NULL) + yield(NULL) + }) expect_snapshot(print(factory, reproducible = TRUE)) expect_snapshot(print(factory, internals = TRUE, reproducible = TRUE)) @@ -320,10 +353,10 @@ test_that("async function returns invisibly (#46)", { test_that("async functions do not cause CMD check notes (#40)", { skip_on_cran() - invisible(compiler::cmpfun( - async(function() NULL), - options = list(suppressAll = FALSE) - )) + invisible(compiler::cmpfun( + async(function() NULL), + options = list(suppressAll = FALSE) + )) expect_silent( invisible(compiler::cmpfun( async(function() NULL), diff --git a/tests/testthat/test-generator.R b/tests/testthat/test-generator.R index fc748fa..e245981 100644 --- a/tests/testthat/test-generator.R +++ b/tests/testthat/test-generator.R @@ -11,13 +11,23 @@ test_that("can yield `NULL` without terminating iteration", { test_that("short syntax and for loop support", { numbers <- 1:6 - odds <- gen(for (x in numbers) if (x %% 2 != 0) yield(x)) - squares <- gen(for (x in odds) yield(x^2)) + odds <- gen( + for (x in numbers) { + if (x %% 2 != 0) yield(x) + } + ) + squares <- gen( + for (x in odds) { + yield(x^2) + } + ) out <- dbl() - loop(for (x in squares) { - out <- c(out, x) - }) + loop( + for (x in squares) { + out <- c(out, x) + } + ) expect_identical(out, dbl(1, 9, 25)) }) @@ -36,7 +46,11 @@ test_that("generator instances prints nicely", { }) test_that("can send values to generators", { - g <- generator(function(x) repeat x <- yield(x)) + g <- generator(function(x) { + repeat { + x <- yield(x) + } + }) expect_identical(g(1)(), 1) expect_identical(g(2)(), 2) }) @@ -106,7 +120,8 @@ test_that("unexpected exits disable generators", { test_that("can use tryCatch()", { out <- collect(gen({ x <- tryCatch( - error = function(...) "handled", { + error = function(...) "handled", + { stop("error") yield("yield") } @@ -117,7 +132,8 @@ test_that("can use tryCatch()", { out <- collect(gen({ x <- tryCatch( - error = function(...) "handled", { + error = function(...) "handled", + { stop("error") yield("yield") } @@ -130,8 +146,11 @@ test_that("can use tryCatch()", { out <- collect(gen({ if (TRUE) { x <- tryCatch( - error = function(...) "handled", { - repeat if (TRUE) stop("error") + error = function(...) "handled", + { + repeat { + if (TRUE) stop("error") + } yield("yield") } ) @@ -141,14 +160,21 @@ test_that("can use tryCatch()", { })) expect_equal(out, list("handled", "value")) - out <- gen(tryCatch({ stop("foo"); yield("value") }, error = function(...) "handled"))() + out <- gen(tryCatch( + { + stop("foo") + yield("value") + }, + error = function(...) "handled" + ))() expect_equal(out, exhausted()) # Handlers are matched to the condition class expect_error( gen({ tryCatch( - foo = function(...) "handled", { + foo = function(...) "handled", + { stop("error") yield("yield") } @@ -163,7 +189,8 @@ test_that("tryCatch(finally = ) is handled", { expect_error( gen({ tryCatch( - error = function(...) "handled", { + error = function(...) "handled", + { stop("error") yield("yield") }, @@ -201,7 +228,14 @@ test_that("can assign tryCatch()", { test_that("can't await() within a generator", { expect_error(generator(function() await(foo))(), "non-async") - expect_error(generator(function() for (x in await_each(foo)) NULL)(), "non-async") + expect_error( + generator(function() { + for (x in await_each(foo)) { + NULL + } + })(), + "non-async" + ) }) test_that("reentering the generator forces argument in proper context", { @@ -286,7 +320,11 @@ test_that("generators call as_iterator() method", { i <- structure(list(), class = "coro_iterator") out <- NULL - loop(for (x in i) out <- c(out, x)) + loop( + for (x in i) { + out <- c(out, x) + } + ) expect_equal(out, 1:3) }) @@ -336,9 +374,11 @@ test_that("on.exit is called when loop breaks early (#52)", { called <- FALSE expect_error( - coro::loop(for (i in g()) { - stop("boom!") - }) + coro::loop( + for (i in g()) { + stop("boom!") + } + ) ) expect_true(called) diff --git a/tests/testthat/test-iterator-for.R b/tests/testthat/test-iterator-for.R index facf80f..47f389e 100644 --- a/tests/testthat/test-iterator-for.R +++ b/tests/testthat/test-iterator-for.R @@ -2,9 +2,11 @@ test_that("can loop() with iterators", { iter <- as_iterator(1:3) out <- int() - loop(for (x in iter) { - out <- c(out, x) - }) + loop( + for (x in iter) { + out <- c(out, x) + } + ) expect_identical(out, 1:3) }) @@ -12,13 +14,15 @@ test_that("can use break within loop()", { out <- int() bool <- FALSE - loop(for (x in 1:3) { - out <- c(out, x) - if (bool) { - break + loop( + for (x in 1:3) { + out <- c(out, x) + if (bool) { + break + } + bool <- TRUE } - bool <- TRUE - }) + ) expect_identical(out, 1:2) }) @@ -27,14 +31,16 @@ test_that("can use next within loop()", { out <- int() bool <- FALSE - loop(for (x in 1:3) { - if (bool) { - next - } else { - out <- c(out, x) + loop( + for (x in 1:3) { + if (bool) { + next + } else { + out <- c(out, x) + } + bool <- TRUE } - bool <- TRUE - }) + ) expect_identical(out, 1L) }) @@ -43,21 +49,37 @@ test_that("can loop with a non-block expression", { iter <- as_iterator(1:3) out <- int() - loop(for (x in iter) out <- c(out, x)) + loop( + for (x in iter) { + out <- c(out, x) + } + ) expect_identical(out, 1:3) }) test_that("iterating with a done iterator cause an error", { iter <- gen("foo") - loop(for (x in iter) x) - expect_exhausted(loop(for (x in iter) x)) + loop( + for (x in iter) { + x + } + ) + expect_exhausted(loop( + for (x in iter) { + x + } + )) }) test_that("iterating works when coro is not loaded", { new_env <- new.env(parent = baseenv()) evalq( - coro::loop(for (x in coro::as_iterator(1:3)) x), + coro::loop( + for (x in coro::as_iterator(1:3)) { + x + } + ), new_env ) @@ -75,23 +97,41 @@ test_that("loop returns invisibly", { test_that("can return from `loop()`", { fn <- function() { - loop(for (x in 1) return("foo")) + loop( + for (x in 1) { + return("foo") + } + ) } expect_identical(fn(), "foo") }) test_that("loop() fails informatively inside generators (#31)", { expect_snapshot_error( - gen(loop(for (x in 1:10) yield(x)))(), + gen(loop( + for (x in 1:10) { + yield(x) + } + ))(), cran = TRUE ) }) test_that("can use loop() in lambdas inside generators", { out <- NULL - g <- gen(for (i in 1:3) yield(i)) + g <- gen( + for (i in 1:3) { + yield(i) + } + ) gen({ - f <- function() loop(for (x in g) out <<- c(out, x)) + f <- function() { + loop( + for (x in g) { + out <<- c(out, x) + } + ) + } f() })() expect_equal(out, 1:3) diff --git a/tests/testthat/test-iterator.R b/tests/testthat/test-iterator.R index 1b1e46c..c73f794 100644 --- a/tests/testthat/test-iterator.R +++ b/tests/testthat/test-iterator.R @@ -3,13 +3,15 @@ test_that("can use reticulate iterators", { skip_on_cran() skip_on_ci() - reticulate::py_run_string(" + reticulate::py_run_string( + " def first_n(n): num = 1 while num <= n: yield num num += 1 -") +" + ) expect_equal( collect(reticulate::py$first_n(3)), @@ -17,12 +19,12 @@ def first_n(n): ) out <- NULL - loop(for (x in reticulate::py$first_n(3)) { - out <- c(out, x) - }) + loop( + for (x in reticulate::py$first_n(3)) { + out <- c(out, x) + } + ) expect_equal(out, 1:3) - - }) @@ -32,10 +34,10 @@ test_that("can use reticulate iteratables", { skip_on_ci() i <- 0L - loop(for (el in reticulate::py_eval("range(3)")) { - i <- i + el - }) + loop( + for (el in reticulate::py_eval("range(3)")) { + i <- i + el + } + ) expect_equal(i, 3L) }) - - diff --git a/tests/testthat/test-parser-block.R b/tests/testthat/test-parser-block.R index 86913e0..b787fba 100644 --- a/tests/testthat/test-parser-block.R +++ b/tests/testthat/test-parser-block.R @@ -135,5 +135,9 @@ test_that("`{` blocks - simple nesting with various continuation states", { }) test_that("yield assignment in a loop", { - expect_snapshot0(generator_body(function() while (1) var <- yield("value"))) + expect_snapshot0(generator_body(function() { + while (1) { + var <- yield("value") + } + })) }) diff --git a/tests/testthat/test-parser-if.R b/tests/testthat/test-parser-if.R index c774808..04b5262 100644 --- a/tests/testthat/test-parser-if.R +++ b/tests/testthat/test-parser-if.R @@ -49,7 +49,9 @@ test_that("`if` blocks - nested", { "before" if (TRUE) { "if-before" - if (FALSE) yield(1L) + if (FALSE) { + yield(1L) + } "if-after" } else { "foo" diff --git a/tests/testthat/test-parser-loop.R b/tests/testthat/test-parser-loop.R index 1c9aa05..bf527f1 100644 --- a/tests/testthat/test-parser-loop.R +++ b/tests/testthat/test-parser-loop.R @@ -13,13 +13,19 @@ test_that("`repeat` - one pause", { test_that("`repeat` - no continuation", { expect_snapshot0(generator_body(function() { "before" - repeat yield(1L) + repeat { + yield(1L) + } "after" })) expect_snapshot0(generator_body(function() { "before" - repeat {{ yield(1L) }} + repeat { + { + yield(1L) + } + } "after" })) }) @@ -29,7 +35,9 @@ test_that("`repeat` - pause within `if`", { "before" repeat { "loop-before" - if (TRUE) yield(1L) + if (TRUE) { + yield(1L) + } "loop-after" } "after" @@ -41,7 +49,9 @@ test_that("`repeat` - nested loop", { "before" repeat { "loop-before" - repeat yield(1L) + repeat { + yield(1L) + } "loop-after" } "after" @@ -51,7 +61,9 @@ test_that("`repeat` - nested loop", { test_that("`repeat` - non-yielding", { expect_snapshot0(generator_body(function() { "before" - repeat NULL + repeat { + NULL + } yield(1L) "after" })) @@ -61,7 +73,9 @@ test_that("`repeat` - non-yielding but other control flow constructs", { # FIXME expect_snapshot0(generator_body(function() { "before" - repeat if (TRUE) break else next + repeat { + if (TRUE) break else next + } yield(1L) "after" })) @@ -103,8 +117,11 @@ test_that("loops - `next` and `break` within `if`-`else`", { expect_snapshot0(generator_body(function() { repeat { "loop-after" - if (TRUE) break - else next + if (TRUE) { + break + } else { + next + } "next-after" } })) @@ -128,17 +145,23 @@ test_that("loops - `break` and `next` with past and future", { test_that("loops - goto loop start after `if` or `else`", { expect_snapshot0(generator_body(function() { - repeat if (TRUE) yield() + repeat { + if (TRUE) yield() + } })) expect_snapshot0(generator_body(function() { - repeat if (TRUE) yield(1L) else FALSE + repeat { + if (TRUE) yield(1L) else FALSE + } })) }) test_that("`while` - single pause no past or future", { expect_snapshot0(generator_body(function() { - while (TRUE) yield(1L) + while (TRUE) { + yield(1L) + } })) }) @@ -185,7 +208,9 @@ test_that("`while` - pause after loop", { test_that("`while` - complex control flow", { expect_snapshot0(generator_body(function() { "before" - while (TRUE) break + while (TRUE) { + break + } while (TRUE) { "loop-before" yield(1L) @@ -218,13 +243,17 @@ test_that("`while` - top level break", { test_that("`for` - top level break (#7)", { expect_snapshot0(generator_body(function() { - for (i in x) break + for (i in x) { + break + } })) }) test_that("`for` - one pause with no past or future", { expect_snapshot0(generator_body(function() { - for (i in x) yield(1L) + for (i in x) { + yield(1L) + } })) }) @@ -244,8 +273,11 @@ test_that("`for` - one pause within `if` and one `break` within `else`", { expect_snapshot0(generator_body(function() { for (i in x) { "for-before" - if (TRUE) yield(1L) - else break + if (TRUE) { + yield(1L) + } else { + break + } "if-after" next "for-after" @@ -254,7 +286,11 @@ test_that("`for` - one pause within `if` and one `break` within `else`", { }) test_that("`return()` deep in control flow", { - expect_snapshot0(generator_body(function() { while (TRUE) if (TRUE) return(1L) else yield(2L) })) + expect_snapshot0(generator_body(function() { + while (TRUE) { + if (TRUE) return(1L) else yield(2L) + } + })) }) test_that("nested loops break to outer loops", { @@ -286,7 +322,6 @@ test_that("nested loops break to outer loops", { } )) - expect_snapshot0(generator_body( function() { "before" diff --git a/tests/testthat/test-parser.R b/tests/testthat/test-parser.R index 98d9c8a..98ab4e7 100644 --- a/tests/testthat/test-parser.R +++ b/tests/testthat/test-parser.R @@ -39,7 +39,9 @@ test_that("generators support blocks", { test_that("generators support repeat loops", { expect_snapshot0(generator_body(function() { - repeat yield("value") + repeat { + yield("value") + } })) expect_snapshot0(generator_body(function() { @@ -62,7 +64,9 @@ test_that("generators support repeat loops", { })) expect_snapshot0(generator_body(function() { - repeat next + repeat { + next + } })) expect_snapshot0(generator_body(function() { @@ -88,34 +92,52 @@ test_that("generators support while loops", { test_that("generators support nested loops", { expect_snapshot0(generator_body(function() { - repeat { repeat yield("foo") } + repeat { + repeat { + yield("foo") + } + } })) # No srcrefs for inner loops expect_snapshot0(generator_body(function() { - repeat repeat yield("foo") + repeat { + repeat { + yield("foo") + } + } })) expect_snapshot0(generator_body(function() { - repeat while (TRUE) yield("foo") + repeat { + while (TRUE) { + yield("foo") + } + } })) expect_snapshot0(generator_body(function() { repeat { - repeat yield("foo") + repeat { + yield("foo") + } "after" } })) expect_snapshot0(generator_body(function() { repeat { - repeat yield("foo") + repeat { + yield("foo") + } break } })) expect_snapshot0(generator_body(function() { repeat { - repeat break + repeat { + break + } break } })) @@ -185,7 +207,9 @@ test_that("break within if", { expect_snapshot0(generator_body(function() { body1() - if (truth1) if (truth2) yield("value") + if (truth1) { + if (truth2) yield("value") + } body2() })) }) @@ -235,7 +259,11 @@ test_that("next and break within two layers of if-else", { repeat { body1() if (TRUE) { - if (TRUE) next else break + if (TRUE) { + next + } else { + break + } body2() } body3() @@ -245,19 +273,33 @@ test_that("next and break within two layers of if-else", { }) test_that("handle for loops", { - expect_snapshot0(generator_body(function() for (x in 1:3) yield(x))) - expect_snapshot0(generator_body(function() for (x in 1:3) for (y in 2:4) yield(list(x, y)))) + expect_snapshot0(generator_body(function() { + for (x in 1:3) { + yield(x) + } + })) + expect_snapshot0(generator_body(function() { + for (x in 1:3) { + for (y in 2:4) { + yield(list(x, y)) + } + } + })) expect_snapshot0(generator_body(function() { body1() - for (x in 1:3) yield(x) + for (x in 1:3) { + yield(x) + } body2() })) }) test_that("handle yield-assign", { expect_snapshot0(generator_body(function(x) x <- yield(x))) - expect_snapshot0(generator_body(function(x) { x <- yield(x) })) + expect_snapshot0(generator_body(function(x) { + x <- yield(x) + })) }) test_that("can parse generators without source references", { @@ -276,9 +318,23 @@ test_that("can parse generators without source references", { }) test_that("tryCatch() expressions are treated as normal expressions if possible", { - expect_equal(with_handlers_type(quote(tryCatch(error = hnd, foo())), "tryCatch"), "expr") - expect_equal(with_handlers_type(quote(tryCatch(error = hnd, yield())), "tryCatch"), "tryCatch") - expect_equal(with_handlers_type(quote(tryCatch(error = hnd, { foo() })), "tryCatch"), "tryCatch") + expect_equal( + with_handlers_type(quote(tryCatch(error = hnd, foo())), "tryCatch"), + "expr" + ) + expect_equal( + with_handlers_type(quote(tryCatch(error = hnd, yield())), "tryCatch"), + "tryCatch" + ) + expect_equal( + with_handlers_type( + quote(tryCatch(error = hnd, { + foo() + })), + "tryCatch" + ), + "tryCatch" + ) expect_snapshot0(generator_body(function() tryCatch(foo()))) }) @@ -286,7 +342,8 @@ test_that("tryCatch() expressions are treated as normal expressions if possible" test_that("tryCatch() expressions are parsed", { expect_snapshot0(generator_body(function() { tryCatch( - error = function(...) "handled", { + error = function(...) "handled", + { stop("error") yield("yield") } @@ -295,7 +352,8 @@ test_that("tryCatch() expressions are parsed", { expect_snapshot0(generator_body(function() { tryCatch( - error = function(...) "handled", { + error = function(...) "handled", + { stop("error") yield("yield") } @@ -311,7 +369,9 @@ test_that("withCallingHandlers() expressions are parsed", { "not implemented yet" ) expect_error( - generator_body(function() { withCallingHandlers(yield("value")) }), + generator_body(function() { + withCallingHandlers(yield("value")) + }), "not implemented yet" ) }) @@ -319,7 +379,8 @@ test_that("withCallingHandlers() expressions are parsed", { test_that("tryCatch() can be assigned", { expect_snapshot0(generator_body(function() { value <- tryCatch( - error = function(...) "handled", { + error = function(...) "handled", + { stop("error") yield("yield") } @@ -331,9 +392,21 @@ test_that("trailing `await()` returns the awaited value wrapped in a promise", { expect_snapshot0(async_body(function() await(x))) # Non-returning cases - expect_snapshot0(async_body(function() repeat await(x))) - expect_snapshot0(async_body(function() while (x) if (y) await(z))) - expect_snapshot0(async_body(function() for (x in y) await(z))) + expect_snapshot0(async_body(function() { + repeat { + await(x) + } + })) + expect_snapshot0(async_body(function() { + while (x) { + if (y) await(z) + } + })) + expect_snapshot0(async_body(function() { + for (x in y) { + await(z) + } + })) # Assignment case expect_snapshot0(async_body(function() x <- await(async_foo()))) diff --git a/tests/testthat/test-step-reduce.R b/tests/testthat/test-step-reduce.R index f7fad0a..78d8c79 100644 --- a/tests/testthat/test-step-reduce.R +++ b/tests/testthat/test-step-reduce.R @@ -106,29 +106,53 @@ test_that("collect() calls `as_iterator()`", { test_that("collect() preserves type (#32)", { expect_equal( - collect(gen(for (i in 1:3) yield(i))), + collect(gen( + for (i in 1:3) { + yield(i) + } + )), as.list(1:3) ) expect_equal( - wait_for(async_collect(async_generator(function() for (i in 1:3) yield(i))())), + wait_for(async_collect(async_generator(function() { + for (i in 1:3) { + yield(i) + } + })())), as.list(1:3) ) expect_equal( - collect(gen(for (i in 1:3) yield(list(i)))), + collect(gen( + for (i in 1:3) { + yield(list(i)) + } + )), lapply(1:3, list) ) expect_equal( - wait_for(async_collect(async_generator(function() for (i in 1:3) yield(list(i)))())), + wait_for(async_collect(async_generator(function() { + for (i in 1:3) { + yield(list(i)) + } + })())), lapply(1:3, list) ) expect_equal( - collect(gen(for (i in 1:3) yield(mtcars[i, 1:3]))), + collect(gen( + for (i in 1:3) { + yield(mtcars[i, 1:3]) + } + )), lapply(1:3, function(i) mtcars[i, 1:3]) ) expect_equal( - wait_for(async_collect(async_generator(function() for (i in 1:3) yield(mtcars[i, 1:3]))())), + wait_for(async_collect(async_generator(function() { + for (i in 1:3) { + yield(mtcars[i, 1:3]) + } + })())), lapply(1:3, function(i) mtcars[i, 1:3]) ) }) From fdc2a575d82c07ef9786150b37fac016bc446d11 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Wed, 10 Sep 2025 10:02:25 +0200 Subject: [PATCH 2/2] Use `delayedAssign()` --- R/aaa.R | 3 -- R/iterator-adapt.R | 50 ++++++++++++++++---------------- R/step-reduce.R | 72 +++++++++++++++++++++++----------------------- 3 files changed, 61 insertions(+), 64 deletions(-) diff --git a/R/aaa.R b/R/aaa.R index 81d4f2a..1f7ebe6 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -2,9 +2,6 @@ run_on_load() } -`%<~%` <- function(lhs, rhs, env = caller_env()) { - env_bind_lazy(env, !!substitute(lhs) := !!substitute(rhs), .eval_env = env) -} on_load <- function(expr, env = topenv(caller_env())) { callback <- function() eval_bare(expr, env) diff --git a/R/iterator-adapt.R b/R/iterator-adapt.R index 93d94a9..55b7b6f 100644 --- a/R/iterator-adapt.R +++ b/R/iterator-adapt.R @@ -79,36 +79,36 @@ iter_builder <- function(result, input) { #' @rdname iter_adapt #' @name async_adapt #' @usage async_adapt(iter, steps) -on_load( - async_adapt %<~% - async_generator(function(iter, steps) { - force(iter) +on_load(delayedAssign( + "async_adapt", + async_generator(function(iter, steps) { + force(iter) - reducer <- steps(iter_builder) + reducer <- steps(iter_builder) - # Initialise the adaptors - reducer() + # Initialise the adaptors + reducer() - flag <- "_coro_iter_adapt_result" - - while (TRUE) { - out <- await(iter()) + flag <- "_coro_iter_adapt_result" - if (is_exhausted(out)) { - # Finalise adaptors and signal exhaustion - reducer(NULL) - return(exhausted()) - } + while (TRUE) { + out <- await(iter()) - last <- reducer(flag, out) + if (is_exhausted(out)) { + # Finalise adaptors and signal exhaustion + reducer(NULL) + return(exhausted()) + } - # If we get `flag` back, it means a transducer has skipped this - # input. Continue until we get an actual result. - if (identical(last, flag)) { - next - } + last <- reducer(flag, out) - yield(last) + # If we get `flag` back, it means a transducer has skipped this + # input. Continue until we get an actual result. + if (identical(last, flag)) { + next } - }) -) + + yield(last) + } + }) +)) diff --git a/R/step-reduce.R b/R/step-reduce.R index 4f5b8c7..10b8ee7 100644 --- a/R/step-reduce.R +++ b/R/step-reduce.R @@ -336,50 +336,50 @@ iter_reduce_impl <- function(.x, .f, ..., .init, .left = TRUE) { out } -on_load( - async_reduce_steps %<~% - async(function(x, steps, builder, init) { - builder <- as_closure(builder) +on_load(delayedAssign( + "async_reduce_steps", + async(function(x, steps, builder, init) { + builder <- as_closure(builder) - if (is_null(steps)) { - reducer <- builder - } else { - reducer <- steps(builder) - } - stopifnot(is_closure(reducer)) + if (is_null(steps)) { + reducer <- builder + } else { + reducer <- steps(builder) + } + stopifnot(is_closure(reducer)) - if (missing(init)) { - identity <- reducer() - } else { - identity <- init - } + if (missing(init)) { + identity <- reducer() + } else { + identity <- init + } - result <- await(async_reduce(x, reducer)) + result <- await(async_reduce(x, reducer)) - reducer(result) - }) -) + reducer(result) + }) +)) -on_load( - async_reduce %<~% - async(function(.x, .f, ...) { - out <- NULL +on_load(delayedAssign( + "async_reduce", + async(function(.x, .f, ...) { + out <- NULL - while (TRUE) { - new <- await(.x()) + while (TRUE) { + new <- await(.x()) - if (is_exhausted(new)) { - break - } + if (is_exhausted(new)) { + break + } - out <- .f(out, new, ...) + out <- .f(out, new, ...) - # Return early if we get a reduced result - if (is_done_box(out)) { - return(unbox(out)) - } + # Return early if we get a reduced result + if (is_done_box(out)) { + return(unbox(out)) } + } - out - }) -) + out + }) +))