From 98ff8ef27083aab7c6ddce81eb61b7da75aede87 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Sun, 10 Sep 2023 16:21:56 -0500 Subject: [PATCH] Parse float constants --- hercules_ir/src/ir.rs | 1 + hercules_ir/src/parse.rs | 99 ++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 24 deletions(-) diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index 36638498..bdad05df 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -32,6 +32,7 @@ pub enum Type { Float64, Product(Box<[TypeID]>), Summation(Box<[TypeID]>), + Array(TypeID, Box<[DynamicConstantID]>), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/hercules_ir/src/parse.rs b/hercules_ir/src/parse.rs index acdd92ad..aae3914d 100644 --- a/hercules_ir/src/parse.rs +++ b/hercules_ir/src/parse.rs @@ -337,20 +337,15 @@ fn parse_dynamic_constant_id<'a>( fn parse_dynamic_constant<'a>(ir_text: &'a str) -> nom::IResult<&'a str, DynamicConstant> { let ir_text = nom::character::complete::multispace0(ir_text)?.0; - let parse_usize = |x: &'a str| -> nom::IResult<&'a str, usize> { - let (ir_text, num_text) = nom::bytes::complete::is_a("-1234567890")(x)?; - let num = num_text.parse::<usize>().map_err(|_| { - nom::Err::Error(nom::error::Error { - input: num_text, - code: nom::error::ErrorKind::IsNot, - }) - })?; - Ok((ir_text, num)) - }; let (ir_text, dc) = nom::branch::alt(( - nom::combinator::map(parse_usize, |x| DynamicConstant::Constant(x)), nom::combinator::map( - nom::sequence::tuple((nom::character::complete::char('#'), parse_usize)), + |x| parse_prim::<usize>(x, "-1234567890"), + |x| DynamicConstant::Constant(x), + ), + nom::combinator::map( + nom::sequence::tuple((nom::character::complete::char('#'), |x| { + parse_prim::<usize>(x, "-1234567890") + })), |(_, x)| DynamicConstant::Parameter(x), ), ))(ir_text)?; @@ -374,42 +369,98 @@ fn parse_constant<'a>( ) -> nom::IResult<&'a str, Constant> { let (ir_text, constant) = match ty { Type::Integer8 => parse_integer8(ir_text)?, + Type::Integer16 => parse_integer16(ir_text)?, Type::Integer32 => parse_integer32(ir_text)?, + Type::Integer64 => parse_integer64(ir_text)?, + Type::UnsignedInteger8 => parse_unsigned_integer8(ir_text)?, + Type::UnsignedInteger16 => parse_unsigned_integer16(ir_text)?, + Type::UnsignedInteger32 => parse_unsigned_integer32(ir_text)?, + Type::UnsignedInteger64 => parse_unsigned_integer64(ir_text)?, + Type::Float32 => parse_float32(ir_text)?, + Type::Float64 => parse_float64(ir_text)?, _ => todo!(), }; context.get_type_id(ty); Ok((ir_text, constant)) } -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(|_| { +fn parse_prim<'a, T: std::str::FromStr>( + ir_text: &'a str, + chars: &'static str, +) -> nom::IResult<&'a str, T> { + let (ir_text, x_text) = nom::bytes::complete::is_a(chars)(ir_text)?; + let x = x_text.parse::<T>().map_err(|_| { nom::Err::Error(nom::error::Error { - input: num_text, + input: x_text, code: nom::error::ErrorKind::IsNot, }) })?; + Ok((ir_text, x)) +} + +fn parse_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; Ok((ir_text, Constant::Integer8(num))) } +fn parse_integer16<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; + Ok((ir_text, Constant::Integer16(num))) +} + fn parse_integer32<'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::<i32>().map_err(|_| { - nom::Err::Error(nom::error::Error { - input: num_text, - code: nom::error::ErrorKind::IsNot, - }) - })?; + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; Ok((ir_text, Constant::Integer32(num))) } +fn parse_integer64<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; + Ok((ir_text, Constant::Integer64(num))) +} + +fn parse_unsigned_integer8<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; + Ok((ir_text, Constant::UnsignedInteger8(num))) +} + +fn parse_unsigned_integer16<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; + Ok((ir_text, Constant::UnsignedInteger16(num))) +} + +fn parse_unsigned_integer32<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; + Ok((ir_text, Constant::UnsignedInteger32(num))) +} + +fn parse_unsigned_integer64<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = parse_prim(ir_text, "-1234567890")?; + Ok((ir_text, Constant::UnsignedInteger64(num))) +} + +fn parse_float32<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = nom::number::complete::float(ir_text)?; + Ok(( + ir_text, + Constant::Float32(ordered_float::OrderedFloat::<f32>(num)), + )) +} + +fn parse_float64<'a>(ir_text: &'a str) -> nom::IResult<&'a str, Constant> { + let (ir_text, num) = nom::number::complete::double(ir_text)?; + Ok(( + ir_text, + Constant::Float64(ordered_float::OrderedFloat::<f64>(num)), + )) +} + mod tests { #[allow(unused_imports)] use super::*; #[test] fn parse_ir1() { - let module = parse( + parse( " fn myfunc(x: i32) -> i32 y = call(start, add, x, x) -- GitLab