use crate::node::*; use crate::parser::*; use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::character::complete::*; use nom::combinator::*; use nom::error::*; use nom::multi::*; use nom::{Err, IResult}; // ----------------------------------------------------------------------------- #[derive(Debug, Node)] pub struct Symbol<'a> { pub nodes: (Span<'a>, Vec>), } #[derive(Debug, Node)] pub enum WhiteSpace<'a> { Space(Span<'a>), Comment(Comment<'a>), } #[derive(Debug)] pub struct Paren<'a, T: 'a> { pub nodes: (Symbol<'a>, T, Symbol<'a>), } #[derive(Debug)] pub struct Brace<'a, T: 'a> { pub nodes: (Symbol<'a>, T, Symbol<'a>), } #[derive(Debug)] pub struct Bracket<'a, T: 'a> { pub nodes: (Symbol<'a>, T, Symbol<'a>), } #[derive(Debug)] pub struct ApostropheBrace<'a, T: 'a> { pub nodes: (Symbol<'a>, T, Symbol<'a>), } #[derive(Debug)] pub struct List { pub nodes: (T, Vec<(U, T)>), } // ----------------------------------------------------------------------------- pub fn ws<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, (O, Vec>)> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, x) = f(s)?; let (s, y) = many0(white_space)(s)?; Ok((s, (x, y))) } } pub fn symbol<'a>(t: &'a str) -> impl Fn(Span<'a>) -> IResult, Symbol<'a>> { move |s: Span<'a>| map(ws(tag(t.clone())), |x| Symbol { nodes: x })(s) } pub fn paren2<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, Paren> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, a) = symbol("(")(s)?; let (s, b) = f(s)?; let (s, c) = symbol(")")(s)?; Ok((s, Paren { nodes: (a, b, c) })) } } pub fn bracket2<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, Bracket> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, a) = symbol("[")(s)?; let (s, b) = f(s)?; let (s, c) = symbol("]")(s)?; Ok((s, Bracket { nodes: (a, b, c) })) } } pub fn brace2<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, Brace> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, a) = symbol("{")(s)?; let (s, b) = f(s)?; let (s, c) = symbol("}")(s)?; Ok((s, Brace { nodes: (a, b, c) })) } } pub fn apostrophe_brace2<'a, O, F>( f: F, ) -> impl Fn(Span<'a>) -> IResult, ApostropheBrace> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, a) = symbol("'{")(s)?; let (s, b) = f(s)?; let (s, c) = symbol("}")(s)?; Ok((s, ApostropheBrace { nodes: (a, b, c) })) } } pub fn list<'a, O1, O2, F, G>(f: F, g: G) -> impl Fn(Span<'a>) -> IResult, List> where F: Fn(Span<'a>) -> IResult, O1>, G: Fn(Span<'a>) -> IResult, O2>, { move |s: Span<'a>| { let (s, a) = g(s)?; let mut s = s.clone(); let mut ret = Vec::new(); loop { if let Ok((t, b)) = f(s) { let (u, c) = g(t)?; s = u; ret.push((b, c)); } else { break; } } Ok((s, List { nodes: (a, ret) })) } } pub fn paren<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, O> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, _) = symbol("(")(s)?; let (s, b) = f(s)?; let (s, _) = symbol(")")(s)?; Ok((s, b)) } } pub fn bracket<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, O> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, _) = symbol("[")(s)?; let (s, b) = f(s)?; let (s, _) = symbol("]")(s)?; Ok((s, b)) } } pub fn brace<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, O> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, _) = symbol("{")(s)?; let (s, x) = f(s)?; let (s, _) = symbol("}")(s)?; Ok((s, x)) } } pub fn apostrophe_brace<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, O> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { let (s, _) = symbol("'{")(s)?; let (s, x) = f(s)?; let (s, _) = symbol("}")(s)?; Ok((s, x)) } } pub fn rec<'a, O, F>(f: F, id: u32) -> impl Fn(Span<'a>) -> IResult, O> where F: Fn(Span<'a>) -> IResult, O>, { move |s: Span<'a>| { if check_bit(s, id) { return Err(Err::Error(make_error(s, ErrorKind::Fix))); } let s = set_bit(s, id, true); let (s, x) = f(s)?; let s = set_bit(s, id, false); Ok((s, x)) } } pub fn triple<'a, O1, O2, O3, F, G, H>( f: F, g: G, h: H, ) -> impl Fn(Span<'a>) -> IResult, (O1, O2, O3)> where F: Fn(Span<'a>) -> IResult, O1>, G: Fn(Span<'a>) -> IResult, O2>, H: Fn(Span<'a>) -> IResult, O3>, { move |s: Span<'a>| { let (s, x) = f(s)?; let (s, y) = g(s)?; let (s, z) = h(s)?; Ok((s, (x, y, z))) } } // ----------------------------------------------------------------------------- pub fn white_space(s: Span) -> IResult { alt(( map(multispace1, |x| WhiteSpace::Space(x)), map(comment, |x| WhiteSpace::Comment(x)), ))(s) } // ----------------------------------------------------------------------------- pub fn concat<'a>(a: Span<'a>, b: Span<'a>) -> Option> { let c = str_concat::concat(a.fragment, b.fragment); if let Ok(c) = c { Some(Span { offset: a.offset, line: a.line, fragment: c, extra: a.extra, }) } else { None } } pub fn check_bit(s: Span, id: u32) -> bool { ((s.extra >> id) & 1) == 1 } pub fn set_bit(s: Span, id: u32, bit: bool) -> Span { let val = if bit { 1u64 << id } else { 0u64 }; let mask = !(1u64 << id); let val = (s.extra & mask) | val; Span { offset: s.offset, line: s.line, fragment: s.fragment, extra: val, } } // ----------------------------------------------------------------------------- #[cfg(test)] macro_rules! parser_test { ( $x:expr, $y:expr, $z:pat ) => { let ret = all_consuming($x)(Span::new_extra($y, 0)); if let $z = ret { } else { assert!(false, "{:?}", ret) } }; }