@@ -309,7 +309,8 @@ pub struct RMain {
309309 /// consoles to get R to shut down
310310 read_console_shutdown : Cell < bool > ,
311311
312- /// Current topmost environment on the stack while waiting for input in ReadConsole
312+ /// Current topmost environment on the stack while waiting for input in ReadConsole.
313+ /// This is a RefCell since we require `get()` for this field and `RObject` isn't `Copy`.
313314 pub ( crate ) read_console_frame : RefCell < RObject > ,
314315}
315316
@@ -344,7 +345,6 @@ impl PendingInputs {
344345 let status = match harp:: parse_status ( & input) {
345346 Err ( err) => {
346347 // Failed to even attempt to parse the input, something is seriously wrong
347- // FIXME: There are some valid syntax errors going through here, e.g. `identity |> _(1)`.
348348 return Ok ( ParseResult :: SyntaxError ( format ! ( "{err}" ) ) ) ;
349349 } ,
350350 Ok ( status) => status,
@@ -353,7 +353,7 @@ impl PendingInputs {
353353 // - Incomplete inputs put R into a state where it expects more input that will never come, so we
354354 // immediately reject them. Positron should never send us these, but Jupyter Notebooks may.
355355 // - Complete statements are obviously fine.
356- // - Syntax errors will cause R to throw an error, which is expected .
356+ // - Syntax errors will get bubbled up as R errors via an `ConsoleResult::Error` .
357357 let exprs = match status {
358358 harp:: ParseResult :: Complete ( exprs) => exprs,
359359 harp:: ParseResult :: Incomplete => {
@@ -793,6 +793,7 @@ impl RMain {
793793 read_console_nested_return : Cell :: new ( false ) ,
794794 read_console_threw_error : Cell :: new ( false ) ,
795795 read_console_nested_return_next_input : Cell :: new ( None ) ,
796+ // Can't use `R_ENVS.global` here as it isn't initialised yet
796797 read_console_frame : RefCell :: new ( RObject :: new ( unsafe { libr:: R_GlobalEnv } ) ) ,
797798 read_console_shutdown : Cell :: new ( false ) ,
798799 }
@@ -956,16 +957,17 @@ impl RMain {
956957 // Clear any pending inputs, if any
957958 self . pending_inputs = None ;
958959
959- // Reply to active request with error
960+ // Reply to active request with error, then fall through to event loop
960961 self . handle_active_request ( & info, ConsoleValue :: Error ( exception) ) ;
961962 } else if matches ! ( info. kind, PromptKind :: InputRequest ) {
962- // Request input reply to the frontend and return it to R
963+ // Request input from the frontend and return it to R
963964 return self . handle_input_request ( & info, buf, buflen) ;
964965 } else if let Some ( input) = self . pop_pending ( ) {
965966 // Evaluate pending expression if there is any remaining
966967 return self . handle_pending_input ( input, buf, buflen) ;
967968 } else {
968- // Otherwise reply to active request with accumulated result
969+ // Otherwise reply to active request with accumulated result, then
970+ // fall through to event loop
969971 let result = self . take_result ( ) ;
970972 self . handle_active_request ( & info, ConsoleValue :: Success ( result) ) ;
971973 }
@@ -1029,12 +1031,12 @@ impl RMain {
10291031 let tasks_interrupt_index = select. recv ( & tasks_interrupt_rx) ;
10301032 let polled_events_index = select. recv ( & polled_events_rx) ;
10311033
1032- // Don't process idle tasks unless at top level. We currently don't want
1033- // idle tasks (e.g. for srcref generation) to run when the call stack is
1034- // not empty. We could make this configurable though if needed, i.e. some
1035- // idle tasks would be able to run in the browser. Those should be sent
1036- // to a dedicated channel that would always be included in the set of
1037- // recv channels.
1034+ // Only process idle at top level. We currently don't want idle tasks
1035+ // (e.g. for srcref generation) to run when the call stack is not empty.
1036+ // We could make this configurable though if needed, i.e. some idle
1037+ // tasks would be able to run in the browser. Those should be sent to a
1038+ // dedicated channel that would always be included in the set of recv
1039+ // channels.
10381040 let tasks_idle_index = if matches ! ( info. kind, PromptKind :: TopLevel ) {
10391041 Some ( select. recv ( & tasks_idle_rx) )
10401042 } else {
@@ -1175,8 +1177,7 @@ impl RMain {
11751177
11761178 if autoprint. ends_with ( '\n' ) {
11771179 // Remove the trailing newlines that R adds to outputs but that
1178- // Jupyter frontends are not expecting. Is it worth taking a
1179- // mutable self ref across calling methods to avoid the clone?
1180+ // Jupyter frontends are not expecting
11801181 autoprint. pop ( ) ;
11811182 }
11821183 if autoprint. len ( ) != 0 {
@@ -1249,9 +1250,6 @@ impl RMain {
12491250 Some ( exception)
12501251 }
12511252
1252- /// Returns:
1253- /// - `None` if we should fall through to the event loop to wait for more user input
1254- /// - `Some(ConsoleResult)` if we should immediately exit `read_console()`
12551253 fn handle_active_request ( & mut self , info : & PromptInfo , value : ConsoleValue ) {
12561254 // If we get here we finished evaluating all pending inputs. Check if we
12571255 // have an active request from a previous `read_console()` iteration. If
@@ -2423,7 +2421,8 @@ pub extern "C-unwind" fn r_read_console(
24232421 }
24242422
24252423 // We've finished evaluating a dummy value to reset state in R's REPL,
2426- // and are now ready to evaluate the actual input
2424+ // and are now ready to evaluate the actual input, which is typically
2425+ // just `.ark_last_value`.
24272426 if let Some ( next_input) = main. read_console_nested_return_next_input . take ( ) {
24282427 RMain :: on_console_input ( buf, buflen, next_input) . unwrap ( ) ;
24292428 return 1 ;
0 commit comments