Skip to content

Commit

Permalink
refactor: pull out Interpreter struct
Browse files Browse the repository at this point in the history
  • Loading branch information
justinpombrio committed Apr 11, 2024
1 parent cd302bd commit d92c247
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 51 deletions.
59 changes: 37 additions & 22 deletions src/editor/app.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use super::interpreter::Interpreter;
use super::runtime::Runtime;
use super::stack::{CallStack, DataStack, Op, Prog};
use super::EditorError;
use crate::engine::Engine;
use crate::frontends::{Event, Frontend, Key, MouseEvent};
use crate::style::Style;
use crate::util::SynlessBug;
use partial_pretty_printer::pane;
use std::time::Duration;

/*
Expand Down Expand Up @@ -33,47 +35,35 @@ use std::time::Duration;
*/

struct App<F: Frontend<Style = Style>> {
runtime: Runtime<F>,
call_stack: CallStack,
data_stack: DataStack,
runtime: Runtime,
frontend: F,
interpreter: Interpreter,
}

impl<F: Frontend<Style = Style>> App<F> {
pub fn run_event_loop(&mut self) {
loop {
if let Err(err) = self.runtime.display() {
if let Err(err) = self.display() {
self.abort(err);
}
let prog = match self.block_on_input() {
Ok(prog) => prog,
Err(err) => self.abort(err),
};
match self.execute(prog) {
Ok(()) => (),
match self.interpreter.execute(&mut self.runtime, prog) {
Ok(_) => (),
Err(err) => self.runtime.engine.report_error(&err),
}
}
}

fn execute(&mut self, prog: Prog) -> Result<(), EditorError> {
self.call_stack.push(prog);
while let Some(op) = self.call_stack.pop() {
if op == Op::Block {
return Ok(());
} else {
self.call(op)?;
}
}
Ok(())
}

fn block_on_input(&mut self) -> Result<Prog, EditorError> {
use std::str::FromStr;

let ctrl_c = Key::from_str("C-c").bug();

loop {
match self.runtime.next_event()? {
match self.next_event()? {
// TODO: Remove Ctrl-c. It's only for testing.
Event::Key(ctrl_c) => return Err(EditorError::KeyboardInterrupt),
Event::Key(key) => {
Expand All @@ -82,20 +72,45 @@ impl<F: Frontend<Style = Style>> App<F> {
}
// wait for a better key press
}
Event::Resize => self.runtime.display()?,
Event::Resize => self.display()?,
Event::Mouse(_) => (),
Event::Paste(_) => (), // TODO: OS paste support
}
}
}

fn call(&mut self, op: Op) -> Result<(), EditorError> {
todo!()
/// Block until the next input event.
fn next_event(&mut self) -> Result<Event, EditorError> {
loop {
match self.frontend.next_event(Duration::from_secs(1)) {
Ok(None) => (), // continue waiting
Ok(Some(event)) => return Ok(event),
Err(err) => return Err(EditorError::FrontendError(Box::new(err))),
}
}
}

fn abort(&mut self, err: EditorError) -> ! {
self.runtime.engine.report_error(&err);
// TODO: Save the error log, and maybe the docs
panic!("{}", err);
}

pub fn display(&mut self) -> Result<(), EditorError> {
self.frontend
.start_frame()
.map_err(|err| EditorError::FrontendError(Box::new(err)))?;

let get_content = |doc_label| self.runtime.engine.get_content(doc_label);
pane::display_pane(
&mut self.frontend,
&self.runtime.pane_notation,
&get_content,
)
.map_err(|err| EditorError::PaneError(Box::new(err)))?;

self.frontend
.end_frame()
.map_err(|err| EditorError::FrontendError(Box::new(err)))
}
}
33 changes: 33 additions & 0 deletions src/editor/interpreter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::runtime::Runtime;
use super::stack::{CallStack, DataStack, Op, Prog};
use super::EditorError;

#[derive(Debug, Default)]
pub struct Interpreter {
call_stack: CallStack,
data_stack: DataStack,
}

impl Interpreter {
pub fn new() -> Interpreter {
Interpreter::default()
}

/// Execute the program. Returns `Ok(true)` if it halted from a `Block` op,
/// and `Ok(false)` if it halted from hitting the end of the program.
pub fn execute(&mut self, r: &mut Runtime, prog: Prog) -> Result<bool, EditorError> {
self.call_stack.push(prog);
while let Some(op) = self.call_stack.pop() {
if op == Op::Block {
return Ok(true);
} else {
self.call(r, op)?;
}
}
Ok(false)
}

fn call(&mut self, r: &mut Runtime, op: Op) -> Result<(), EditorError> {
todo!()
}
}
2 changes: 2 additions & 0 deletions src/editor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod app;
mod interpreter;
mod keymap;
mod layer;
mod runtime;
Expand All @@ -9,6 +10,7 @@ use crate::frontends::Frontend;
use std::error::Error;
use std::fmt;

// TODO: Is this InterpreterError, AppError, a mix of both?
#[derive(thiserror::Error, fmt::Debug)]
pub enum EditorError {
#[error("Error from the document engine")]
Expand Down
34 changes: 5 additions & 29 deletions src/editor/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::layer::LayerManager;
use super::stack::Prog;
use super::EditorError;
use crate::engine::{DocDisplayLabel, Engine};
Expand All @@ -8,38 +9,13 @@ use partial_pretty_printer::pane;
use std::error::Error;
use std::time::Duration;

pub struct Runtime<F: Frontend<Style = Style>> {
pub struct Runtime {
pub engine: Engine,
pane_notation: pane::PaneNotation<DocDisplayLabel, Style>,
frontend: F,
pub pane_notation: pane::PaneNotation<DocDisplayLabel, Style>,
layer_manager: LayerManager,
}

impl<F: Frontend<Style = Style>> Runtime<F> {
/// Block until the next input event.
pub fn next_event(&mut self) -> Result<Event, EditorError> {
loop {
match self.frontend.next_event(Duration::from_secs(1)) {
Ok(None) => (), // continue waiting
Ok(Some(event)) => return Ok(event),
Err(err) => return Err(EditorError::FrontendError(Box::new(err))),
}
}
}

pub fn display(&mut self) -> Result<(), EditorError> {
self.frontend
.start_frame()
.map_err(|err| EditorError::FrontendError(Box::new(err)))?;

let get_content = |doc_label| self.engine.get_content(doc_label);
pane::display_pane(&mut self.frontend, &self.pane_notation, &get_content)
.map_err(|err| EditorError::PaneError(Box::new(err)))?;

self.frontend
.end_frame()
.map_err(|err| EditorError::FrontendError(Box::new(err)))
}

impl Runtime {
pub fn lookup_key(&self, key: Key) -> Option<Prog> {
// TODO: must handle char insertion in text mode
todo!()
Expand Down
3 changes: 3 additions & 0 deletions src/editor/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use super::EditorError;
use crate::util::SynlessBug;
use std::fmt;

#[derive(Debug, Default)]
pub struct DataStack(Vec<Value>);

#[derive(Debug, Default)]
pub struct CallStack(Vec<Prog>);

// Executes the last op first
Expand Down

0 comments on commit d92c247

Please sign in to comment.