Skip to content

Commit 29ee707

Browse files
committed
i don't know what this is
1 parent 5358f32 commit 29ee707

15 files changed

Lines changed: 134 additions & 235 deletions

File tree

cli/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ rpi = ["endbasic-rpi"]
1919

2020
[dependencies]
2121
anyhow = "1.0"
22-
async-channel = "2.2"
2322
dirs = "5.0"
2423
getopts = "0.2"
2524
thiserror = "1.0"

cli/src/main.rs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
#![warn(unsafe_code)]
2424

2525
use anyhow::{anyhow, Result};
26-
use async_channel::Sender;
27-
use endbasic_core::exec::Signal;
2826
use endbasic_std::console::Console;
2927
use endbasic_std::storage::Storage;
3028
use getopts::Options;
@@ -107,10 +105,8 @@ fn new_machine_builder(console_spec: Option<&str>) -> io::Result<endbasic_std::M
107105
builder
108106
}
109107

110-
let signals_chan = async_channel::unbounded();
111108
let mut builder = endbasic_std::MachineBuilder::default();
112-
builder = builder.with_console(setup_console(console_spec, signals_chan.0.clone())?);
113-
builder = builder.with_signals_chan(signals_chan);
109+
builder = builder.with_console(setup_console(console_spec)?);
114110
builder = add_gpio_pins(builder);
115111
Ok(builder)
116112
}
@@ -169,60 +165,49 @@ fn get_local_drive_spec(flag: Option<String>) -> Result<String> {
169165
}
170166

