@@ -22,10 +22,7 @@ use crate::reader::LineCol;
2222use crate :: syms:: { Callable , Symbol , SymbolKey , Symbols } ;
2323use crate :: value;
2424use crate :: value:: double_to_integer;
25- use async_channel:: { Receiver , Sender , TryRecvError } ;
26- use std:: future:: Future ;
2725use std:: io;
28- use std:: pin:: Pin ;
2926use std:: rc:: Rc ;
3027
3128/// Execution errors.
@@ -78,13 +75,6 @@ fn new_syntax_error<T, S: Into<String>>(pos: LineCol, message: S) -> Result<T> {
7875 Err ( Error :: SyntaxError ( pos, message. into ( ) ) )
7976}
8077
81- /// Signals that can be delivered to the machine.
82- #[ derive( Clone , Debug , Eq , PartialEq ) ]
83- pub enum Signal {
84- /// Asks the machine to stop execution of the currently-running program.
85- Break ,
86- }
87-
8878/// Request to exit the VM execution loop to execute a native command or function.
8979#[ derive( Clone , Debug , Eq , PartialEq ) ]
9080pub struct UpcallData {
@@ -148,13 +138,6 @@ pub enum StopReason {
148138 /// nested invocation triggered by `RUN` so the caller may want to capture the stop and print a
149139 /// message instead of exiting.
150140 Exited ( u8 , bool ) ,
151-
152- /// Execution terminated because the machine received a break signal.
153- ///
154- /// The boolean indicates whether this stop is final. If false, the stop request comes from
155- /// cancelling the execution of a nested `RUN` so the caller may want to capture the stop and
156- /// print a message instead of exiting.
157- Break ( bool ) ,
158141}
159142
160143impl StopReason {
@@ -163,14 +146,6 @@ impl StopReason {
163146 match self {
164147 StopReason :: Eof => 0 ,
165148 StopReason :: Exited ( i, _is_final) => * i as i32 ,
166- StopReason :: Break ( _is_final) => {
167- // This mimics the behavior of typical Unix shells, which translate a signal to a
168- // numerical exit code, but this is not accurate. First, because a CTRL+C sequence
169- // should be exposed as a SIGINT signal to whichever process is waiting for us, and
170- // second because this is not meaningful on Windows. But for now this will do.
171- const SIGINT : i32 = 2 ;
172- 128 + SIGINT
173- }
174149 }
175150 }
176151}
@@ -182,9 +157,6 @@ pub trait Clearable {
182157 fn reset_state ( & self , syms : & mut Symbols ) ;
183158}
184159
185- /// Type of the function used by the execution loop to yield execution.
186- pub type YieldNowFn = Box < dyn Fn ( ) -> Pin < Box < dyn Future < Output = ( ) > + ' static > > > ;
187-
188160/// Tags used in the value stack to identify the type of their corresponding value.
189161pub enum ValueTag {
190162 /// Represents that there is no next value to consume. Can only appear for command invocations.
@@ -610,39 +582,13 @@ impl From<Image> for Context {
610582}
611583
612584/// Executes an EndBASIC program and tracks its state.
585+ #[ derive( Default ) ]
613586pub struct Machine {
614587 symbols : Symbols ,
615588 clearables : Vec < Box < dyn Clearable > > ,
616- yield_now_fn : Option < YieldNowFn > ,
617- signals_chan : ( Sender < Signal > , Receiver < Signal > ) ,
618- }
619-
620- impl Default for Machine {
621- fn default ( ) -> Self {
622- Self :: with_signals_chan_and_yield_now_fn ( async_channel:: unbounded ( ) , None )
623- }
624589}
625590
626591impl Machine {
627- /// Constructs a new empty machine with the given signals communication channel.
628- pub fn with_signals_chan ( signals : ( Sender < Signal > , Receiver < Signal > ) ) -> Self {
629- Self :: with_signals_chan_and_yield_now_fn ( signals, None )
630- }
631-
632- /// Constructs a new empty machine with the given signals communication channel and yielding
633- /// function.
634- pub fn with_signals_chan_and_yield_now_fn (
635- signals : ( Sender < Signal > , Receiver < Signal > ) ,
636- yield_now_fn : Option < YieldNowFn > ,
637- ) -> Self {
638- Self {
639- symbols : Symbols :: default ( ) ,
640- clearables : vec ! [ ] ,
641- yield_now_fn,
642- signals_chan : signals,
643- }
644- }
645-
646592 /// Registers the given clearable.
647593 ///
648594 /// In the common case, functions and commands hold a reference to the out-of-machine state
@@ -658,11 +604,6 @@ impl Machine {
658604 self . symbols . add_callable ( callable)
659605 }
660606
661- /// Obtains a channel via which to send signals to the machine during execution.
662- pub fn get_signals_tx ( & self ) -> Sender < Signal > {
663- self . signals_chan . 0 . clone ( )
664- }
665-
666607 /// Resets the state of the machine by clearing all variable.
667608 pub fn clear ( & mut self ) {
668609 for clearable in self . clearables . as_slice ( ) {
@@ -681,19 +622,6 @@ impl Machine {
681622 & mut self . symbols
682623 }
683624
684- /// Returns true if execution should stop because we have hit a stop condition.
685- pub async fn should_stop ( & mut self ) -> bool {
686- if let Some ( yield_now) = self . yield_now_fn . as_ref ( ) {
687- ( yield_now) ( ) . await ;
688- }
689-
690- match self . signals_chan . 1 . try_recv ( ) {
691- Ok ( Signal :: Break ) => true ,
692- Err ( TryRecvError :: Empty ) => false ,
693- Err ( TryRecvError :: Closed ) => panic ! ( "Channel unexpectedly closed" ) ,
694- }
695- }
696-
697625 /// Handles an array assignment.
698626 fn assign_array (
699627 & mut self ,
@@ -760,13 +688,6 @@ impl Machine {
760688 Ok ( ( ) )
761689 }
762690
763- /// Consumes any pending signals so that they don't interfere with an upcoming execution.
764- pub fn drain_signals ( & mut self ) {
765- while self . signals_chan . 1 . try_recv ( ) . is_ok ( ) {
766- // Do nothing.
767- }
768- }
769-
770691 /// Tells the machine to stop execution at the next statement boundary.
771692 fn end ( & mut self , context : & mut Context , has_code : bool ) -> Result < InternalStopReason > {
772693 let code = if has_code {
@@ -1630,14 +1551,13 @@ impl Machine {
16301551 }
16311552
16321553 /// Executes the instructions in `context` through completion.
1554+ ///
1555+ /// This execution loop is _not_ interruptible. If the caller wants to respect stop signals,
1556+ /// the caller must use `resume()` instead.
16331557 pub async fn exec ( & mut self , context : & mut Context ) -> Result < StopReason > {
16341558 loop {
16351559 match self . resume ( context) . await ? {
1636- InternalStopReason :: CheckStop ( is_final) => {
1637- if self . should_stop ( ) . await {
1638- return Ok ( StopReason :: Break ( is_final) ) ;
1639- }
1640- }
1560+ InternalStopReason :: CheckStop ( _is_final) => ( ) ,
16411561
16421562 InternalStopReason :: Upcall ( data) => {
16431563 self . handle_upcall ( context, & data) . await ?;
@@ -2317,6 +2237,8 @@ mod tests {
23172237 assert_eq ! ( & [ "2" ] , captured_out. borrow( ) . as_slice( ) ) ;
23182238 }
23192239
2240+ /* DO NOT SUBMIT
2241+
23202242 #[tokio::test]
23212243 async fn test_signals_stop() {
23222244 let mut machine = Machine::default();
@@ -2421,6 +2343,7 @@ mod tests {
24212343 do_check_stop_test("WHILE TRUE: WEND").await;
24222344 do_check_stop_test("WHILE TRUE: a = 1: WEND").await;
24232345 }
2346+ */
24242347
24252348 #[ test]
24262349 fn test_do_infinite_ok ( ) {
0 commit comments