use super::*; pub struct Node { pub data: Option, } pub type BNode = Box>; pub enum ParseResult { Ok(T), Node(Node), Continue(CompilerMsg), Break(CompilerMsg), SubErr, } pub trait Parsable: Sized { type Data = (); fn parse(ctx: &mut ParserCtx, data: Self::Data) -> ParseResult; } impl Node { pub fn bx(self) -> Box { Box::new(self) } pub fn map(self, f: impl FnOnce(T) -> U) -> Node { Node { data: self.data.map(f), } } } use std::convert::Infallible; impl std::ops::FromResidual> for ParseResult { fn from_residual(residual: Option) -> Self { match residual { None => ParseResult::SubErr, } } } impl std::ops::FromResidual> for ParseResult { fn from_residual(residual: Result) -> Self { match residual { Err(msg) => ParseResult::Break(msg), } } } impl CompilerMsg { pub fn res(self) -> ParseResult { ParseResult::Break(self) } } impl std::fmt::Debug for Node { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if let Some(d) = &self.data { d.fmt(f) } else { f.write_str("{error}") } } }