use crate::parser::types as parser_types;
use parser_types::Statement;
use std::collections::HashMap;
use crate::generator::ast::{Probe, Script, WhammParam};
use crate::parser::provider_handler::ModeKind;
#[derive(Default)]
pub struct SimpleAST {
pub global_stmts: Vec<Statement>,
pub provs: HashMap<String, SimpleProv>,
}
impl SimpleAST {
pub fn new(ast: Vec<Script>) -> Self {
let mut s = Self::default();
for Script {
global_stmts,
probes,
..
} in ast.iter()
{
s.global_stmts.extend(global_stmts.to_owned());
for probe in probes.iter() {
s.add_probe(
&probe.rule.provider.name,
&probe.rule.package.name,
&probe.rule.event.name,
&probe.rule.mode.name,
probe.to_owned(),
);
}
}
s
}
fn add_probe(
&mut self,
provider_name: &str,
package_name: &str,
event_name: &str,
mode_name: &str,
probe: Probe,
) {
self.provs
.entry(provider_name.to_string())
.and_modify(|provider| {
provider.add_probe(package_name, event_name, mode_name, probe.to_owned());
})
.or_insert(SimpleProv::new(package_name, event_name, mode_name, probe));
}
}
#[derive(Default)]
pub struct SimpleProv {
pub pkgs: HashMap<String, SimplePkg>,
all_params: Option<Vec<WhammParam>>,
}
impl SimpleProv {
fn new(package_name: &str, event_name: &str, mode_name: &str, probe: Probe) -> Self {
let mut s = Self::default();
s.add_probe(package_name, event_name, mode_name, probe);
s
}
fn add_probe(&mut self, package_name: &str, event_name: &str, mode_name: &str, probe: Probe) {
self.pkgs
.entry(package_name.to_string())
.and_modify(|pkg| {
pkg.add_probe(event_name, mode_name, probe.to_owned());
})
.or_insert(SimplePkg::new(event_name, mode_name, probe));
}
pub fn all_params(&mut self) -> &Vec<WhammParam> {
self.all_params.get_or_insert_with(|| {
let mut ps = vec![];
for pkg in self.pkgs.values_mut() {
ps.extend(pkg.all_params().clone());
}
ps
})
}
}
#[derive(Default)]
pub struct SimplePkg {
pub evts: HashMap<String, SimpleEvt>,
all_params: Option<Vec<WhammParam>>,
}
impl SimplePkg {
fn new(event_name: &str, mode_name: &str, probe: Probe) -> Self {
let mut s = Self::default();
s.add_probe(event_name, mode_name, probe);
s
}
fn add_probe(&mut self, event_name: &str, mode_name: &str, probe: Probe) {
self.evts
.entry(event_name.to_string())
.and_modify(|evt| {
evt.add_probe(mode_name, probe.to_owned());
})
.or_insert(SimpleEvt::new(mode_name, probe));
}
pub fn all_params(&mut self) -> &Vec<WhammParam> {
self.all_params.get_or_insert_with(|| {
let mut ps = vec![];
for evt in self.evts.values_mut() {
ps.extend(evt.all_params().clone());
}
ps
})
}
}
#[derive(Default)]
pub struct SimpleEvt {
pub modes: HashMap<ModeKind, Vec<Probe>>,
all_params: Option<Vec<WhammParam>>,
}
impl SimpleEvt {
fn new(mode_name: &str, probe: Probe) -> Self {
let mut s = Self::default();
s.add_probe(mode_name, probe);
s
}
fn add_probe(&mut self, mode_name: &str, probe: Probe) {
let mode_kind = ModeKind::from(mode_name.to_string());
self.modes
.entry(mode_kind)
.and_modify(|probes| {
probes.push(probe.clone());
})
.or_insert(vec![probe]);
}
pub fn all_params(&mut self) -> &Vec<WhammParam> {
self.all_params.get_or_insert_with(|| {
let mut ps = vec![];
for probes in self.modes.values() {
for p in probes.iter() {
ps.extend(p.metadata.pred_args.params.clone());
ps.extend(p.metadata.body_args.params.clone());
}
}
ps
})
}
}