use crate::instructions::Instruction;
use crate::{Alphabet, Program, Scope, State, Symbolic};
use async_trait::async_trait;
use contained_core::{states::Stateful, Error};
use futures::{Future, StreamExt};
use predicates::Predicate;
use std::sync::{Arc, Mutex};
#[async_trait]
pub trait AsyncExecute<S: Symbolic + Send + Sync>:
Alphabet<S> + StreamExt<Item = Instruction<S>> + Stateful<State> + Unpin
{
type Driver: Future + Scope<S> + Send + Sync;
type Error: Send + Sync;
async fn execute(&mut self) -> Result<&Arc<Mutex<Self::Driver>>, Self::Error> {
let default_symbol = self.clone().default_symbol();
while let Some(instruction) = self.next().await {
let tail = instruction.clone().tail();
self.update_state(tail.state());
self.scope_mut().lock().unwrap().set_symbol(tail.symbol());
self.scope_mut()
.lock()
.unwrap()
.shift(tail.action(), default_symbol.clone());
}
Ok(self.scope())
}
fn scope(&self) -> &Arc<Mutex<Self::Driver>>;
fn scope_mut(&mut self) -> &mut Arc<Mutex<Self::Driver>>;
}
pub trait Execute<S: Symbolic>:
Alphabet<S> + Iterator<Item = Instruction<S>> + Stateful<State>
{
type Driver: Scope<S>;
fn execute(&mut self) -> Result<&Self::Driver, Error> {
let default_symbol = self.program().default_symbol();
while let Some(instruction) = self.next() {
let tail = instruction.clone().tail();
self.update_state(tail.state());
self.scope_mut().set_symbol(tail.symbol());
self.scope_mut()
.shift(tail.action(), default_symbol.clone());
}
Ok(self.scope())
}
fn execute_once(&mut self) -> Result<&Self::Driver, Error> {
let default_symbol = self.clone().default_symbol();
if let Some(instruction) = self.next() {
let tail = instruction.tail();
self.update_state(tail.state());
self.scope_mut().set_symbol(tail.symbol());
self.scope_mut().shift(tail.action(), default_symbol);
return Ok(self.scope());
}
Err(Error::ExecutionError(
"No more instructions to execute".into(),
))
}
fn execute_until(
&mut self,
until: impl Predicate<Self::Driver>,
) -> Result<&Self::Driver, Error> {
while !until.eval(self.scope()) {
self.execute_once()?;
}
Ok(self.scope())
}
fn program(&self) -> &Program<S>;
fn scope(&self) -> &Self::Driver;
fn scope_mut(&mut self) -> &mut Self::Driver;
}
pub trait Executable<S: Symbolic>: Clone + Alphabet<S> + Iterator<Item = Instruction<S>> {
type Driver: Scope<S>;
type Error;
fn execute(&mut self, driver: &mut Self::Driver) -> Result<Self::Driver, Self::Error> {
let default_symbol = self.clone().default_symbol();
for instruction in self.by_ref() {
let tail = instruction.clone().tail();
driver.update_state(tail.state());
driver.set_symbol(tail.symbol());
driver.shift(tail.action(), default_symbol.clone());
}
Ok(driver.clone())
}
fn execute_once(&mut self, driver: &mut Self::Driver) -> Result<Self::Driver, Self::Error> {
let default_symbol = self.clone().default_symbol();
if let Some(instruction) = self.next() {
let tail = instruction.tail();
driver.update_state(tail.state());
driver.set_symbol(tail.symbol());
driver.shift(tail.action(), default_symbol);
}
Ok(driver.clone())
}
fn execute_until(
&mut self,
driver: &mut Self::Driver,
until: impl Predicate<Self::Driver>,
) -> Result<Self::Driver, Self::Error> {
let default_symbol = self.clone().default_symbol();
for instruction in self.by_ref() {
let tail = instruction.clone().tail();
driver.update_state(tail.state());
driver.set_symbol(tail.symbol());
driver.shift(tail.action(), default_symbol.clone());
if until.eval(driver) {
break;
}
}
Ok(driver.clone())
}
}