From 347e4f0312c37ccdeb9ea63d73f6ed946334cc27 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Tue, 5 Sep 2023 10:28:43 -0500 Subject: [PATCH] Refactor parsing code --- hercules_ir/src/ir.rs | 16 +++-- hercules_ir/src/parse.rs | 134 +++++++++++++++++++++++---------------- 2 files changed, 93 insertions(+), 57 deletions(-) diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index 005de050..1d237481 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -22,16 +22,24 @@ pub enum Type { Integer16, Integer32, Integer64, + UnsignedInteger8, + UnsignedInteger16, + UnsignedInteger32, + UnsignedInteger64, Float32, Float64, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Constant { - Integer8(u8), - Integer16(u16), - Integer32(u32), - Integer64(u64), + Integer8(i8), + Integer16(i16), + Integer32(i32), + Integer64(i64), + UnsignedInteger8(u8), + UnsignedInteger16(u16), + UnsignedInteger32(u32), + UnsignedInteger64(u64), Float32(ordered_float::OrderedFloat<f32>), Float64(ordered_float::OrderedFloat<f64>), } diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs index e70e608a..5f3e83c8 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -115,64 +115,73 @@ fn parse_node<'a>( let ir_text = nom::character::complete::multispace0(ir_text)?.0; let (ir_text, node_kind) = nom::character::complete::alphanumeric1(ir_text)?; let (ir_text, node) = match node_kind { - "return" => { - let (ir_text, comps) = nom::sequence::tuple(( - nom::character::complete::multispace0, - nom::character::complete::char('('), - nom::character::complete::multispace0, - nom::character::complete::alphanumeric1, - nom::character::complete::multispace0, - nom::character::complete::char(','), - nom::character::complete::multispace0, - nom::character::complete::alphanumeric1, - nom::character::complete::multispace0, - nom::character::complete::char(')'), - ))(ir_text)?; - let control_id = context.get_node_id(comps.3); - let value_id = context.get_node_id(comps.7); - ( - ir_text, - Node::Return { - control: control_id, - value: value_id, - }, - ) - } - "add" => { - let (ir_text, comps) = nom::sequence::tuple(( - nom::character::complete::multispace0, - nom::character::complete::char('('), - nom::character::complete::multispace0, - nom::character::complete::alphanumeric1, - nom::character::complete::multispace0, - nom::character::complete::char(','), - nom::character::complete::multispace0, - nom::character::complete::alphanumeric1, - nom::character::complete::multispace0, - nom::character::complete::char(','), - nom::character::complete::multispace0, - nom::character::complete::alphanumeric1, - nom::character::complete::multispace0, - nom::character::complete::char(')'), - ))(ir_text)?; - let control_id = context.get_node_id(comps.3); - let left_id = context.get_node_id(comps.7); - let right_id = context.get_node_id(comps.11); - ( - ir_text, - Node::Add { - control: control_id, - left: left_id, - right: right_id, - }, - ) - } + "return" => parse_return(ir_text, context)?, + "constant" => parse_constant_node(ir_text, context)?, + "add" => parse_add(ir_text, context)?, _ => todo!(), }; context.get_node_id(node_name); Ok((ir_text, (node_name, node))) } +fn parse_return<'a>(ir_text: &'a str, context: &mut 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) = nom::character::complete::alphanumeric1(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) = nom::character::complete::alphanumeric1(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, + Node::Return { + control: context.get_node_id(control), + value: context.get_node_id(value), + }, + )) +} + +fn parse_constant_node<'a>( + ir_text: &'a str, + context: &mut 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, id) = parse_constant(ir_text, context)?; + let ir_text = nom::character::complete::multispace0(ir_text)?.0; + let ir_text = nom::character::complete::char(')')(ir_text)?.0; + Ok((ir_text, Node::Constant { id })) +} + +fn parse_add<'a>(ir_text: &'a str, context: &mut 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) = nom::character::complete::alphanumeric1(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, left) = nom::character::complete::alphanumeric1(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) = nom::character::complete::alphanumeric1(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, + Node::Add { + control: context.get_node_id(control), + left: context.get_node_id(left), + right: context.get_node_id(right), + }, + )) +} + fn parse_type<'a>(ir_text: &'a str, context: &mut Context<'a>) -> nom::IResult<&'a str, TypeID> { let ir_text = nom::character::complete::multispace0(ir_text)?.0; let (ir_text, ty) = @@ -191,7 +200,26 @@ fn parse_constant<'a>( ir_text: &'a str, context: &mut Context<'a>, ) -> nom::IResult<&'a str, ConstantID> { - todo!() + let (ir_text, constant) = nom::branch::alt((parse_integer8,))(ir_text)?; + let id = if let Some(id) = context.interned_constants.get(&constant) { + *id + } else { + let id = ConstantID::new(context.interned_constants.len()); + context.interned_constants.insert(constant, id); + id + }; + Ok((ir_text, id)) +} + +fn parse_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num_text) = nom::bytes::complete::is_a("-1234567890")(ir_text)?; + let num = num_text.parse::<i8>().map_err(|_| { + nom::Err::Error(nom::error::Error { + input: num_text, + code: nom::error::ErrorKind::IsNot, + }) + })?; + Ok((ir_text, Constant::Integer8(num))) } mod tests { -- GitLab