use super::*;
use crate::value::Parselet;
#[derive(Debug)]
pub struct ImlParselet {
pub consuming: Option<Consumable>, pub severity: u8, pub name: Option<String>, pub signature: Vec<(String, Option<usize>)>, locals: usize, begin: ImlOp, end: ImlOp, body: ImlOp, }
impl ImlParselet {
pub fn new(
name: Option<String>,
signature: Vec<(String, Option<usize>)>,
locals: usize,
begin: ImlOp,
end: ImlOp,
body: ImlOp,
) -> Self {
assert!(
signature.len() <= locals,
"signature may not be longer than locals..."
);
Self {
name,
consuming: None,
severity: 5,
signature,
locals,
begin,
end,
body,
}
}
pub fn into_parselet(&self ) -> Parselet {
Parselet::new(
self.name.clone(),
if let Some(Consumable { leftrec, .. }) = self.consuming {
Some(leftrec)
} else {
None
},
self.severity,
self.signature.clone(),
self.locals,
self.begin.compile(&self),
self.end.compile(&self),
self.body.compile(&self),
)
}
pub fn resolve(&mut self, usages: &mut Vec<Vec<ImlOp>>) {
self.begin.resolve(usages);
self.end.resolve(usages);
self.body.resolve(usages);
}
pub fn finalize(
&mut self,
values: &Vec<ImlValue>,
stack: &mut Vec<(usize, bool)>,
) -> Option<Consumable> {
self.body.finalize(values, stack)
}
}
impl std::cmp::PartialEq for ImlParselet {
fn eq(&self, other: &Self) -> bool {
self as *const ImlParselet as usize == other as *const ImlParselet as usize
}
}
impl std::hash::Hash for ImlParselet {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(self as *const ImlParselet as usize).hash(state);
}
}
impl std::cmp::PartialOrd for ImlParselet {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
let left = self as *const ImlParselet as usize;
let right = other as *const ImlParselet as usize;
left.partial_cmp(&right)
}
}