diff --git a/src/frame.rs b/src/frame.rs index 686f8f2adcb112caf85b0dc2728e2f537f5acb8d..e35e0aca68b034ba2a568387b97301d73a59bff3 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -1,5 +1,6 @@ use crate::callable::Callable; use crate::instruction::Instruction; +use crate::tvm::Tvm; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Frame { @@ -15,4 +16,14 @@ pub enum FrameData { Callable(Callable, Vec<i32>), // TODO: Maybe this should be a reference to the callable id? Instruction(Instruction, Vec<i32>), Primitive(i32), +} + +pub trait FrameEvaluator { + fn eval_frame(&mut self, frame: Frame); +} + +impl FrameEvaluator for Tvm { + fn eval_frame(&mut self, frame: Frame) { + println!("Evaluating frame: {:?}", frame); + } } \ No newline at end of file diff --git a/src/state.rs b/src/state.rs index fded70a6901a76ed8a4237dcf25a1d276b1afb2a..5bd6d5462a74180b929b85535eb57a12f700984f 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,10 +3,8 @@ use crate::callable::Callable; use crate::frame::Frame; use crate::tvm::Tvm; -pub trait State : Debug + Clone { - fn pause(&mut self); - fn resume(&mut self); - fn tick(&mut self) -> StateResult; +pub trait State : Debug { + fn tick(&mut self, tvm: &mut Tvm) -> StateResult; } #[derive(Debug, Clone, PartialEq, Eq)] @@ -26,13 +24,55 @@ pub enum TvmState { Halted, } +impl TvmState { + pub fn to_state(&self) -> Box<dyn State> { + match self { + TvmState::Waiting => Box::new(states::Waiting), + TvmState::Paused => Box::new(states::Paused), + TvmState::Call(callable) => Box::new(states::Call { callable: callable.clone() }), + TvmState::Eval(frame, pc) => Box::new(states::Eval { frame: frame.clone(), pc: *pc }), + TvmState::FrameEval(frame) => Box::new(states::FrameEval { frame: frame.clone() }), + TvmState::Halted => Box::new(states::Halted), + } + } + + pub fn is_waiting(&self) -> bool { + matches!(self, TvmState::Waiting) + } + + pub fn is_paused(&self) -> bool { + matches!(self, TvmState::Paused) + } + + pub fn is_call(&self) -> bool { + matches!(self, TvmState::Call(_)) + } + + pub fn is_eval(&self) -> bool { + matches!(self, TvmState::Eval(_, _)) + } + + pub fn is_frame_eval(&self) -> bool { + matches!(self, TvmState::FrameEval(_)) + } + + pub fn is_halted(&self) -> bool { + matches!(self, TvmState::Halted) + } +} + pub trait Stateful : Debug { fn get_state(&self) -> TvmState; fn set_state(&mut self, state: TvmState); fn get_ticks(&self) -> usize; fn increment_ticks(&mut self); fn previous_state(&self) -> Option<TvmState>; + fn pause(&mut self); + fn resume(&mut self); + fn tick(&mut self); + fn get_last_result(&self) -> Option<StateResult>; fn is_paused(&self) -> bool; + fn handle_result(&mut self, result: StateResult); } impl Stateful for Tvm { @@ -57,8 +97,95 @@ impl Stateful for Tvm { self.previous_state.clone() } + fn pause(&mut self) { + if !self.is_paused() { + self.set_state(TvmState::Paused); + } + } + + fn resume(&mut self) { + if self.is_paused() { + self.set_state(self.previous_state().unwrap()); + } + } + + fn tick(&mut self) { + + } + + fn get_last_result(&self) -> Option<StateResult> { + todo!() + } + fn is_paused(&self) -> bool { self.state == TvmState::Paused } + + fn handle_result(&mut self, result: StateResult) { + println!("Handling result: {:?}", result); + } } +pub mod states { + use super::*; + + #[derive(Debug, Clone)] + pub struct Waiting; + #[derive(Debug, Clone)] + pub struct Paused; + #[derive(Debug, Clone)] + pub struct Call { + pub callable: Callable, + } + #[derive(Debug, Clone)] + pub struct Eval { + pub frame: Frame, + pub pc: usize, + } + #[derive(Debug, Clone)] + pub struct FrameEval { + pub frame: Frame, + } + #[derive(Debug, Clone)] + pub struct Halted; + + impl State for Waiting { + // Tick should do nothing. + fn tick(&mut self, tvm: &mut Tvm) -> StateResult { + StateResult::Continue + } + } + + impl State for Paused { + // Tick should do nothing. + fn tick(&mut self, tvm: &mut Tvm) -> StateResult { + StateResult::Continue + } + } + + impl State for Call { + fn tick(&mut self, tvm: &mut Tvm) -> StateResult { + unimplemented!() + } + } + + impl State for Eval { + fn tick(&mut self, tvm: &mut Tvm) -> StateResult { + unimplemented!() + } + } + + impl State for FrameEval { + + fn tick(&mut self, tvm: &mut Tvm) -> StateResult { + unimplemented!() + } + } + + impl State for Halted { + + fn tick(&mut self, tvm: &mut Tvm) -> StateResult { + unimplemented!() + } + } +} diff --git a/src/tvm.rs b/src/tvm.rs index 8f1e08e2184bd8d420109b98d64bfe7d0cea2899..e670e383bfe137395860ebe768d7a666d4316b2a 100644 --- a/src/tvm.rs +++ b/src/tvm.rs @@ -1,5 +1,5 @@ use crate::frame::Frame; -use crate::state::{TvmState}; +use crate::state::{StateResult, TvmState}; #[derive(Debug, Clone)] pub struct Tvm { @@ -10,6 +10,7 @@ pub struct Tvm { pub state: TvmState, pub ticks: usize, pub previous_state: Option<TvmState>, + pub last_result: Option<StateResult>, } impl Default for Tvm { @@ -22,6 +23,7 @@ impl Default for Tvm { state: TvmState::Waiting, ticks: 0, previous_state: None, + last_result: None, } } }