171167
/// Sets up the console.
172-
fn setup_console(
173-
console_spec: Option<&str>,
174-
signals_tx: Sender<Signal>,
175-
) -> io::Result<Rc<RefCell<dyn Console>>> {
168+
fn setup_console(console_spec: Option<&str>) -> io::Result<Rc<RefCell<dyn Console>>> {
176169
/// Creates the textual console when crossterm support is built in.
177170
#[cfg(feature = "crossterm")]
178-
fn setup_text_console(signals_tx: Sender<Signal>) -> io::Result<Rc<RefCell<dyn Console>>> {
179-
Ok(Rc::from(RefCell::from(endbasic_terminal::TerminalConsole::from_stdio(signals_tx)?)))
171+
fn setup_text_console() -> io::Result<Rc<RefCell<dyn Console>>> {
172+
Ok(Rc::from(RefCell::from(endbasic_terminal::TerminalConsole::from_stdio()?)))
180173
}
181174

182175
/// Creates the textual console with very basic features when crossterm support is not built in.
183176
#[cfg(not(feature = "crossterm"))]
184-
fn setup_text_console(_signals_tx: Sender<Signal>) -> io::Result<Rc<RefCell<dyn Console>>> {
177+
fn setup_text_console() -> io::Result<Rc<RefCell<dyn Console>>> {
185178
Ok(Rc::from(RefCell::from(endbasic_std::console::TrivialConsole::default())))
186179
}
187180

188181
/// Creates the graphical console when SDL support is built in.
189182
#[cfg(feature = "sdl")]
190-
pub fn setup_graphics_console(
191-
signals_tx: Sender<Signal>,
192-
spec: &str,
193-
) -> io::Result<Rc<RefCell<dyn Console>>> {
194-
endbasic_sdl::setup(spec, signals_tx)
183+
pub fn setup_graphics_console(spec: &str) -> io::Result<Rc<RefCell<dyn Console>>> {
184+
endbasic_sdl::setup(spec)
195185
}
196186

197187
/// Errors out during the creation of the graphical console when SDL support is not compiled in.
198188
#[cfg(not(feature = "sdl"))]
199-
pub fn setup_graphics_console(
200-
_signals_tx: Sender<Signal>,
201-
_spec: &str,
202-
) -> io::Result<Rc<RefCell<dyn Console>>> {
189+
pub fn setup_graphics_console(_spec: &str) -> io::Result<Rc<RefCell<dyn Console>>> {
203190
// TODO(jmmv): Make this io::ErrorKind::Unsupported when our MSRV allows it.
204191
Err(io::Error::new(io::ErrorKind::InvalidInput, "SDL support not compiled in"))
205192
}
206193

207194
#[cfg(feature = "rpi")]
208-
fn setup_st7735s_console(signals_tx: Sender<Signal>) -> io::Result<Rc<RefCell<dyn Console>>> {
209-
Ok(Rc::from(RefCell::from(endbasic_rpi::new_st7735s_console(signals_tx)?)))
195+
fn setup_st7735s_console() -> io::Result<Rc<RefCell<dyn Console>>> {
196+
Ok(Rc::from(RefCell::from(endbasic_rpi::new_st7735s_console()?)))
210197
}
211198

212199
#[cfg(not(feature = "rpi"))]
213-
pub fn setup_st7735s_console(
214-
_signals_tx: Sender<Signal>,
215-
) -> io::Result<Rc<RefCell<dyn Console>>> {
200+
pub fn setup_st7735s_console() -> io::Result<Rc<RefCell<dyn Console>>> {
216201
Err(io::Error::new(io::ErrorKind::InvalidInput, "ST7735S support not compiled in"))
217202
}
218203

219204
let console: Rc<RefCell<dyn Console>> = match console_spec {
220-
None | Some("text") => setup_text_console(signals_tx)?,
205+
None | Some("text") => setup_text_console()?,
221206

222-
Some("graphics") => setup_graphics_console(signals_tx, "")?,
223-
Some("st7735s") => setup_st7735s_console(signals_tx)?,
207+
Some("graphics") => setup_graphics_console("")?,
208+
Some("st7735s") => setup_st7735s_console()?,
224209
Some(text) if text.starts_with("graphics:") => {
225-
setup_graphics_console(signals_tx, &text["graphics:".len()..])?
210+
setup_graphics_console(&text["graphics:".len()..])?
226211
}
227212

228213
Some(text) => {

core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ readme = "README.md"
1212
edition = "2018"
1313

1414
[dependencies]
15-
async-channel = "2.2"
1615
async-trait = "0.1"
1716
thiserror = "1.0"
1817

core/examples/config.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ fn main() {
4747
StopReason::Exited(i, _is_final) => {
4848
println!("Script explicitly exited with code {}", i)
4949
}
50-
StopReason::Break(_is_final) => (), // Ignore signals.
5150
}
5251
}
5352

core/examples/dsl.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ fn main() {
157157
StopReason::Exited(i, _is_final) => {
158158
println!("Script explicitly exited with code {}", i)
159159
}
160-
StopReason::Break(_is_final) => (), // Ignore signals.
161160
}
162161
}
163162

core/src/exec.rs

Lines changed: 8 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ use crate::reader::LineCol;
2222
use crate::syms::{Callable, Symbol, SymbolKey, Symbols};
2323
use crate::value;
2424
use crate::value::double_to_integer;
25-
use async_channel::{Receiver, Sender, TryRecvError};
26-
use std::future::Future;
2725
use std::io;
28-
use std::pin::Pin;
2926
use 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)]
9080
pub 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

160143
impl 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.
189161
pub 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)]
613586
pub 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

626591
impl 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() {

repl/src/lib.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ pub mod editor;
3636
/// Message to print on the console when receiving a break signal.
3737
const BREAK_MSG: &str = "**** BREAK ****";
3838

39+
/*
40+
/// Type of the function used by the execution loop to yield execution.
41+
pub type YieldNowFn = Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()> + 'static>>>;
42+
43+
/// Consumes any pending signals so that they don't interfere with an upcoming execution.
44+
pub fn drain_signals(&mut self) {
45+
while self.signals_chan.1.try_recv().is_ok() {
46+
// Do nothing.
47+
}
48+
}
49+
50+
/// Returns true if execution should stop because we have hit a stop condition.
51+
pub async fn should_stop(&mut self) -> bool {
52+
if let Some(yield_now) = self.yield_now_fn.as_ref() {
53+
(yield_now)().await;
54+
}
55+
56+
match self.signals_chan.1.try_recv() {
57+
Ok(Signal::Break) => true,
58+
Err(TryRecvError::Empty) => false,
59+
Err(TryRecvError::Closed) => panic!("Channel unexpectedly closed"),
60+
}
61+
}
62+
*/
63+
3964
/// Prints the EndBASIC welcome message to the given console.
4065
pub fn print_welcome(console: Rc<RefCell<dyn Console>>) -> io::Result<()> {
4166
let mut console = console.borrow_mut();
@@ -140,10 +165,12 @@ pub async fn run_from_cloud(
140165
console.print(&format!("**** Program exited with code {} ****", code))?;
141166
code
142167
}
168+
/* DO NOT SUBMIT
143169
Ok(r @ StopReason::Break(_is_final)) => {
144170
console.print("**** Program stopped due to BREAK ****")?;
145171
r.as_exit_code()
146172
}
173+
*/
147174
Err(e) => {
148175
console.print(&format!("**** ERROR: {} ****", e))?;
149176
1
@@ -191,7 +218,9 @@ pub async fn run_repl_loop(
191218

192219
// Any signals entered during console input should not impact upcoming execution. Drain
193220
// them all.
194-
machine.drain_signals();
221+
// DO NOT SUBMIT
222+
//machine.drain_signals();
223+
let _ = console.borrow_mut().take_signal().await;
195224

196225
match line {
197226
Ok(line) => {
@@ -206,9 +235,11 @@ pub async fn run_repl_loop(
206235

207236
loop {
208237
match machine.resume(&mut context).await {
209-
Ok(InternalStopReason::CheckStop(is_final)) => {
210-
if machine.should_stop().await {
211-
stop_reason = StopReason::Break(is_final);
238+
Ok(InternalStopReason::CheckStop(_is_final)) => {
239+
let mut console = console.borrow_mut();
240+
if console.take_signal().await.is_some() {
241+
console.print("**** BREAK ****")?;
242+
stop_reason = StopReason::Eof;
212243
break;
213244
}
214245
}
@@ -254,10 +285,6 @@ pub async fn run_repl_loop(
254285

255286
match stop_reason {
256287
StopReason::Eof => (),
257-
StopReason::Break(_is_final) => {
258-
console.borrow_mut().print("**** BREAK ****")?;
259-
stop_reason = StopReason::Eof;
260-
}
261288
StopReason::Exited(_, false) => {
262289
console
263290
.borrow_mut()

0 commit comments

Comments
 (0)