diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs index e8438283835de53286bdec2920eb495665b7609e..5f6b31873ff47b3c8bb403c5b79363abeae14359 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -217,16 +217,7 @@ fn parse_return<'a>( ir_text: &'a str, context: &RefCell<Context<'a>>, ) -> nom::IResult<&'a str, Node> { - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let ir_text = nom::character::complete::char('(')(ir_text)?.0; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let (ir_text, control) = parse_identifier(ir_text)?; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let ir_text = nom::character::complete::char(',')(ir_text)?.0; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let (ir_text, value) = parse_identifier(ir_text)?; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let ir_text = nom::character::complete::char(')')(ir_text)?.0; + let (ir_text, (control, value)) = parse_tuple2(parse_identifier, parse_identifier)(ir_text)?; let control = context.borrow_mut().get_node_id(control); let value = context.borrow_mut().get_node_id(value); Ok((ir_text, Node::Return { control, value })) @@ -250,16 +241,7 @@ fn parse_constant_node<'a>( } fn parse_add<'a>(ir_text: &'a str, context: &RefCell<Context<'a>>) -> nom::IResult<&'a str, Node> { - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let ir_text = nom::character::complete::char('(')(ir_text)?.0; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let (ir_text, left) = parse_identifier(ir_text)?; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let ir_text = nom::character::complete::char(',')(ir_text)?.0; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let (ir_text, right) = parse_identifier(ir_text)?; - let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let ir_text = nom::character::complete::char(')')(ir_text)?.0; + let (ir_text, (left, right)) = parse_tuple2(parse_identifier, parse_identifier)(ir_text)?; let left = context.borrow_mut().get_node_id(left); let right = context.borrow_mut().get_node_id(right); Ok((ir_text, Node::Add { left, right })) @@ -723,6 +705,73 @@ fn parse_identifier<'a>(ir_text: &'a str) -> nom::IResult<&'a str, &'a str> { )(ir_text) } +fn parse_tuple1<'a, A, AF>(mut parse_a: AF) -> impl FnMut(&'a str) -> nom::IResult<&'a str, (A,)> +where + AF: nom::Parser<&'a str, A, nom::error::Error<&'a str>>, +{ + move |ir_text: &'a str| { + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char('(')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, a) = parse_a.parse(ir_text)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(')')(ir_text)?.0; + Ok((ir_text, (a,))) + } +} + +fn parse_tuple2<'a, A, B, AF, BF>( + mut parse_a: AF, + mut parse_b: BF, +) -> impl FnMut(&'a str) -> nom::IResult<&'a str, (A, B)> +where + AF: nom::Parser<&'a str, A, nom::error::Error<&'a str>>, + BF: nom::Parser<&'a str, B, nom::error::Error<&'a str>>, +{ + move |ir_text: &'a str| { + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char('(')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, a) = parse_a.parse(ir_text)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(',')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, b) = parse_b.parse(ir_text)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(')')(ir_text)?.0; + Ok((ir_text, (a, b))) + } +} + +fn parse_tuple3<'a, A, B, C, AF, BF, CF>( + mut parse_a: AF, + mut parse_b: BF, + mut parse_c: CF, +) -> impl FnMut(&'a str) -> nom::IResult<&'a str, (A, B, C)> +where + AF: nom::Parser<&'a str, A, nom::error::Error<&'a str>>, + BF: nom::Parser<&'a str, B, nom::error::Error<&'a str>>, + CF: nom::Parser<&'a str, C, nom::error::Error<&'a str>>, +{ + move |ir_text: &'a str| { + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char('(')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, a) = parse_a.parse(ir_text)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(',')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, b) = parse_b.parse(ir_text)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(',')(ir_text)?.0; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let (ir_text, c) = parse_c.parse(ir_text)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(')')(ir_text)?.0; + Ok((ir_text, (a, b, c))) + } +} + mod tests { #[allow(unused_imports)] use super::*;