aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs99
1 files changed, 89 insertions, 10 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 95ac4c8..86de7e3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -10,7 +10,7 @@ impl State {
#[inline(always)]
pub fn exit_action(&self) -> Action {
unsafe {
- *::table::EXIT_ACTIONS.get_unchecked(*self as usize)
+ *EXIT_ACTIONS.get_unchecked(*self as usize)
}
}
@@ -18,20 +18,99 @@ impl State {
#[inline(always)]
pub fn entry_action(&self) -> Action {
unsafe {
- *::table::ENTRY_ACTIONS.get_unchecked(*self as usize)
+ *ENTRY_ACTIONS.get_unchecked(*self as usize)
}
}
}
-// struct StateMachine<P: Parser> {
-// state: State,
-// }
-//
-// trait Parser {
-// fn csi_entry(&mut self, c: char);
-// fn csi_param(&mut self, c: char);
-// }
+pub struct StateMachine<P: Parser> {
+ state: State,
+ parser: P,
+}
+
+impl<P: Parser> StateMachine<P> {
+ pub fn advance(&mut self, byte: u8) {
+ // Handle state changes in the anywhere state before evaluating changes
+ // for current state.
+ let mut change = STATE_CHANGE[State::Anywhere as usize][byte as usize];
+ if change == 0 {
+ change = STATE_CHANGE[self.state as usize][byte as usize];
+ }
+
+ // Unpack into a state and action
+ let (state, action) = unpack(change);
+
+ self.perform_state_change(state, action, byte);
+ }
+
+ fn perform_state_change(&mut self, state: State, action: Action, byte: u8) {
+ macro_rules! maybe_action {
+ ($action:expr, $arg:expr) => {
+ match $action {
+ Action::None | Action::Unused__ => (),
+ action => {
+ self.perform_action(action, $arg);
+ },
+ }
+ }
+ }
+
+ match state {
+ State::Anywhere | State::Unused__ => {
+ // Just run the action
+ self.perform_action(action, byte);
+ },
+ state => {
+ // Exit action for previous state
+ let exit_action = self.state.exit_action();
+ maybe_action!(exit_action, 0);
+
+ // Transition action
+ maybe_action!(action, byte);
+
+ // Entry action for new state
+ maybe_action!(state.entry_action(), 0);
+
+ // Assume the new state
+ self.state = state;
+ }
+ }
+ }
+
+ /// XXX I don't think this handles UTF-8 properly. Hmm...
+ fn perform_action(&mut self, action: Action, byte: u8) {
+ unimplemented!();
+
+ match action {
+ Action::Execute => self.parser.execute(byte),
+ Action::Hook => self.parser.hook(byte),
+ Action::Put => self.parser.put(byte),
+ Action::OscStart => self.parser.osc_start(byte),
+ Action::OscPut => self.parser.osc_put(byte),
+ Action::OscEnd => self.parser.osc_end(byte),
+ Action::Unhook => self.parser.unhook(byte),
+ Action::CsiDispatch => self.parser.csi_dispatch(byte),
+ Action::EscDispatch => self.parser.esc_dispatch(byte),
+ Action::Ignore | Action::None | Action::Unused__=> (),
+ Action::Collect => {
+ unimplemented!();
+ },
+ Action::Param => {
+ unimplemented!();
+ },
+ Action::Clear => {
+ unimplemented!();
+ }
+ }
+ }
+}
+
+pub trait Parser {
+ fn csi_entry(&mut self, byte: u8);
+ fn csi_param(&mut self, byte: u8);
+}
+
//
// struct Foo;
//