use crate::rule::Rule;
use rstm_core::{Direction, Head, Symbol, Tail};
use rstm_state::{RawState, State};
pub trait Scope<Q, S>
where
Q: RawState,
{
fn current_state(&self) -> &State<Q>;
fn current_symbol(&self) -> &S;
}
pub trait Directive<Q, S>
where
Q: RawState,
{
fn direction(&self) -> Direction;
fn next_state(&self) -> &State<Q>;
fn next_symbol(&self) -> &S;
}
pub trait Instruction<Q, S>
where
Q: RawState,
{
fn direction(&self) -> Direction;
fn current_state(&self) -> &State<Q>;
fn next_state(&self) -> &State<Q>;
fn symbol(&self) -> &S;
fn write_symbol(&self) -> &S;
fn head(&self) -> Head<&Q, &S> {
Head {
state: self.current_state().view(),
symbol: self.symbol(),
}
}
fn tail(&self) -> Tail<&Q, &S> {
Tail {
direction: self.direction(),
next_state: self.next_state().view(),
write_symbol: self.write_symbol(),
}
}
fn as_rule(&self) -> Rule<&Q, &S> {
Rule {
head: self.head(),
tail: self.tail(),
}
}
}
impl<A, Q, S> Instruction<Q, S> for A
where
A: Scope<Q, S> + Directive<Q, S>,
Q: RawState,
S: Symbol,
{
fn direction(&self) -> Direction {
self.direction()
}
fn current_state(&self) -> &State<Q> {
self.current_state()
}
fn next_state(&self) -> &State<Q> {
self.next_state()
}
fn symbol(&self) -> &S {
self.current_symbol()
}
fn write_symbol(&self) -> &S {
self.next_symbol()
}
}
impl<Q, S> Scope<Q, S> for (State<Q>, S)
where
Q: RawState,
{
fn current_state(&self) -> &State<Q> {
&self.0
}
fn current_symbol(&self) -> &S {
&self.1
}
}
impl<Q, S> Scope<Q, S> for Head<Q, S>
where
Q: RawState,
{
fn current_state(&self) -> &State<Q> {
self.state()
}
fn current_symbol(&self) -> &S {
&self.symbol
}
}
impl<Q, S> Scope<Q, S> for Rule<Q, S>
where
Q: RawState,
{
fn current_state(&self) -> &State<Q> {
self.state()
}
fn current_symbol(&self) -> &S {
self.symbol()
}
}
impl<Q, S> Directive<Q, S> for (Direction, State<Q>, S)
where
Q: RawState,
{
fn direction(&self) -> Direction {
self.0
}
fn next_state(&self) -> &State<Q> {
&self.1
}
fn next_symbol(&self) -> &S {
&self.2
}
}
impl<Q, S> Directive<Q, S> for Tail<Q, S>
where
Q: RawState,
{
fn direction(&self) -> Direction {
self.direction
}
fn next_state(&self) -> &State<Q> {
self.state()
}
fn next_symbol(&self) -> &S {
self.symbol()
}
}
impl<Q, S> Directive<Q, S> for Rule<Q, S>
where
Q: RawState,
{
fn direction(&self) -> Direction {
self.direction()
}
fn next_state(&self) -> &State<Q> {
self.tail().state()
}
fn next_symbol(&self) -> &S {
self.write_symbol()
}
}