Started creating FSM builder

This commit is contained in:
AlexanderHD27
2025-05-31 02:10:42 +02:00
parent bfb7851c7b
commit e8b0811a9e
5 changed files with 579 additions and 8 deletions

199
src/configotron/fsm.rs Normal file
View File

@@ -0,0 +1,199 @@
use std::{cell::RefCell, rc::{Weak, Rc}};
pub struct FSM {
states: Vec<Rc<RefCell<FSMState>>>
}
impl FSM {
pub fn new(state: Vec<Rc<RefCell<FSMState>>>) -> Self {
FSM {states: state}
}
}
#[derive(Debug, Clone, Copy)]
pub enum FSMStateAction {
NONE, TERMINAL
}
#[derive(Debug, Clone)]
pub struct FSMState {
name: String,
action: FSMStateAction,
transition: Option<FSMTranistion>
}
#[derive(Debug, Clone)]
pub struct FSMTranistion {
array: [Weak<RefCell<FSMState>>; 128],
}
impl FSMState {
pub fn new(name: String, action: FSMStateAction) -> Self {
FSMState { name: name, action: action, transition: None }
}
pub fn set_transitions(&mut self, t: FSMTranistion) {
self.transition = Some(t);
}
}
impl FSMTranistion {
pub fn new_from_mask(mask: TransitionMask, pos: Weak<RefCell<FSMState>>, default: Weak<RefCell<FSMState>>) -> Self {
let mut array: [Weak<RefCell<FSMState>>; 128] = std::array::from_fn(|_| Weak::clone(&default));
for i in 0..128 {
if mask.get_bit(i) {
array[i] = Weak::clone(&pos );
}
}
FSMTranistion { array }
}
pub fn new(mask: TransitionMask, default: Weak<RefCell<FSMState>>) -> Self {
let mut array: [Weak<RefCell<FSMState>>; 128] = std::array::from_fn(|_| Weak::clone(&default));
FSMTranistion { array }
}
pub fn apply(&mut self, mask: TransitionMask, state: Weak<RefCell<FSMState>>) {
for i in 0..128 {
if mask.get_bit(i) {
self.array[i] = Weak::clone(&state );
}
}
}
}
use transition_masking::{TransitionMask};
mod transition_masking {
use std::ops::RangeInclusive;
pub enum MaskPresets {
Char(char),
AnyCase, LowerCase, UpperCase,
AllHumanReadable,
Numbers, SpecialChars,
WhiteSpace, LineTermination,
NoChar
}
pub struct TransitionMask {
mask: u128
}
impl From<MaskPresets> for TransitionMask {
fn from(value: MaskPresets) -> Self {
let mut n: u128 = 0;
let mut set_range = |r: RangeInclusive<i32>| {
r.for_each(|i| { n |= 1 << i });
};
match value {
MaskPresets::NoChar => {}
MaskPresets::AnyCase => {
set_range(0x41..=0x5a); // UpperCase
set_range(0x61..=0x7a); // LowerCase
},
MaskPresets::LowerCase => {
set_range(0x61..=0x7a); // LowerCase
},
MaskPresets::UpperCase => {
set_range(0x41..=0x5a); // UpperCase
},
MaskPresets::AllHumanReadable => {
set_range(0x20..=0x7e); // All Ascii Chars + Space + Tab
n |= 1 << 0x9; // Tab
},
MaskPresets::Numbers => {
set_range(0x30..=0x39); // Numbers
},
MaskPresets::SpecialChars => {
set_range(0x21..=0x2F); // ! to /
set_range(0x3A..=0x40); // : to @
set_range(0x5B..=0x0D); // [ to `
set_range(0x7B..=0x7E); // { to ~
},
MaskPresets::WhiteSpace => {
n |= 1 << 0x9; // Tab
n |= 1 << 0x20; // Spaces
},
MaskPresets::LineTermination => {
n |= 1 << 0x0a; // Line Feed
n |= 1 << 0x0d; // Carriage Return
}
MaskPresets::Char(c) => {
if c.is_ascii() {
n |= 1 << (c as u32)
}
},
}
TransitionMask { mask: n }
}
}
impl TransitionMask {
pub fn new() -> Self {
TransitionMask { mask: 0 }
}
pub fn or(&self, other: Self) -> TransitionMask {
TransitionMask { mask: other.mask | self.mask }
}
pub fn and(&self, other: Self) -> TransitionMask {
TransitionMask { mask: other.mask & self.mask }
}
pub fn inv(&self) -> TransitionMask {
TransitionMask { mask: !self.mask }
}
pub fn get_bit(&self, i: usize) -> bool {
(self.mask & (1 << i)) > 0
}
}
}
#[cfg(test)]
mod test {
use super::{transition_masking::*, *};
#[test]
fn simple_fsm_building() {
let z0 = Rc::new(RefCell::new(FSMState::new("z0".to_string(), FSMStateAction::NONE)));
let z1 = Rc::new(RefCell::new(FSMState::new("z1".to_string(), FSMStateAction::NONE)));
let z2 = Rc::new(RefCell::new(FSMState::new("z2".to_string(), FSMStateAction::TERMINAL)));
let z3 = Rc::new(RefCell::new(FSMState::new("z3".to_string(), FSMStateAction::NONE)));
let mut z0_transisions = FSMTranistion::new_from_mask(
TransitionMask::from(MaskPresets::Char('a')), Rc::downgrade(&z1), Rc::downgrade(&z3));
z0_transisions.apply(TransitionMask::from(MaskPresets::Char('b')), Rc::downgrade(&z2));
let mut z1_transisions = FSMTranistion::new_from_mask(
TransitionMask::from(MaskPresets::Char('a')), Rc::downgrade(&z1), Rc::downgrade(&z3));
z1_transisions.apply(TransitionMask::from(MaskPresets::Char('b')), Rc::downgrade(&z2));
let z2_transisions = FSMTranistion::new_from_mask(
TransitionMask::from(MaskPresets::Char('a')), Rc::downgrade(&z2), Rc::downgrade(&z3));
let z3_transisions = FSMTranistion::new(
TransitionMask::from(MaskPresets::Char('a')), Rc::downgrade(&z3));
z0.borrow_mut().set_transitions(z0_transisions);
z1.borrow_mut().set_transitions(z1_transisions);
z2.borrow_mut().set_transitions(z2_transisions);
z3.borrow_mut().set_transitions(z3_transisions);
let fsm = FSM::new(vec![z0, z1, z2, z3]);
}
}

View File

@@ -1,2 +1,3 @@
pub mod conf;
pub mod doc;
pub mod doc;
pub mod fsm;