synthphonia/forward/data/
mod.rs

1
2
3use std::cell::{RefCell, UnsafeCell};
4
5use itertools::Itertools;
6
7use crate::{expr::{cfg::Cfg, context::Context, Expr}, text::parsing::TextObjData, utils::UnsafeCellExt, value::{Type, Value}};
8
9use self::size::{VecEv, EV};
10
11use super::executor::Executor;
12
13/// Term Dispatcher for SubString
14pub mod substr;
15
16/// Term Dispatcher for Equal
17pub mod all_eq;
18
19/// Term Dispatcher for Size
20pub mod size;
21
22/// Term Dispatcher for Prefix
23pub mod prefix;
24
25/// Term Dispatcher for Contains
26pub mod contains;
27/// Term Dispatcher for Len
28pub mod len;
29
30/// All Term Dispatchers
31pub struct Data {
32    pub size: size::Data,
33    pub all_eq: all_eq::Data,
34    pub substr: Option<UnsafeCell<substr::Data>>,
35    pub prefix: Option<UnsafeCell<prefix::Data>>,
36    pub contains: Option<contains::Data>,
37    pub len: Option<UnsafeCell<len::Data>>,
38    pub to: TextObjData,
39    pub new_ev: RefCell<Vec<(&'static Expr, Value)>>,
40} 
41
42impl Data {
43    /// Create a instance of all term dispatchers
44    pub fn new(cfg: & Cfg, ctx: & Context) -> Vec<Self> {
45        cfg.iter().enumerate().map(|(i, nt)| {
46            Self {
47                size: size::Data::new(cfg),
48                all_eq: all_eq::Data::new(),
49                substr: substr::Data::new(ctx.output, cfg.config.substr_limit),
50                prefix: prefix::Data::new(ctx.output, usize::MAX),
51                contains: contains::Data::new(ctx.output.len(), nt.ty),
52                len: if nt.ty != Type::ListStr && cfg[i].get_op1("list.map").is_some() { None } else { Some(len::Data::new().into()) },
53                to: TextObjData::new(),
54                new_ev: Vec::<(&'static Expr, Value)>::new().into()
55            }
56        }).collect_vec()
57    }
58    /// Get substr dispatcher
59    pub fn substr(&self) -> Option<&mut substr::Data> {
60        self.substr.as_ref().map(|a| unsafe { a.as_mut() } )
61    }
62    /// Get prefix dispatcher
63    pub fn prefix(&self) -> Option<&mut prefix::Data> {
64        self.prefix.as_ref().map(|a| unsafe { a.as_mut() } )
65    }
66    /// Get len dispatcher
67    pub fn len(&self) -> Option<&mut len::Data> {
68        self.len.as_ref().map(|a| unsafe { a.as_mut() } )
69    }
70    
71    #[inline(always)]
72    /// Add an new expression and value pair into the term dispatcher
73    pub fn update(&self, exec: &'static Executor, e: Expr, v: Value) -> Result<Option<&'static Expr>, ()> {
74        let new_ev = std::mem::take(&mut *self.new_ev.borrow_mut());
75        for (e,v) in new_ev {
76            self.all_eq.set_ref(v, e);
77        }
78
79        if let Some(e) = self.all_eq.set(v, e) {
80            if let Some(s) = self.substr() { s.update(v, exec); }
81            if let Some(s) = self.prefix() { s.update(v, exec); }
82            if let Some(l) = self.len() { l.update(v, exec); };
83            if let Some(c) = self.contains.as_ref() { c.update(v); }
84            // self.listsubseq.update(v)?;
85            self.to.update(exec, e, v);
86            Ok(Some(e))
87        } else {
88            Ok(None)
89        }
90    }
91    pub fn add_ev(&self, e: &'static Expr, v: Value) {
92        self.new_ev.borrow_mut().push((e, v));
93    }
94}